import 'dart:developer' as developer;

import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../core/network/api_response.dart';
import '../core/network/dio_client.dart';
import '../data/services/auth_service.dart';

// ── State ──────────────────────────────────────────────────

class FundPasswordState {
  final bool isLoading;
  final bool isSendingCode;
  final String? errorMessage;
  final String? successMessage;
  final int codeCooldown;

  const FundPasswordState({
    this.isLoading = false,
    this.isSendingCode = false,
    this.errorMessage,
    this.successMessage,
    this.codeCooldown = 0,
  });

  FundPasswordState copyWith({
    bool? isLoading,
    bool? isSendingCode,
    String? errorMessage,
    String? successMessage,
    int? codeCooldown,
  }) =>
      FundPasswordState(
        isLoading: isLoading ?? this.isLoading,
        isSendingCode: isSendingCode ?? this.isSendingCode,
        errorMessage: errorMessage,
        successMessage: successMessage,
        codeCooldown: codeCooldown ?? this.codeCooldown,
      );
}

// ── Notifier ───────────────────────────────────────────────

class FundPasswordNotifier extends Notifier<FundPasswordState> {
  AuthService get _service => AuthService(ref.read(dioClientProvider));

  @override
  FundPasswordState build() => const FundPasswordState();

  void clearError() => state = state.copyWith(errorMessage: null);
  void clearSuccess() => state = state.copyWith(successMessage: null);

  /// 密码校验：7-20位字母+数字混合
  static final _passwordRegex =
      RegExp(r'^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{7,20}$');

  static bool validatePassword(String password) =>
      _passwordRegex.hasMatch(password);

  /// 首次设置资金密码 — POST uc/approve/transaction/password
  Future<bool> setPassword(String password) async {
    state = state.copyWith(isLoading: true, errorMessage: null);
    try {
      await _service.setFundPassword(password);
      state = state.copyWith(
        isLoading: false,
        successMessage: 'setSuccess',
      );
      return true;
    } catch (e) {
      state = state.copyWith(
        isLoading: false,
        errorMessage: _parseError(e),
      );
      return false;
    }
  }

  /// 发送邮箱验证码 — POST uc/transaction/email/code
  Future<bool> sendEmailCode() async {
    state = state.copyWith(isSendingCode: true, errorMessage: null);
    try {
      await _service.sendFundPasswordEmailCode();
      state = state.copyWith(isSendingCode: false);
      _startCountdown();
      return true;
    } catch (e) {
      state = state.copyWith(
        isSendingCode: false,
        errorMessage: _parseError(e),
      );
      return false;
    }
  }

  /// 重置资金密码 — POST uc/approve/reset/transaction/password
  Future<bool> resetPassword({
    required String newPassword,
    required String vcode,
  }) async {
    state = state.copyWith(isLoading: true, errorMessage: null);
    try {
      await _service.resetFundPassword(
        newPassword: newPassword,
        vcode: vcode,
      );
      state = state.copyWith(
        isLoading: false,
        successMessage: 'changeSuccess',
      );
      return true;
    } catch (e) {
      state = state.copyWith(
        isLoading: false,
        errorMessage: _parseError(e),
      );
      return false;
    }
  }

  void _startCountdown() {
    state = state.copyWith(codeCooldown: 60);
    Future.doWhile(() async {
      await Future.delayed(const Duration(seconds: 1));
      final remaining = state.codeCooldown - 1;
      state = state.copyWith(codeCooldown: remaining);
      return remaining > 0;
    });
  }

  String _parseError(Object e) {
    developer.log('FundPassword error: $e', name: 'FUND_PWD', error: e);
    if (e is DioException) {
      if (e.error is ApiException) {
        return (e.error as ApiException).message;
      }
      final responseData = e.response?.data;
      if (responseData is Map<String, dynamic>) {
        final msg = responseData['message'] as String? ??
            responseData['msg'] as String?;
        if (msg != null && msg.isNotEmpty) return msg;
      }
      return e.message ?? '网络请求异常';
    }
    if (e is ApiException) return e.message;
    return e.toString();
  }
}

// ── Provider ──────────────────────────────────────────────

final fundPasswordProvider =
    NotifierProvider<FundPasswordNotifier, FundPasswordState>(
  FundPasswordNotifier.new,
);
