import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'auth_provider.dart';

class ConsultationMsg {
  final String id;
  final String senderType; // 'User' | 'Ai' | 'Doctor'
  final String? senderName;
  final String content;
  final DateTime createdAt;
  final List<String>? quickOptions;

  ConsultationMsg({
    required this.id,
    required this.senderType,
    this.senderName,
    required this.content,
    required this.createdAt,
    this.quickOptions,
  });
}

class ConsultationChatState {
  final String? consultationId;
  final String doctorId;
  final String doctorName;
  final String doctorTitle;
  final String doctorDepartment;
  final String status; // AiTalking | WaitingDoctor | DoctorReplied | Closed
  final List<ConsultationMsg> messages;
  final bool isLoading;
  final bool isSending;
  final int quotaRemaining;
  final int quotaTotal;

  const ConsultationChatState({
    this.consultationId,
    this.doctorId = '',
    this.doctorName = '',
    this.doctorTitle = '',
    this.doctorDepartment = '',
    this.status = 'AiTalking',
    this.messages = const [],
    this.isLoading = true,
    this.isSending = false,
    this.quotaRemaining = 3,
    this.quotaTotal = 3,
  });

  ConsultationChatState copyWith({
    String? consultationId,
    String? doctorId,
    String? doctorName,
    String? doctorTitle,
    String? doctorDepartment,
    String? status,
    List<ConsultationMsg>? messages,
    bool? isLoading,
    bool? isSending,
    int? quotaRemaining,
    int? quotaTotal,
  }) =>
      ConsultationChatState(
        consultationId: consultationId ?? this.consultationId,
        doctorId: doctorId ?? this.doctorId,
        doctorName: doctorName ?? this.doctorName,
        doctorTitle: doctorTitle ?? this.doctorTitle,
        doctorDepartment: doctorDepartment ?? this.doctorDepartment,
        status: status ?? this.status,
        messages: messages ?? this.messages,
        isLoading: isLoading ?? this.isLoading,
        isSending: isSending ?? this.isSending,
        quotaRemaining: quotaRemaining ?? this.quotaRemaining,
        quotaTotal: quotaTotal ?? this.quotaTotal,
      );
}

final consultationChatProvider =
    NotifierProvider<ConsultationChatNotifier, ConsultationChatState>(
        ConsultationChatNotifier.new);

class ConsultationChatNotifier extends Notifier<ConsultationChatState> {
  Timer? _pollTimer;

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

  Future<void> init(String doctorId) async {
    state = state.copyWith(doctorId: doctorId, isLoading: true);
    final api = ref.read(apiClientProvider);

    try {
      // 加载医生信息
      await _loadDoctorInfo(doctorId);

      // 加载配额
      final quotaRes = await api.get('/api/user/consultation-quota');
      final quota = quotaRes.data['data'];
      state = state.copyWith(
        quotaRemaining: quota?['remaining'] ?? 3,
        quotaTotal: quota?['total'] ?? 3,
      );

      // 创建问诊会话
      final createRes = await api.post('/api/consultations', data: {'doctorId': doctorId});
      final consultationId = createRes.data['data']?['id']?.toString() ?? '';

      // 加载历史消息
      await _loadMessages(consultationId);

      // 新会话：插入AI开场问候
      if (state.messages.isEmpty) {
        final greeting = ConsultationMsg(
          id: 'greeting_${DateTime.now().millisecondsSinceEpoch}',
          senderType: 'Ai',
          senderName: 'AI分身 · ${state.doctorName}',
          content:
              '您好，我是${state.doctorName}的AI分身。请问您最近有什么身体不适？可以描述一下您的症状，我会先帮您做初步分析。\n\n如果情况需要，我会帮您转接${state.doctorName}医生。',
          createdAt: DateTime.now(),
        );
        state = state.copyWith(
          consultationId: consultationId,
          messages: [greeting],
          isLoading: false,
        );
      } else {
        state = state.copyWith(consultationId: consultationId, isLoading: false);
      }

      _startPolling();
    } catch (_) {
      state = state.copyWith(isLoading: false);
    }
  }

  Future<void> _loadDoctorInfo(String doctorId) async {
    try {
      final api = ref.read(apiClientProvider);
      final res = await api.get('/api/doctors');
      final list = (res.data['data'] as List?) ?? [];
      final doc = list.cast<Map<String, dynamic>>().firstWhere(
          (d) => d['id']?.toString() == doctorId,
          orElse: () => <String, dynamic>{});
      state = state.copyWith(
        doctorName: doc['name']?.toString() ?? '',
        doctorTitle: doc['title']?.toString() ?? '',
        doctorDepartment: doc['department']?.toString() ?? '',
      );
    } catch (_) {}
  }

  Future<void> _loadMessages(String consultationId) async {
    try {
      final api = ref.read(apiClientProvider);
      final res = await api.get('/api/consultations/$consultationId/messages');
      final list = (res.data['data'] as List?) ?? [];
      final msgs = list.map((m) {
        final map = m as Map<String, dynamic>;
        return ConsultationMsg(
          id: map['id']?.toString() ?? '',
          senderType: map['senderType']?.toString() ?? 'User',
          senderName: map['senderName']?.toString(),
          content: map['content']?.toString() ?? '',
          createdAt: DateTime.tryParse(map['createdAt']?.toString() ?? '') ?? DateTime.now(),
        );
      }).toList();
      if (msgs.isNotEmpty) {
        state = state.copyWith(messages: msgs);
      }
    } catch (_) {}
  }

  Future<void> sendMessage(String text) async {
    if (text.trim().isEmpty || state.isSending || state.consultationId == null) return;

    final userMsg = ConsultationMsg(
      id: '${DateTime.now().millisecondsSinceEpoch}',
      senderType: 'User',
      content: text,
      createdAt: DateTime.now(),
    );
    state = state.copyWith(
      messages: [...state.messages, userMsg],
      isSending: true,
    );

    try {
      final api = ref.read(apiClientProvider);
      await api.post('/api/consultations/${state.consultationId}/messages', data: {'content': text});
      state = state.copyWith(isSending: false);
      _pollMessages();
    } catch (_) {
      state = state.copyWith(isSending: false);
    }
  }

  void _startPolling() {
    _pollTimer?.cancel();
    _pollTimer = Timer.periodic(const Duration(seconds: 15), (_) => _pollMessages());
  }

  Future<void> _pollMessages() async {
    if (state.consultationId == null) return;
    try {
      final api = ref.read(apiClientProvider);
      final lastId = state.messages.isNotEmpty ? state.messages.last.id : null;
      final params = <String, dynamic>{};
      if (lastId != null && lastId.startsWith('greeting_') == false) {
        params['after'] = lastId;
      }
      final res = await api.get(
        '/api/consultations/${state.consultationId}/messages',
        queryParameters: params.isNotEmpty ? params : null,
      );
      final list = (res.data['data'] as List?) ?? [];
      if (list.isEmpty) return;

      final existingIds = state.messages.map((m) => m.id).toSet();
      final newMsgs = list
          .map((m) {
            final map = m as Map<String, dynamic>;
            return ConsultationMsg(
              id: map['id']?.toString() ?? '',
              senderType: map['senderType']?.toString() ?? 'User',
              senderName: map['senderName']?.toString(),
              content: map['content']?.toString() ?? '',
              createdAt: DateTime.tryParse(map['createdAt']?.toString() ?? '') ?? DateTime.now(),
            );
          })
          .where((m) => !existingIds.contains(m.id))
          .toList();

      if (newMsgs.isNotEmpty) {
        state = state.copyWith(messages: [...state.messages, ...newMsgs]);
      }
    } catch (_) {}
  }

  void stopPolling() {
    _pollTimer?.cancel();
    _pollTimer = null;
  }
}
