import 'dart:async';

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:qpay/screens/onboarding/verify/verify_controller.dart';
import 'package:qpay/screens/onboarding/widgets/onboarding_layout.dart';
import 'package:skeletonizer/skeletonizer.dart';

class VerifyScreen extends StatefulWidget {
  const VerifyScreen({super.key});

  @override
  State<VerifyScreen> createState() => _VerifyScreenState();
}

class _VerifyScreenState extends State<VerifyScreen> {
  late VerifyController verifyController;
  String? errorMessage;
  // Resend cooldown
  final Duration _resendCooldown = const Duration(minutes: 1);
  DateTime? _resendAvailableAt;
  Timer? _resendTimer;
  int _remainingSeconds = 0;

  @override
  void initState() {
    super.initState();
    verifyController = VerifyController(context);
    // Start the resend cooldown immediately since the OTP was just sent
    // during registration.
    _startResendCooldown();
  }

  final List<TextEditingController> _codeControllers = List.generate(
    6,
    (index) => TextEditingController(),
  );
  final List<FocusNode> _focusNodes = List.generate(6, (index) => FocusNode());

  @override
  void dispose() {
    for (var controller in _codeControllers) {
      controller.dispose();
    }
    for (var node in _focusNodes) {
      node.dispose();
    }
    _resendTimer?.cancel();
    super.dispose();
  }

  void _startResendCooldown() {
    _resendTimer?.cancel();
    _resendAvailableAt = DateTime.now().add(_resendCooldown);
    _remainingSeconds = _resendCooldown.inSeconds;
    if (mounted) setState(() {});
    _resendTimer = Timer.periodic(
      const Duration(seconds: 1),
      (_) => _updateRemaining(),
    );
  }

  void _updateRemaining() {
    if (_resendAvailableAt == null) return;
    final seconds = _resendAvailableAt!.difference(DateTime.now()).inSeconds;
    if (seconds <= 0) {
      _resendTimer?.cancel();
      setState(() {
        _resendAvailableAt = null;
        _remainingSeconds = 0;
      });
    } else {
      setState(() {
        _remainingSeconds = seconds;
      });
    }
  }

  String _formatDuration(int totalSeconds) {
    final mins = (totalSeconds ~/ 60).toString().padLeft(2, '0');
    final secs = (totalSeconds % 60).toString().padLeft(2, '0');
    return '$mins:$secs';
  }

  void showErrorMessage(String? message) {
    setState(() {
      errorMessage = message;
    });
  }

  void _onCodeChanged(String value, int index) {
    if (value.length == 1 && index < 5) {
      _focusNodes[index + 1].requestFocus();
    } else if (value.isEmpty && index > 0) {
      _focusNodes[index - 1].requestFocus();
    }
  }

  Future<void> _submitCode() async {
    showErrorMessage(null);
    String code = '';
    for (var controller in _codeControllers) {
      code += controller.text;
    }

    if (code.length != 6) {
      showErrorMessage('Invalid code');
      return;
    }
    verifyController.updateCode(code);
    final response = await verifyController.verifyOtp();
    if (!mounted) return;
    if (response.isSuccess) {
      if (verifyController.model.status == 'done') {
        context.go('/onboarding/complete');
      } else {
        showErrorMessage(
          verifyController.model.errorMessage ?? 'Verification failed',
        );
      }
    } else {
      showErrorMessage(
        response.error ?? 'Verification failed. Please try again.',
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return ListenableBuilder(
      listenable: verifyController,
      builder: (context, child) {
        return OnboardingLayout(
          showBackButton: true,
          trailingLabel: 'Sign in',
          trailingRoute: '/onboarding/login',
          trailingIcon: Icons.login_rounded,
          bottomLinkLabel: 'Continue as guest?',
          bottomLinkRoute: '/',
          child: OnboardingCard(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                const OnboardingHero(
                  icon: Icons.sms_rounded,
                  title: 'Verify your account',
                  subtitle:
                      'Enter the 6-digit code we sent to your phone or email.',
                ),
                const SizedBox(height: 32),
                _buildCodeInputs(),
                const SizedBox(height: 16),
                if (errorMessage != null)
                  Padding(
                    padding: const EdgeInsets.symmetric(vertical: 8),
                    child: Center(
                      child: Text(
                        errorMessage!,
                        style: TextStyle(
                          color: Theme.of(context).colorScheme.error,
                          fontSize: 14,
                          fontWeight: FontWeight.w500,
                        ),
                      ),
                    ),
                  ),
                const SizedBox(height: 8),
                _buildResendRow(),
                const SizedBox(height: 28),
                Skeletonizer(
                  enabled: verifyController.model.isLoading,
                  child: OnboardingPrimaryButton(
                    label: 'Verify code',
                    icon: Icons.check_rounded,
                    onPressed: _submitCode,
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  Widget _buildCodeInputs() {
    final colorScheme = Theme.of(context).colorScheme;
    final borderRadius = BorderRadius.circular(14);

    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: List.generate(6, (index) {
        return SizedBox(
          width: 48,
          child: TextFormField(
            controller: _codeControllers[index],
            focusNode: _focusNodes[index],
            textAlign: TextAlign.center,
            keyboardType: TextInputType.number,
            maxLength: 1,
            style: TextStyle(
              fontSize: 22,
              fontWeight: FontWeight.w700,
              color: colorScheme.onSurface,
            ),
            decoration: InputDecoration(
              counterText: '',
              filled: true,
              fillColor: colorScheme.surface,
              contentPadding: const EdgeInsets.symmetric(vertical: 14),
              enabledBorder: OutlineInputBorder(
                borderRadius: borderRadius,
                borderSide: BorderSide(
                  color: colorScheme.onSurface.withValues(alpha: 0.12),
                ),
              ),
              focusedBorder: OutlineInputBorder(
                borderRadius: borderRadius,
                borderSide: BorderSide(color: colorScheme.primary, width: 1.6),
              ),
              errorBorder: OutlineInputBorder(
                borderRadius: borderRadius,
                borderSide: BorderSide(color: colorScheme.error),
              ),
              focusedErrorBorder: OutlineInputBorder(
                borderRadius: borderRadius,
                borderSide: BorderSide(color: colorScheme.error, width: 1.6),
              ),
            ),
            onChanged: (value) => _onCodeChanged(value, index),
          ),
        );
      }),
    );
  }

  Widget _buildResendRow() {
    final colorScheme = Theme.of(context).colorScheme;
    return Center(
      child: Wrap(
        crossAxisAlignment: WrapCrossAlignment.center,
        children: [
          Text(
            "Didn't receive the code?",
            style: TextStyle(
              color: colorScheme.onSurface.withValues(alpha: 0.65),
              fontSize: 14,
            ),
          ),
          // Show countdown while cooling down, otherwise show resend button
          _remainingSeconds == 0
              ? TextButton(
                  onPressed: verifyController.model.isLoading
                      ? null
                      : () async {
                          // Start cooldown immediately to give immediate feedback
                          _startResendCooldown();
                          final resp = await verifyController.resendOtp();
                          if (!mounted) return;
                          if (!resp.isSuccess) {
                            // cancel cooldown on failure and show error
                            _resendTimer?.cancel();
                            setState(() {
                              _resendAvailableAt = null;
                              _remainingSeconds = 0;
                            });
                            showErrorMessage(
                              resp.error ?? 'Failed to resend code',
                            );
                          }
                        },
                  style: TextButton.styleFrom(
                    foregroundColor: colorScheme.primary,
                    padding: const EdgeInsets.symmetric(horizontal: 6),
                    textStyle: const TextStyle(
                      fontSize: 14,
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                  child: const Text('Resend code'),
                )
              : Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 6),
                  child: Text(
                    'Resend in ${_formatDuration(_remainingSeconds)}',
                    style: TextStyle(
                      color: colorScheme.onSurface.withValues(alpha: 0.65),
                      fontSize: 14,
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                ),
        ],
      ),
    );
  }
}
