import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../../features/assets/presentation/asset_add_page.dart';
import '../../features/assets/presentation/asset_edit_page.dart';
import '../../features/assets/presentation/assets_page.dart';
import '../../features/assets/presentation/holding_detail_page.dart';
import '../../features/auth/presentation/delete_account_page.dart';
import '../../features/auth/presentation/login_page.dart';
import '../../features/debug/presentation/debug_info_page.dart';
import '../../features/debug/presentation/debug_page.dart';
import '../../features/debug/presentation/debug_shorebird_page.dart';
import '../../features/debug/presentation/fancy_dio_inspector_page.dart';
import '../../features/debug/presentation/typography_test_page.dart';
import '../../features/market/presentation/market_page.dart';
import '../../features/market/presentation/market_kline_page.dart';
import '../../features/news/presentation/news_page.dart';
import '../../features/news/presentation/news_detail_page.dart';
import '../../features/profile/presentation/profile_page.dart';
import '../../features/profile/presentation/profile_action_pages.dart';
import '../../features/settings/presentation/settings_page.dart';
import '../../features/settings/presentation/privacy_consent_page.dart';
import '../services/device_header_service.dart';
import 'tab_shell.dart';

abstract final class AppRoutes {
  static const assets = '/assets';
  static const assetAdd = '/assets/add';
  static const assetEdit = '/assets/edit';
  static const market = '/market';
  static const marketKline = '/market/kline';
  static const news = '/news';
  static const newsDetail = '/news/detail';
  static const profile = '/profile';
  static const profileInvite = '/profile/invite';
  static const profileShare = '/profile/share';
  static const profileLocalBackup = '/profile/local-backup';
  static const profileCloudBackup = '/profile/cloud-backup';
  static const profileWidget = '/profile/widget';
  static const profilePurity = '/profile/purity';
  static const profileRecycle = '/profile/recycle';
  static const profilePriceColor = '/profile/price-color';
  static const profileCurrency = '/profile/currency';
  static const profileDisclaimer = '/profile/disclaimer';
  static const profileAbout = '/profile/about';
  static const assetDetail = '/assets/detail';
  static const login = '/login';
  static const settings = '/settings';
  static const deleteAccount = '/delete-account';
  static const deleteAccountCompleted = '/delete-account-completed';
  static const debug = '/debug';
  static const debugInfo = '/debug/info';
  static const debugShorebird = '/debug/shorebird';
  static const debugTypography = '/debug/typography';
  static const fancyDioInspector = '/debug/fancy_dio_inspector';
  static const privacyConsent = '/privacy-consent';
}

final routerProvider = Provider<GoRouter>((ref) {
  final startupListenable = ValueNotifier<int>(0);
  return GoRouter(
    initialLocation: AppRoutes.assets,
    refreshListenable: startupListenable,
    redirect: (context, state) {
      final loc = state.matchedLocation;
      final onConsent = loc == AppRoutes.privacyConsent;
      final showStartup =
          DeviceHeaderService.to.privacyConsentRequired ||
          DeviceHeaderService.to.iosStartupRequired;
      if (showStartup) {
        if (!onConsent) return AppRoutes.privacyConsent;
      } else if (onConsent) {
        return AppRoutes.assets;
      }
      return null;
    },
    routes: [
      ShellRoute(
        builder: (context, state, child) =>
            TabShell(location: state.matchedLocation, child: child),
        routes: [
          GoRoute(
            path: AppRoutes.assets,
            builder: (ctx, s) => const AssetsPage(),
          ),
          GoRoute(
            path: AppRoutes.market,
            builder: (ctx, s) => const MarketPage(),
          ),
          GoRoute(path: AppRoutes.news, builder: (ctx, s) => const NewsPage()),
          GoRoute(
            path: AppRoutes.profile,
            builder: (ctx, s) => const ProfilePage(),
          ),
        ],
      ),
      GoRoute(
        path: AppRoutes.assetDetail,
        builder: (ctx, s) => HoldingDetailPage(id: s.uri.queryParameters['id']),
      ),
      GoRoute(
        path: AppRoutes.assetAdd,
        pageBuilder: (ctx, s) =>
            _rightToLeftPage(state: s, child: const AssetAddPage()),
      ),
      GoRoute(
        path: AppRoutes.assetEdit,
        pageBuilder: (ctx, s) => _rightToLeftPage(
          state: s,
          child: AssetEditPage(id: s.uri.queryParameters['id'] ?? ''),
        ),
      ),
      GoRoute(
        path: AppRoutes.marketKline,
        builder: (ctx, s) => MarketKlinePage(
          metalId: s.uri.queryParameters['metal'],
          periodId: s.uri.queryParameters['period'],
        ),
      ),
      GoRoute(
        path: AppRoutes.newsDetail,
        builder: (ctx, s) => NewsDetailPage(id: s.uri.queryParameters['id']),
      ),
      GoRoute(
        path: AppRoutes.profileInvite,
        pageBuilder: (ctx, s) =>
            _bottomUpPage(state: s, child: const InviteRewardPage()),
      ),
      GoRoute(
        path: AppRoutes.profileShare,
        pageBuilder: (ctx, s) =>
            _bottomUpPage(state: s, child: const ShareCardPage()),
      ),
      GoRoute(
        path: AppRoutes.profileLocalBackup,
        pageBuilder: (ctx, s) =>
            _bottomUpPage(state: s, child: const LocalBackupPage()),
      ),
      GoRoute(
        path: AppRoutes.profileCloudBackup,
        pageBuilder: (ctx, s) =>
            _bottomUpPage(state: s, child: const CloudBackupPage()),
      ),
      GoRoute(
        path: AppRoutes.profileWidget,
        pageBuilder: (ctx, s) =>
            _bottomUpPage(state: s, child: const WidgetSettingsPage()),
      ),
      GoRoute(
        path: AppRoutes.profilePurity,
        pageBuilder: (ctx, s) =>
            _bottomUpPage(state: s, child: const PuritySettingsPage()),
      ),
      GoRoute(
        path: AppRoutes.profileRecycle,
        pageBuilder: (ctx, s) =>
            _bottomUpPage(state: s, child: const RecycleDiscountPage()),
      ),
      GoRoute(
        path: AppRoutes.profilePriceColor,
        pageBuilder: (ctx, s) =>
            _bottomUpPage(state: s, child: const PriceColorPage()),
      ),
      GoRoute(
        path: AppRoutes.profileCurrency,
        pageBuilder: (ctx, s) =>
            _bottomUpPage(state: s, child: const CurrencyPage()),
      ),
      GoRoute(
        path: AppRoutes.profileDisclaimer,
        pageBuilder: (ctx, s) =>
            _rightToLeftPage(state: s, child: const DisclaimerPage()),
      ),
      GoRoute(
        path: AppRoutes.profileAbout,
        pageBuilder: (ctx, s) =>
            _bottomUpPage(state: s, child: const AboutPage()),
      ),
      GoRoute(path: AppRoutes.debug, builder: (_, s) => const DebugPage()),
      GoRoute(
        path: AppRoutes.login,
        builder: (_, s) => LoginPage(next: s.uri.queryParameters['next']),
      ),
      GoRoute(
        path: AppRoutes.settings,
        builder: (_, s) => const SettingsPage(),
      ),
      GoRoute(
        path: AppRoutes.deleteAccount,
        builder: (_, s) => const DeleteAccountPage(),
      ),
      GoRoute(
        path: AppRoutes.deleteAccountCompleted,
        builder: (_, s) => const DeleteAccountSuccessPage(),
      ),
      GoRoute(
        path: AppRoutes.debugInfo,
        builder: (_, s) => const DebugInfoPage(),
      ),
      GoRoute(
        path: AppRoutes.debugShorebird,
        builder: (_, s) => const DebugShorebirdPage(),
      ),
      GoRoute(
        path: AppRoutes.debugTypography,
        builder: (_, s) => const TypographyTestPage(),
      ),
      GoRoute(
        path: AppRoutes.fancyDioInspector,
        builder: (_, s) => const FancyDioInspectorPage(),
      ),
      GoRoute(
        path: AppRoutes.privacyConsent,
        builder: (_, s) => const PrivacyConsentPage(),
      ),
    ],
  );
});

CustomTransitionPage<T> _bottomUpPage<T>({
  required GoRouterState state,
  required Widget child,
}) {
  return CustomTransitionPage<T>(
    key: state.pageKey,
    transitionDuration: const Duration(milliseconds: 260),
    reverseTransitionDuration: const Duration(milliseconds: 220),
    child: child,
    transitionsBuilder: (context, animation, secondaryAnimation, pageChild) {
      final curved = CurvedAnimation(
        parent: animation,
        curve: Curves.easeOutCubic,
        reverseCurve: Curves.easeInCubic,
      );
      return SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(0, 0.08),
          end: Offset.zero,
        ).animate(curved),
        child: FadeTransition(opacity: curved, child: pageChild),
      );
    },
  );
}

CustomTransitionPage<T> _rightToLeftPage<T>({
  required GoRouterState state,
  required Widget child,
}) {
  return CustomTransitionPage<T>(
    key: state.pageKey,
    transitionDuration: const Duration(milliseconds: 260),
    reverseTransitionDuration: const Duration(milliseconds: 220),
    child: child,
    transitionsBuilder: (context, animation, secondaryAnimation, pageChild) {
      final curved = CurvedAnimation(
        parent: animation,
        curve: Curves.easeOutCubic,
        reverseCurve: Curves.easeInCubic,
      );
      return SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(1, 0),
          end: Offset.zero,
        ).animate(curved),
        child: FadeTransition(opacity: curved, child: pageChild),
      );
    },
  );
}
