import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:formz/formz.dart';
import '../../../../core/form_inputs/form_inputs.dart';
import '../../data/auth_repository.dart';

class ResetPasswordState extends Equatable {
  final Email email;
  final VerificationCode code;
  final Password newPassword;
  final Password confirmPassword;
  final FormzSubmissionStatus status;
  final String? errorMessage;
  final bool isSuccess;
  final int resendCountdown;
  final bool codeSent;

  const ResetPasswordState({
    this.email = const Email.pure(),
    this.code = const VerificationCode.pure(),
    this.newPassword = const Password.pure(),
    this.confirmPassword = const Password.pure(),
    this.status = FormzSubmissionStatus.initial,
    this.errorMessage,
    this.isSuccess = false,
    this.resendCountdown = 0,
    this.codeSent = false,
  });

  bool get canSubmit {
    if (!codeSent) {
      return email.isValid && status != FormzSubmissionStatus.inProgress;
    }
    return email.isValid &&
        code.isValid &&
        newPassword.isValid &&
        confirmPassword.isValid &&
        newPassword.value == confirmPassword.value &&
        status != FormzSubmissionStatus.inProgress;
  }

  ResetPasswordState copyWith({
    Email? email,
    VerificationCode? code,
    Password? newPassword,
    Password? confirmPassword,
    FormzSubmissionStatus? status,
    String? errorMessage,
    bool? isSuccess,
    int? resendCountdown,
    bool? codeSent,
  }) {
    return ResetPasswordState(
      email: email ?? this.email,
      code: code ?? this.code,
      newPassword: newPassword ?? this.newPassword,
      confirmPassword: confirmPassword ?? this.confirmPassword,
      status: status ?? this.status,
      errorMessage: errorMessage,
      isSuccess: isSuccess ?? this.isSuccess,
      resendCountdown: resendCountdown ?? this.resendCountdown,
      codeSent: codeSent ?? this.codeSent,
    );
  }

  @override
  List<Object?> get props => [
    email,
    code,
    newPassword,
    confirmPassword,
    status,
    errorMessage,
    isSuccess,
    resendCountdown,
    codeSent,
  ];
}

class ResetPasswordCubit extends Cubit<ResetPasswordState> {
  final AuthRepository _repository;
  Timer? _resendTimer;

  ResetPasswordCubit(this._repository) : super(const ResetPasswordState());

  @override
  Future<void> close() {
    _resendTimer?.cancel();
    return super.close();
  }

  void emailChanged(String value) {
    emit(state.copyWith(email: Email.dirty(value), errorMessage: null));
  }

  void codeChanged(String value) {
    emit(
      state.copyWith(code: VerificationCode.dirty(value), errorMessage: null),
    );
  }

  void newPasswordChanged(String value) {
    emit(
      state.copyWith(newPassword: Password.dirty(value), errorMessage: null),
    );
  }

  void confirmPasswordChanged(String value) {
    emit(
      state.copyWith(
        confirmPassword: Password.dirty(value),
        errorMessage: null,
      ),
    );
  }

  Future<void> sendCode() async {
    if (state.status == FormzSubmissionStatus.inProgress ||
        state.resendCountdown > 0) {
      return;
    }

    if (!state.email.isValid) {
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          errorMessage: state.email.value.isEmpty ? '请输入邮箱' : '邮箱格式不正确',
        ),
      );
      return;
    }

    emit(
      state.copyWith(
        status: FormzSubmissionStatus.inProgress,
        codeSent: true,
        resendCountdown: 60,
        errorMessage: null,
      ),
    );
    _startResendCountdown();

    try {
      await _repository.requestPasswordReset(state.email.value);
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.success,
          errorMessage: 'CODE_SENT_SUCCESS',
        ),
      );
    } catch (e) {
      _cancelResendCountdown();
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          codeSent: false,
          resendCountdown: 0,
          errorMessage: '网络错误，请稍后重试',
        ),
      );
    }
  }

  void _cancelResendCountdown() {
    _resendTimer?.cancel();
  }

  void _startResendCountdown() {
    _cancelResendCountdown();
    _resendTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      final newCountdown = state.resendCountdown - 1;
      if (newCountdown <= 0) {
        timer.cancel();
        emit(state.copyWith(resendCountdown: 0));
      } else {
        emit(state.copyWith(resendCountdown: newCountdown));
      }
    });
  }

  Future<void> resendCode() async {
    if (state.resendCountdown > 0 ||
        state.status == FormzSubmissionStatus.inProgress) {
      return;
    }

    if (!state.email.isValid) {
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          errorMessage: state.email.value.isEmpty ? '请输入邮箱' : '邮箱格式不正确',
        ),
      );
      return;
    }

    emit(
      state.copyWith(
        status: FormzSubmissionStatus.inProgress,
        codeSent: true,
        resendCountdown: 60,
        errorMessage: null,
      ),
    );
    _startResendCountdown();

    try {
      await _repository.requestPasswordReset(state.email.value);
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.success,
          errorMessage: 'CODE_SENT_SUCCESS',
        ),
      );
    } catch (e) {
      _cancelResendCountdown();
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          resendCountdown: 0,
          errorMessage: '网络错误，请稍后重试',
        ),
      );
    }
  }

  Future<void> submit() async {
    if (!state.codeSent) {
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          errorMessage: '请先获取验证码',
        ),
      );
      return;
    }

    if (!state.email.isValid) {
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          errorMessage: '请输入有效的邮箱地址',
        ),
      );
      return;
    }

    if (!state.code.isValid) {
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          errorMessage: '请输入6位验证码',
        ),
      );
      return;
    }

    if (!state.newPassword.isValid) {
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          errorMessage: '新密码至少6位',
        ),
      );
      return;
    }

    if (!state.confirmPassword.isValid) {
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          errorMessage: '请输入确认密码',
        ),
      );
      return;
    }

    if (state.newPassword.value != state.confirmPassword.value) {
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          errorMessage: '两次密码输入不一致',
        ),
      );
      return;
    }

    emit(
      state.copyWith(
        status: FormzSubmissionStatus.inProgress,
        errorMessage: null,
      ),
    );

    try {
      await _repository.confirmPasswordReset(
        email: state.email.value,
        token: state.code.value,
        newPassword: state.newPassword.value,
      );
      emit(
        state.copyWith(status: FormzSubmissionStatus.success, isSuccess: true),
      );
    } catch (e) {
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          errorMessage: '密码重置失败，请检查验证码',
        ),
      );
    }
  }
}
