import 'package:auth/src/features/link_phone/presentation/providers/link_phone_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'package:auth/src/features/link_phone/domain/use_cases/link_phone_use_case.dart';
import 'package:auth/src/features/link_phone/presentation/state/link_phone_view_state.dart';

final linkPhoneViewModelProvider =
    NotifierProvider.autoDispose<LinkPhoneViewModel, LinkPhoneViewState>(
      LinkPhoneViewModel.new,
    );

class LinkPhoneViewModel extends Notifier<LinkPhoneViewState> {
  late final LinkPhoneUseCase _linkPhoneUseCase;
  late final TextEditingController phoneNumberController;
  late final TextEditingController codeController;

  @override
  LinkPhoneViewState build() {
    _linkPhoneUseCase = ref.read(linkPhoneUseCaseProvider);

    phoneNumberController = TextEditingController();
    phoneNumberController.addListener(_onPhoneNumberChanged);

    codeController = TextEditingController();

    ref.onDispose(disposeControllers);

    return const LinkPhoneViewState();
  }

  void _onPhoneNumberChanged() {
    final raw = phoneNumberController.text;
    state = state.copyWith(
      phoneNumber: raw,
      errorMessage: '',
      codeVerified: false,
    );
  }

  void updateDialCode(String dialCode) {
    state = state.copyWith(
      dialCode: dialCode,
      errorMessage: '',
      codeVerified: false,
    );
  }

  void updateCode(String code) {
    codeController.text = code;
    state = state.copyWith(errorMessage: '', codeVerified: false);
  }

  Future<void> requestCode() async {
    final trimmedNumber = state.phoneNumber.trim();

    if (trimmedNumber.isEmpty) {
      state = state.copyWith(
        errorMessage: 'errorMessagePhoneIsEmpty',
        codeVerified: false,
      );
      return;
    }

    final fullPhone = '${state.dialCode}$trimmedNumber';

    state = state.copyWith(
      isLoading: true,
      errorMessage: '',
      codeRequested: false,
      codeVerified: false,
    );

    try {
      await _linkPhoneUseCase.requestCode(phone: fullPhone);
      if (!ref.mounted) return;

      state = state.copyWith(
        isLoading: false,
        errorMessage: '',
        codeRequested: true,
      );
    } catch (e) {
      if (!ref.mounted) return;

      state = state.copyWith(
        isLoading: false,
        errorMessage: e.toString(),
        codeRequested: false,
        codeVerified: false,
      );
    }
  }

  Future<void> verifyCode() async {
    final dialCode = state.dialCode;
    final phoneNumber = state.phoneNumber.trim();
    final code = codeController.text.trim();
    final fullPhone = '$dialCode$phoneNumber';

    if (phoneNumber.isEmpty) {
      state = state.copyWith(
        errorMessage: 'errorMessagePhoneIsEmpty',
        codeVerified: false,
      );
      return;
    }

    if (code.isEmpty) {
      state = state.copyWith(
        errorMessage: 'errorMessageCodeIsEmpty',
        codeVerified: false,
      );
      return;
    }

    state = state.copyWith(
      isLoading: true,
      errorMessage: '',
      codeVerified: false,
    );

    try {
      await _linkPhoneUseCase.verifyCode(phone: fullPhone, code: code);
      if (!ref.mounted) return;

      state = state.copyWith(
        isLoading: false,
        errorMessage: '',
        codeVerified: true,
      );
    } catch (e) {
      if (!ref.mounted) return;

      state = state.copyWith(
        isLoading: false,
        errorMessage: e.toString(),
        codeVerified: false,
      );
    }
  }

  void disposeControllers() {
    phoneNumberController.removeListener(_onPhoneNumberChanged);
    phoneNumberController.dispose();
    codeController.dispose();
  }
}
