import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:staff_authentication/src/presentation/blocs/auth_bloc.dart';
import 'package:staff_authentication/src/presentation/blocs/auth_event.dart';
import 'package:staff_authentication/src/presentation/blocs/auth_state.dart';
import 'package:staff_authentication/staff_authentication.dart';

import 'package:krow_core/core.dart';
import '../widgets/phone_verification_page/otp_verification.dart';
import '../widgets/phone_verification_page/phone_input.dart';

/// A combined page for phone number entry and OTP verification.
///
/// This page coordinates the authentication flow by switching between
/// [PhoneInput] and [OtpVerification] based on the current [AuthState].
class PhoneVerificationPage extends StatefulWidget {
  /// The authentication mode (login or signup).
  final AuthMode mode;

  /// Creates a [PhoneVerificationPage].
  const PhoneVerificationPage({super.key, required this.mode});

  @override
  State<PhoneVerificationPage> createState() => _PhoneVerificationPageState();
}

class _PhoneVerificationPageState extends State<PhoneVerificationPage> {
  late final AuthBloc _authBloc;

  @override
  void initState() {
    super.initState();
    _authBloc = Modular.get<AuthBloc>();
    _authBloc.add(AuthResetRequested(mode: widget.mode));
  }

  @override
  void dispose() {
    if (!_authBloc.isClosed) {
      _authBloc.add(AuthResetRequested(mode: widget.mode));
    }
    super.dispose();
  }

  /// Handles the request to send a verification code to the provided phone number.
  void _onSendCode({
    required BuildContext context,
    required String phoneNumber,
  }) {
    String normalized = phoneNumber.replaceAll(RegExp(r'\D'), '');

    // Handle US numbers entered with a leading 1
    if (normalized.length == 11 && normalized.startsWith('1')) {
      normalized = normalized.substring(1);
    }

    if (normalized.length == 10) {
      BlocProvider.of<AuthBloc>(
        context,
      ).add(
        AuthSignInRequested(phoneNumber: '+1$normalized', mode: widget.mode),
      );
    } else {
      UiSnackbar.show(
        context,
        message: t.staff_authentication.phone_verification_page.validation_error,
        type: UiSnackbarType.error,
        margin: const EdgeInsets.only(bottom: 180, left: 16, right: 16),
      );
    }
  }

  /// Handles the submission of the OTP code.
  void _onOtpSubmitted({
    required BuildContext context,
    required String otp,
    required String verificationId,
  }) {
    BlocProvider.of<AuthBloc>(
      context,
    ).add(
      AuthOtpSubmitted(
        verificationId: verificationId,
        smsCode: otp,
        mode: widget.mode,
      ),
    );
  }

  /// Handles the request to resend the verification code using the phone number in the state.
  void _onResend({required BuildContext context}) {
    BlocProvider.of<AuthBloc>(context).add(
      AuthSignInRequested(mode: widget.mode),
    );
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider<AuthBloc>.value(
      value: _authBloc,
      child: Builder(
        builder: (BuildContext context) {
          return BlocListener<AuthBloc, AuthState>(
            listener: (BuildContext context, AuthState state) {
              if (state.status == AuthStatus.authenticated) {
                if (state.mode == AuthMode.signup) {
                  Modular.to.toProfileSetup();
                } else {
                  Modular.to.toStaffHome();
                }
              } else if (state.status == AuthStatus.error &&
                  state.mode == AuthMode.signup) {
                final String messageKey = state.errorMessage ?? '';
                // Handle specific business logic errors for signup
                if (messageKey == 'errors.auth.account_exists') {
                  UiSnackbar.show(
                    context,
                    message: translateErrorKey(messageKey),
                    type: UiSnackbarType.error,
                    margin: const EdgeInsets.only(bottom: 180, left: 16, right: 16),
                  );
                  Future<void>.delayed(const Duration(seconds: 5), () {
                    if (!mounted) return;
                    Modular.to.navigate('/');
                  });
                } else if (messageKey == 'errors.auth.unauthorized_app') {
                  Modular.to.pop();
                }
              }
            },
            child: BlocBuilder<AuthBloc, AuthState>(
              builder: (BuildContext context, AuthState state) {
                // Check if we are in the OTP step
                final bool isOtpStep =
                    state.status == AuthStatus.codeSent ||
                    (state.status == AuthStatus.error &&
                        state.verificationId != null) ||
                    (state.status == AuthStatus.loading &&
                        state.verificationId != null);

                return WillPopScope(
                  onWillPop: () async {
                    BlocProvider.of<AuthBloc>(
                      context,
                    ).add(AuthResetRequested(mode: widget.mode));
                    return true;
                  },
                  child: Scaffold(
                    appBar: UiAppBar(
                      centerTitle: true,
                      showBackButton: true,
                      onLeadingPressed: () {
                        BlocProvider.of<AuthBloc>(context).add(
                          AuthResetRequested(mode: widget.mode),
                        );
                        Navigator.of(context).pop();
                      },
                    ),
                    body: SafeArea(
                      child: isOtpStep
                          ? OtpVerification(
                              state: state,
                              onOtpSubmitted: (String otp) => _onOtpSubmitted(
                                context: context,
                                otp: otp,
                                verificationId: state.verificationId ?? '',
                              ),
                              onResend: () => _onResend(context: context),
                              onContinue: () => _onOtpSubmitted(
                                context: context,
                                otp: state.otp,
                                verificationId: state.verificationId ?? '',
                              ),
                            )
                        : PhoneInput(
                            state: state,
                            onSendCode: (String phoneNumber) => _onSendCode(
                              context: context,
                              phoneNumber: phoneNumber,
                            ),
                          ),
                    ),
                  ),
                );
              },
            ),
          );
        },
      ),
    );
  }
}
