import 'package:auth/src/features/login/presentation/loading_google_screen.dart';
import 'package:auth/src/features/login/presentation/state/login_view_model.dart';
import 'package:auth/src/features/login/presentation/widgets/two_factor_bottom_sheet.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:navigation/navigation.dart';
import 'package:sf_localizations/sf_localizations.dart';

class LoginScreen extends ConsumerWidget {
  final NavigationContract navigationContract;

  const LoginScreen({super.key, required this.navigationContract});

  Future<void> _onLogIn(BuildContext context, WidgetRef ref) async {
    FocusManager.instance.primaryFocus?.unfocus();

    final vm = ref.read(loginViewModelProvider.notifier);

    final String? token = await vm.login();
    if (!context.mounted) return;

    if (token == null || token.isEmpty) return;

    vm.prepareTwoFactor();

    final bool? verified = await showModalBottomSheet<bool>(
      context: context,
      isScrollControlled: true,
      useSafeArea: true,
      isDismissible: false,
      enableDrag: false,
      backgroundColor: Colors.transparent,
      builder: (context) {
        return Consumer(
          builder: (context, ref, _) {
            final theme = ref.watch(themePortProvider);
            final vm = ref.read(loginViewModelProvider.notifier);

            final otpErrorKey = ref.watch(
              loginViewModelProvider.select((s) => s.otpError),
            );
            final isOtpLoading = ref.watch(
              loginViewModelProvider.select((s) => s.isOtpLoading),
            );
            final otpCode = ref.watch(
              loginViewModelProvider.select((s) => s.otpCode),
            );

            final otpErrorText = otpErrorKey.isEmpty
                ? ''
                : context.translate(otpErrorKey);

            Future<void> onVerify() async {
              FocusManager.instance.primaryFocus?.unfocus();

              final ok = await vm.twoFactor(token: token);
              if (!context.mounted) return;

              if (ok) Navigator.of(context).pop(true);
            }

            return TwoFactorBottomSheetView(
              theme: theme,
              title: context.translate(I18n.twoFactorTitle),
              subtitle: context.translate(I18n.twoFactorSubtitle),
              verifyText: context.translate(I18n.twoFactorVerify),
              closeText: context.translate(I18n.close),
              isOtpLoading: isOtpLoading,
              otpCode: otpCode,
              otpErrorText: otpErrorText,
              onChanged: vm.setOtpCode,
              onVerify: onVerify,
              onClose: () => Navigator.of(context).pop(false),
            );
          },
        );
      },
    );

    if (!context.mounted) return;

    if (verified == true) {
      navigationContract.goTo(AppRoutes.dashboardHome);
    }
  }

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final theme = ref.watch(themePortProvider);
    final bool isLoading = ref.watch(
      loginViewModelProvider.select((s) => s.isLoading),
    );

    return Scaffold(
      backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
      body: SafeArea(
        child: AbsorbPointer(
          absorbing: isLoading,
          child: SingleChildScrollView(
            padding: EdgeInsets.symmetric(horizontal: 24),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                _Header(theme: theme),
                SizedBox(height: 48),
                const _EmailSection(),
                SizedBox(height: 24),
                _PasswordSection(onSubmitted: () => _onLogIn(context, ref)),
                SizedBox(height: 16),
                _ForgotPassword(navigationContract: navigationContract),
                SizedBox(height: 30),
                _SignInSection(
                  theme: theme,
                  onSignIn: () => _onLogIn(context, ref),
                ),
                SizedBox(height: 30),
                _OrContinueWith(theme: theme),
                SizedBox(height: 24),
                _SocialButtons(theme: theme),
                SizedBox(height: 30),
                _Footer(navigationContract: navigationContract),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _Header extends StatelessWidget {
  const _Header({required this.theme});
  final ThemePort theme;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Icon(
          Icons.check,
          color: theme.getColorFor(ThemeCode.buttonPrimary),
          size: 54,
        ),
        Text(
          context.translate(I18n.welcome),
          textAlign: TextAlign.center,
          style: const TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
        ),
      ],
    );
  }
}

class _EmailSection extends ConsumerWidget {
  const _EmailSection();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final vm = ref.read(loginViewModelProvider.notifier);
    final String emailErrorKey = ref.watch(
      loginViewModelProvider.select((s) => s.emailError),
    );

    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        CustomTextField(
          hint: context.translate(I18n.username),
          label: context.translate(I18n.username),
          controller: vm.emailController,
          keyboardType: TextInputType.emailAddress,
          textInputAction: TextInputAction.next,
        ),
        _FieldErrorText.fromKey(errorKey: emailErrorKey),
      ],
    );
  }
}

class _PasswordSection extends ConsumerWidget {
  const _PasswordSection({required this.onSubmitted});
  final Future<void> Function() onSubmitted;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final vm = ref.read(loginViewModelProvider.notifier);

    final bool passwordVisible = ref.watch(
      loginViewModelProvider.select((s) => s.passwordVisible),
    );
    final String passwordErrorKey = ref.watch(
      loginViewModelProvider.select((s) => s.passwordError),
    );

    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        CustomTextField(
          showPassword: passwordVisible,
          label: context.translate(I18n.password),
          hint: '********',
          controller: vm.passwordController,
          textInputAction: TextInputAction.done,
          onSubmitted: (_) => onSubmitted(),
        ),
        _FieldErrorText.fromKey(errorKey: passwordErrorKey),
      ],
    );
  }
}

class _ForgotPassword extends ConsumerWidget {
  const _ForgotPassword({required this.navigationContract});
  final NavigationContract navigationContract;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final bool isLoading = ref.watch(
      loginViewModelProvider.select((s) => s.isLoading),
    );

    return Align(
      alignment: Alignment.topLeft,
      child: CustomTextButton(
        text: context.translate(I18n.forgotPassword),
        onPressed: isLoading
            ? () {}
            : () => navigationContract.pushTo(AppRoutes.recoverPassword),
        size: 16,
      ),
    );
  }
}

class _SignInSection extends ConsumerWidget {
  const _SignInSection({required this.onSignIn, required this.theme});

  final VoidCallback onSignIn;
  final ThemePort theme;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final bool isLoading = ref.watch(
      loginViewModelProvider.select((s) => s.isLoading),
    );
    final String errorMessage = ref.watch(
      loginViewModelProvider.select((s) => s.errorMessage),
    );

    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        PrimaryButton(
          onPressed: isLoading ? () {} : onSignIn,
          text: context.translate(I18n.signIn),
          color: theme.getColorFor(ThemeCode.buttonPrimary),
          leading: isLoading
              ? const SizedBox(
                  height: 18,
                  width: 18,
                  child: CircularProgressIndicator(
                    strokeWidth: 2,
                    color: Colors.white,
                  ),
                )
              : null,
        ),
        if (errorMessage.isNotEmpty)
          Padding(
            padding: const EdgeInsets.only(top: 12),
            child: Text(
              errorMessage,
              textAlign: TextAlign.center,
              style: TextStyle(
                color: Theme.of(context).colorScheme.error,
                fontSize: 13,
              ),
            ),
          ),
      ],
    );
  }
}

class _OrContinueWith extends StatelessWidget {
  const _OrContinueWith({required this.theme});
  final ThemePort theme;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        const Divider(endIndent: 74, indent: 74),
        Align(
          alignment: Alignment.center,
          child: Container(
            padding: const EdgeInsets.symmetric(horizontal: 14),
            color: theme.getColorFor(ThemeCode.backgroundPrimary),
            child: Text(context.translate(I18n.orContinueWith)),
          ),
        ),
      ],
    );
  }
}

class _SocialButtons extends ConsumerWidget {
  const _SocialButtons({required this.theme});
  final ThemePort theme;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final bool isLoading = ref.watch(
      loginViewModelProvider.select((s) => s.isLoading),
    );

    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        SecondaryButton(
          onPressed: isLoading
              ? () {}
              : () => Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (_) => const LoadingGoogleScreen(),
                  ),
                ),
          radius: 16,
          padding: 44,
          text: context.translate(I18n.google),
          label: 'Google',
        ),
        const SizedBox(width: 16),
        SecondaryButton(
          onPressed: isLoading ? () {} : () {},
          radius: 16,
          padding: 44,
          icon: Icons.apple,
          label: 'Apple',
        ),
      ],
    );
  }
}

class _Footer extends ConsumerWidget {
  const _Footer({required this.navigationContract});
  final NavigationContract navigationContract;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final bool isLoading = ref.watch(
      loginViewModelProvider.select((s) => s.isLoading),
    );

    return Column(
      children: [
        Text(
          context.translate(I18n.dontHaveAccount),
          style: const TextStyle(fontSize: 18, letterSpacing: 0),
        ),
        TextButton(
          onPressed: isLoading
              ? null
              : () => navigationContract.pushTo(AppRoutes.signup),
          child: Text(
            context.translate(I18n.createOneNow),
            style: const TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.w500,
              letterSpacing: 0,
            ),
          ),
        ),
      ],
    );
  }
}

class _FieldErrorText extends StatelessWidget {
  const _FieldErrorText._({required this.text});
  final String text;

  factory _FieldErrorText.fromKey({required String errorKey}) {
    return _FieldErrorText._(text: errorKey);
  }

  @override
  Widget build(BuildContext context) {
    if (text.isEmpty) return const SizedBox.shrink();

    return Padding(
      padding: const EdgeInsets.only(top: 8),
      child: Align(
        alignment: Alignment.centerLeft,
        child: Text(
          context.translate(text),
          style: TextStyle(
            color: Theme.of(context).colorScheme.error,
            fontSize: 12,
          ),
        ),
      ),
    );
  }
}
