import 'dart:async';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/menu/view/widgets/securty/bloc/security_event.dart';
import 'package:syncrow_app/features/menu/view/widgets/securty/bloc/security_state.dart';
import 'package:syncrow_app/services/api/authentication_api.dart';

class SecurityBloc extends Bloc<SecurityEvent, SecurityState> {
  bool _isPasswordVisible = false;
  String otpCode = '';
  String validate = '';
  SecurityBloc() : super(PasswordVisibilityState(false)) {
    on<SetPassword>(_onSetPassword);
    on<TogglePasswordVisibility>(_onTogglePasswordVisibility);
    on<StartTimerEvent>(_onStartTimer);
    on<StopTimerEvent>(_onStopTimer);
    on<UpdateTimerEvent>(_onUpdateTimer);
    on<VerifyPassCodeEvent>(verifyCode);
    on<ChangePasswordEvent>(changePassword);
  }

  void _onSetPassword(SetPassword event, Emitter<SecurityState> emit) {
    if (event.password.length < 6) {
      emit(PasswordErrorState('Password must be at least 6 characters long.'));
    } else {
      emit(PasswordSetState('Password successfully set.'));
    }
  }

  void _onTogglePasswordVisibility(
      TogglePasswordVisibility event, Emitter<SecurityState> emit) {
    _isPasswordVisible = !_isPasswordVisible;
    emit(PasswordVisibilityState(_isPasswordVisible));
  }

  String? passwordValidator(String? value) {
    if (value == null || value.isEmpty) {
      return 'Please enter your password';
    }
    List<String> validationErrors = [];

    if (!RegExp(r'^(?=.*[a-z])').hasMatch(value)) {
      validationErrors.add(' - one lowercase letter');
    }
    if (!RegExp(r'^(?=.*[A-Z])').hasMatch(value)) {
      validationErrors.add(' - one uppercase letter');
    }
    if (!RegExp(r'^(?=.*\d)').hasMatch(value)) {
      validationErrors.add(' - one number');
    }
    if (!RegExp(r'^(?=.*[@$!%*?&])').hasMatch(value)) {
      validationErrors.add(' - one special character');
    }
    if (value.length < 8) {
      validationErrors.add(' - minimum 8 characters');
    }

    if (validationErrors.isNotEmpty) {
      return 'Password must contain at least:\n${validationErrors.join('\n')}';
    }

    return null;
  }

  TextEditingController newPassword = TextEditingController();

  Timer? _timer;
  int _remainingTime = 0;

  Future _onStartTimer(
      StartTimerEvent event, Emitter<SecurityState> emit) async {
    if (_timer != null && _timer!.isActive) {
      return;
    }
    _remainingTime = 1;
    add(UpdateTimerEvent(
        remainingTime: _remainingTime, isButtonEnabled: false));
    try {
      _remainingTime = 30;
      var res = (await AuthenticationAPI.sendOtp(body: {
        'email': HomeCubit.user!.email,
        'type': 'PASSWORD',
        if (HomeCubit.user!.regionUuid != null)
          'regionUuid': HomeCubit.user!.regionUuid
      }));
      _remainingTime = res['cooldown'];
    } on DioException catch (e) {
      if (e.response!.statusCode == 400) {
        final errorData = e.response!.data;
        String errorMessage = errorData['message'];
        if (errorMessage == 'User not found') {
          validate = 'Invalid Credential';
          emit(AuthInitialState());
          return 1;
        } else {
          validate = '';
          _remainingTime = errorData['data']['cooldown'] ?? 1;
          emit(AuthInitialState());
        }
      } else {
        emit(AuthInitialState());

        return 1;
      }
      emit(AuthInitialState());
    } catch (e) {
      emit(AuthInitialState());

      return 1;
    }

    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      _remainingTime--;
      if (_remainingTime <= 0) {
        _timer?.cancel();
        add(UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true));
      } else {
        add(UpdateTimerEvent(
            remainingTime: _remainingTime, isButtonEnabled: false));
      }
    });
  }

  void _onStopTimer(StopTimerEvent event, Emitter<SecurityState> emit) {
    _timer?.cancel();
    emit(TimerState(isButtonEnabled: true, remainingTime: 0));
  }

  void _onUpdateTimer(UpdateTimerEvent event, Emitter<SecurityState> emit) {
    emit(TimerState(
        isButtonEnabled: event.isButtonEnabled,
        remainingTime: event.remainingTime));
  }

  String formattedTime(int time) {
    final int days = (time / 86400).floor(); // 86400 seconds in a day
    final int hours = ((time % 86400) / 3600).floor();
    final int minutes = (((time % 86400) % 3600) / 60).floor();
    final int seconds = (((time % 86400) % 3600) % 60).floor();

    final String formattedTime = [
      if (days > 0) '${days}d', // Append 'd' for days
      if (days > 0 || hours > 0)
        hours
            .toString()
            .padLeft(2, '0'), // Show hours if there are days or hours
      minutes.toString().padLeft(2, '0'),
      seconds.toString().padLeft(2, '0'),
    ].join(':');

    return formattedTime;
  }

  Future<void> verifyCode(
      VerifyPassCodeEvent event, Emitter<SecurityState> emit) async {
    emit(LoadingForgetState());
    try {
      final response = await AuthenticationAPI.verifyPassCode(body: {
        'email': HomeCubit.user!.email!,
        'type': 'PASSWORD',
        'otpCode': otpCode
      });
      if (response['statusCode'] == 200) {
        _timer?.cancel();
        emit(SuccessForgetState());
      }
    } on DioException catch (e) {
      final errorData = e.response!.data;
      String errorMessage =
          errorData['error']['message'] ?? 'something went wrong';
      validate = errorMessage;
      emit(AuthInitialState());
    }
  }

  Future<void> changePassword(
      ChangePasswordEvent event, Emitter<SecurityState> emit) async {
    emit(LoadingForgetState());
    try {

      final response = await AuthenticationAPI.forgetPassword(
        email: HomeCubit.user!.email!,
        otpCode: event.otpCode,
        password: newPassword.text,
      );
      emit(ChangedPassState());
    } on DioException catch (e) {
      final errorData = e.response!.data;
      String errorMessage =
          errorData['error']['message'] ?? 'something went wrong';
      validate = errorMessage;
      emit(AuthInitialState());
    }
  }
  
}
