import 'dart:developer';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:dio/dio.dart';
import '../core/api_client.dart';
import '../core/local_database.dart';

class UserInfo {
  final String id;
  final String phone;
  final String role;
  final String? name;
  final String? avatarUrl;

  UserInfo({
    required this.id,
    required this.phone,
    this.role = 'User',
    this.name,
    this.avatarUrl,
  });
}

class AuthState {
  final UserInfo? user;
  final bool isLoggedIn;
  final bool isLoading;

  const AuthState({this.user, this.isLoggedIn = false, this.isLoading = true});
}

final authProvider = NotifierProvider<AuthNotifier, AuthState>(
  AuthNotifier.new,
);

final localDbProvider = Provider<LocalDatabase>(
  (ref) => LocalDatabase.instance,
);

final authExpiredNotifierProvider = Provider<AuthExpiredNotifier>((ref) {
  return AuthExpiredNotifier();
});

final apiClientProvider = Provider<ApiClient>((ref) {
  return ApiClient(
    db: ref.watch(localDbProvider),
    authExpiredNotifier: ref.watch(authExpiredNotifierProvider),
  );
});

class AuthNotifier extends Notifier<AuthState> {
  @override
  AuthState build() {
    final removeListener = ref.read(authExpiredNotifierProvider).addListener(
      () {
        state = const AuthState(isLoggedIn: false, isLoading: false);
      },
    );
    ref.onDispose(removeListener);
    _checkAuth();
    // 初始为"加载中"，让启动闸门显示 Splash 盖住登录页/首页初始态
    return const AuthState(isLoggedIn: false, isLoading: true);
  }

  Future<void> _checkAuth() async {
    final db = ref.read(localDbProvider);
    final refresh = await db.read('refresh_token');
    if (refresh == null) {
      // 无 token：判定完成、未登录
      state = const AuthState(isLoggedIn: false, isLoading: false);
      return;
    }

    state = const AuthState(isLoading: true);
    try {
      final response = await Dio(
        BaseOptions(baseUrl: baseUrl),
      ).post('/api/auth/refresh', data: {'refreshToken': refresh});
      final data = response.data['data'];
      if (data != null) {
        await db.write('access_token', data['accessToken']);
        await db.write('refresh_token', data['refreshToken']);
        final u = data['user'] as Map<String, dynamic>?;
        state = AuthState(
          isLoggedIn: true,
          isLoading: false,
          user: UserInfo(id: '', phone: '', role: u?['role'] ?? 'User'),
        );
        _loadProfile();
      } else {
        state = const AuthState(isLoggedIn: false, isLoading: false);
      }
    } catch (_) {
      state = const AuthState(isLoggedIn: false, isLoading: false);
    }
  }

  Future<void> _loadProfile() async {
    // Admin 不查 profile（无 User 记录）
    if (state.user?.role == 'Admin') return;
    try {
      final api = ref.read(apiClientProvider);
      final response = await api.get('/api/user/profile');
      final user = response.data['data'];
      if (user != null) {
        state = AuthState(
          isLoggedIn: true,
          isLoading: false,
          user: UserInfo(
            id: user['id'] ?? '',
            phone: user['phone'] ?? '',
            role: user['role'] ?? state.user?.role ?? 'User',
            name: user['name'],
            avatarUrl: user['avatarUrl'],
          ),
        );
      }
    } catch (e) {
      log('[Auth] loadProfile: $e');
    }
  }

  Future<void> refreshProfile() => _loadProfile();

  /// 发送验证码
  Future<({String? error, String? devCode})> sendSms(String phone) async {
    try {
      final api = ref.read(apiClientProvider);
      final response = await api.post(
        '/api/auth/send-sms',
        data: {'phone': phone},
      );
      return (
        error: null,
        devCode: response.data['data']?['devCode'] as String?,
      );
    } catch (e) {
      return (error: '发送失败: $e', devCode: null);
    }
  }

  /// 注册（新用户，需选身份）
  Future<String?> register(
    String phone,
    String code,
    String name,
    String doctorId,
  ) async {
    try {
      final api = ref.read(apiClientProvider);
      final response = await api.post(
        '/api/auth/register',
        data: {
          'phone': phone,
          'smsCode': code,
          'name': name,
          'doctorId': doctorId,
        },
      );
      final data = response.data['data'];
      if (data == null) return response.data['message'] ?? '注册失败';

      await api.saveTokens(data['accessToken'], data['refreshToken']);
      final user = data['user'];
      state = AuthState(
        isLoggedIn: true,
        isLoading: false,
        user: UserInfo(
          id: user['id'] ?? '',
          phone: user['phone'] ?? '',
          role: user['role'] ?? 'User',
        ),
      );
      return null;
    } catch (e) {
      return '注册失败: $e';
    }
  }

  /// 登录（已有账号）
  Future<String?> login(String phone, String code) async {
    try {
      final api = ref.read(apiClientProvider);
      final response = await api.post(
        '/api/auth/login',
        data: {'phone': phone, 'smsCode': code},
      );
      final data = response.data['data'];
      if (data == null) return response.data['message'] ?? '登录失败';

      await api.saveTokens(data['accessToken'], data['refreshToken']);
      final user = data['user'];
      state = AuthState(
        isLoggedIn: true,
        isLoading: false,
        user: UserInfo(
          id: user['id'] ?? '',
          phone: user['phone'] ?? '',
          role: user['role'] ?? 'User',
          name: user['name'],
          avatarUrl: user['avatarUrl'],
        ),
      );
      return null;
    } catch (e) {
      return '登录失败: $e';
    }
  }

  /// Apple 登录
  Future<String?> appleLogin(String identityToken, String? authorizationCode, String? name) async {
    try {
      final api = ref.read(apiClientProvider);
      final response = await api.post(
        '/api/auth/apple-login',
        data: {
          'identityToken': identityToken,
          if (authorizationCode != null) 'authorizationCode': authorizationCode,
          if (name != null && name.isNotEmpty) 'name': name,
        },
      );
      final data = response.data['data'];
      if (data == null) return response.data['message'] ?? 'Apple 登录失败';

      await api.saveTokens(data['accessToken'], data['refreshToken']);
      final user = data['user'];
      state = AuthState(
        isLoggedIn: true,
        isLoading: false,
        user: UserInfo(
          id: user['id'] ?? '',
          phone: user['phone'] ?? '',
          role: user['role'] ?? 'User',
          name: user['name'],
          avatarUrl: user['avatarUrl'],
        ),
      );
      return null;
    } catch (e) {
      return 'Apple 登录失败: $e';
    }
  }

  /// 登出
  Future<void> logout() async {
    final api = ref.read(apiClientProvider);
    final db = ref.read(localDbProvider);
    final refresh = await db.read('refresh_token');
    if (refresh != null) {
      try {
        await api.post('/api/auth/logout', data: {'refreshToken': refresh});
      } catch (e) {
        log('[Auth] logout: $e');
      }
    }
    await api.clearTokens();
    state = const AuthState(isLoggedIn: false, isLoading: false);
  }
}

/// 便捷：当前用户角色
final userRoleProvider = Provider<String>((ref) {
  return ref.watch(authProvider).user?.role ?? 'User';
});
