import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:formz/formz.dart';
import 'package:equatable/equatable.dart';
import '../../../../core/api/api_exception.dart';
import '../../data/auth_repository.dart';
import '../../data/models/login_request.dart';
import '../../data/models/auth_response.dart';
import '../../../../core/form_inputs/form_inputs.dart';

class LoginState extends Equatable {
  final Email email;
  final Password password;
  final FormzSubmissionStatus status;
  final String? errorMessage;

  const LoginState({
    this.email = const Email.pure(),
    this.password = const Password.pure(),
    this.status = FormzSubmissionStatus.initial,
    this.errorMessage,
  });

  bool get isValid => email.isValid && password.isValid;

  LoginState copyWith({
    Email? email,
    Password? password,
    FormzSubmissionStatus? status,
    String? errorMessage,
  }) {
    return LoginState(
      email: email ?? this.email,
      password: password ?? this.password,
      status: status ?? this.status,
      errorMessage: errorMessage,
    );
  }

  @override
  List<Object?> get props => [email, password, status, errorMessage];
}

class LoginCubit extends Cubit<LoginState> {
  final AuthRepository _repository;

  LoginCubit(this._repository) : super(const LoginState());

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

  void passwordChanged(String value) {
    emit(state.copyWith(password: Password.dirty(value)));
  }

  Future<AuthResponse?> submit() async {
    if (!state.isValid) return null;

    emit(state.copyWith(status: FormzSubmissionStatus.inProgress));

    try {
      final response = await _repository.createSession(
        LoginRequest(email: state.email.value, password: state.password.value),
      );
      emit(state.copyWith(status: FormzSubmissionStatus.success));
      return response;
    } catch (e) {
      final message = e is ApiException ? e.message : e.toString();
      emit(
        state.copyWith(
          status: FormzSubmissionStatus.failure,
          errorMessage: message,
        ),
      );
      return null;
    }
  }
}
