import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:go_router/go_router.dart';
import 'package:userfront/core/i18n/locale_registry.dart';
import 'package:userfront/core/i18n/locale_utils.dart';
import 'package:userfront/core/services/auth_token_store.dart';

Widget _buildTestApp(String initialLocation) {
  final router = GoRouter(
    initialLocation: initialLocation,
    routes: [
      GoRoute(
        path: '/:locale',
        redirect: (context, state) {
          if (state.uri.pathSegments.length != 1) {
            return null;
          }
          final localeCode = normalizeLocaleCode(
            state.pathParameters['locale'],
          );
          final token = AuthTokenStore.getToken();
          final isLoggedIn =
              (token != null && token.isNotEmpty) ||
              AuthTokenStore.usesCookie();
          if (!isLoggedIn) {
            return buildSigninRedirectPath(localeCode, state.uri);
          }
          return '/$localeCode/dashboard';
        },
        routes: [
          GoRoute(
            path: 'dashboard',
            builder: (context, state) =>
                const Scaffold(body: Text('dashboard-page')),
          ),
          GoRoute(
            path: 'signin',
            builder: (context, state) {
              final challenge = state.uri.queryParameters['login_challenge'];
              final redirect =
                  state.uri.queryParameters['redirect_uri'] ??
                  state.uri.queryParameters['redirect_url'] ??
                  '';
              return Scaffold(
                body: Text(
                  'signin|challenge=${challenge ?? ''}|redirect=$redirect',
                ),
              );
            },
          ),
          GoRoute(
            path: 'login',
            builder: (context, state) {
              final challenge = state.uri.queryParameters['login_challenge'];
              final redirect =
                  state.uri.queryParameters['redirect_uri'] ??
                  state.uri.queryParameters['redirect_url'] ??
                  '';
              return Scaffold(
                body: Text(
                  'login|challenge=${challenge ?? ''}|redirect=$redirect',
                ),
              );
            },
          ),
          GoRoute(
            path: 'profile',
            builder: (context, state) =>
                const Scaffold(body: Text('profile-page')),
          ),
        ],
      ),
    ],
    redirect: (context, state) {
      final requestedLocale = extractLocaleFromPath(state.uri);
      if (requestedLocale == null) {
        return buildLocalizedPath(resolvePreferredLocaleCode(), state.uri);
      }

      final token = AuthTokenStore.getToken();
      final isLoggedIn =
          (token != null && token.isNotEmpty) || AuthTokenStore.usesCookie();
      final path = stripLocalePath(state.uri);
      final isPublicPath = path == '/signin' || path == '/login';
      if (isPublicPath) {
        return null;
      }
      if (!isLoggedIn) {
        return buildSigninRedirectPath(requestedLocale, state.uri);
      }
      return null;
    },
  );

  return MaterialApp.router(routerConfig: router);
}

void main() {
  setUp(() {
    LocaleRegistry.setSupportedLocaleCodesForTest(['en', 'ko']);
    AuthTokenStore.clear();
  });

  tearDown(() {
    AuthTokenStore.clear();
    LocaleRegistry.resetForTest();
  });

  testWidgets(
    '루트 경로: /{locale} 로 접근 시 /{locale}/signin 으로 리다이렉트되어야 한다 (버그: 화면 렌더링 안됨)',
    (tester) async {
      await tester.pumpWidget(_buildTestApp('/ko'));
      await tester.pumpAndSettle();

      expect(find.textContaining('signin|'), findsOneWidget);
    },
  );

  testWidgets('로그인 상태에서 /{locale} 접근 시 dashboard로 이동', (tester) async {
    AuthTokenStore.setToken('root-token', provider: 'ory');
    await tester.pumpWidget(_buildTestApp('/ko'));
    await tester.pumpAndSettle();

    expect(find.text('dashboard-page'), findsOneWidget);
    expect(find.textContaining('signin|'), findsNothing);
  });

  testWidgets('/login: login_challenge와 redirect_uri를 전달', (tester) async {
    final encodedRedirectUri = Uri.encodeComponent(
      'https://rp.example.com/callback?x=1',
    );
    await tester.pumpWidget(
      _buildTestApp(
        '/en/login?login_challenge=lc_999&redirect_uri=$encodedRedirectUri',
      ),
    );
    await tester.pumpAndSettle();

    expect(
      find.text(
        'login|challenge=lc_999|redirect=https://rp.example.com/callback?x=1',
      ),
      findsOneWidget,
    );
  });

  testWidgets('비로그인: redirect_uri/login_challenge가 signin으로 전달', (
    tester,
  ) async {
    final encodedRedirectUri = Uri.encodeComponent(
      'https://rp.example.com/cb?x=1',
    );
    await tester.pumpWidget(
      _buildTestApp(
        '/en/profile?login_challenge=lc_123&redirect_uri=$encodedRedirectUri',
      ),
    );
    await tester.pumpAndSettle();

    expect(
      find.text(
        'signin|challenge=lc_123|redirect=https://rp.example.com/cb?x=1',
      ),
      findsOneWidget,
    );
  });

  testWidgets('비로그인: redirect_uri가 없으면 redirect_url을 전달', (tester) async {
    final encodedRedirectUrl = Uri.encodeComponent(
      'https://legacy.example.com/cb',
    );
    await tester.pumpWidget(
      _buildTestApp('/en/profile?redirect_url=$encodedRedirectUrl'),
    );
    await tester.pumpAndSettle();

    expect(
      find.text('signin|challenge=|redirect=https://legacy.example.com/cb'),
      findsOneWidget,
    );
  });

  testWidgets('로그인 상태: profile 접근 시 signin으로 리다이렉트하지 않음', (tester) async {
    AuthTokenStore.setToken('test-token', provider: 'ory');
    await tester.pumpWidget(
      _buildTestApp(
        '/en/profile?redirect_uri=https%3A%2F%2Frp.example.com%2Fcb',
      ),
    );
    await tester.pumpAndSettle();

    expect(find.text('profile-page'), findsOneWidget);
    expect(find.textContaining('signin|'), findsNothing);
  });

  testWidgets('빈 토큰은 로그인으로 간주하지 않고 signin으로 리다이렉트', (tester) async {
    AuthTokenStore.setToken('', provider: 'ory');
    await tester.pumpWidget(_buildTestApp('/ko/profile'));
    await tester.pumpAndSettle();

    expect(find.textContaining('signin|'), findsOneWidget);
    expect(find.text('profile-page'), findsNothing);
  });

  testWidgets('로그인 후 같은 브라우저 새 창/팝업에서도 세션이 유지된다', (tester) async {
    await tester.pumpWidget(_buildTestApp('/en/signin'));
    await tester.pumpAndSettle();
    expect(find.textContaining('signin|'), findsOneWidget);

    AuthTokenStore.setToken('persisted-token', provider: 'ory');

    await tester.pumpWidget(const SizedBox.shrink());
    await tester.pumpAndSettle();

    await tester.pumpWidget(
      _buildTestApp(
        '/en/profile?redirect_uri=https%3A%2F%2Frp.example.com%2Fcb',
      ),
    );
    await tester.pumpAndSettle();

    expect(find.text('profile-page'), findsOneWidget);
    expect(find.textContaining('signin|'), findsNothing);
  });
}
