import 'dart:async';

import 'package:ai_chat_assistant/ai_chat_assistant.dart';
import 'package:ai_chat_assistant/utils/common_util.dart';
import 'package:ai_chat_assistant/utils/tts_util.dart';
import 'package:t_basic_intl/intl.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:uuid/uuid.dart';
import '../services/chat_sse_service.dart';
import '../services/classification_service.dart';
import '../services/control_recognition_service.dart';
// import '../services/audio_recorder_service.dart';
// import '../services/voice_recognition_service.dart';
import 'command_service.dart';
import 'package:fluttertoast/fluttertoast.dart';

// 用单例的模式创建
class MessageService extends ChangeNotifier {
  static const MethodChannel _asrChannel = MethodChannel('com.example.ai_chat_assistant/ali_sdk');

  static MessageService? _instance;

  static MessageService get instance {
    return _instance ??= MessageService._internal();
  }

  // 提供工厂构造函数供 Provider 使用
  factory MessageService() => instance;

  Completer<String>? _asrCompleter;

  MessageService._internal() {
    // 注册MethodChannel的handler
    _asrChannel.setMethodCallHandler(_handleMethodCall);
  }

  @override
  void dispose() {
    // 取消注册MethodChannel的handler，避免内存泄漏和意外回调
    _asrChannel.setMethodCallHandler(null);
    _asrCompleter?.completeError('Disposed');
    _asrCompleter = null;
    super.dispose();
  }

  // 提供真正的销毁方法（可选，用于应用退出时）
  void destroyInstance() {
    _asrChannel.setMethodCallHandler(null);
    _asrCompleter?.completeError('Destroyed');
    _asrCompleter = null;
    super.dispose();
    _instance = null;
  }

  Future<dynamic> _handleMethodCall(MethodCall call) async {
    switch (call.method) {
      case "onAsrResult":
        replaceMessage(
            id: _latestUserMessageId!, text: call.arguments, status: MessageStatus.normal);
        break;
      case "onAsrStop":
        int index = findMessageIndexById(_latestUserMessageId!);
        if (index == -1) {
          return;
        }
        final message = _messages[index];
        if (message.text.isEmpty) {
          removeMessageById(_latestUserMessageId!);
          return;
        }
        if (_asrCompleter != null && !_asrCompleter!.isCompleted) {
          _asrCompleter!.complete(messages.last.text);
        }
        break;
    }
  }

  final ChatSseService _chatSseService = ChatSseService();
  // final LocalTtsService _ttsService = LocalTtsService();
  // final AudioRecorderService _audioService = AudioRecorderService();
  // final VoiceRecognitionService _recognitionService = VoiceRecognitionService();
  final TextClassificationService _classificationService = TextClassificationService();
  final VehicleCommandService _vehicleCommandService = VehicleCommandService();

  final List<ChatMessage> _messages = [];

  List<ChatMessage> get messages => List.unmodifiable(_messages);

  String? _latestUserMessageId;
  String? _latestAssistantMessageId;

  MessageServiceState _state = MessageServiceState.idle;

  bool get isRecording => _state == MessageServiceState.recording;

  bool get isRecognizing => _state == MessageServiceState.recognizing;

  bool get isReplying => _state == MessageServiceState.replying;

  bool get isBusy => _state != MessageServiceState.idle;

  bool _isReplyAborted = true;

  void initializeEmpty() {
    _messages.clear();
    notifyListeners();
  }

  Future<void> startVoiceInput() async {
    if (await Permission.microphone.status == PermissionStatus.denied) {
      PermissionStatus status = await Permission.microphone.request();
      if (status == PermissionStatus.permanentlyDenied) {
        await Fluttertoast.showToast(
            msg: Intl.getCurrentLocale().startsWith('zh')
                ? "请在设置中开启麦克风权限"
                : "Please enable microphone in the settings");
      }
      return;
    }
    if (_state != MessageServiceState.idle) {
      return;
    }
    try {
      abortReply();
      _latestUserMessageId = null;
      _latestAssistantMessageId = null;
      changeState(MessageServiceState.recording);
      _latestUserMessageId = addMessage("", true, MessageStatus.listening);
      _asrChannel.invokeMethod("startAsr");
    } catch (e) {
      print('录音开始出错: $e');
    }
  }

  void changeState(MessageServiceState state) {
    _state = state;
    notifyListeners();
  }

  String addMessage(String text, bool isUser, MessageStatus status) {
    String uuid = Uuid().v1();
    _messages.add(ChatMessage(
        id: uuid, text: text, isUser: isUser, timestamp: DateTime.now(), status: status));
    notifyListeners();
    return uuid;
  }

  Future<void> stopAndProcessVoiceInput() async {
    if (_state != MessageServiceState.recording) {
      changeState(MessageServiceState.idle);
      return;
    }
    try {
      _isReplyAborted = false;
      changeState(MessageServiceState.recognizing);
      _asrChannel.invokeMethod("stopAsr");
      _asrCompleter = Completer<String>();
      final recognizedText = await _asrCompleter!.future;
      // final audioData = await _audioService.stopRecording();
      // replaceMessage(
      //     id: _latestUserMessageId!,
      //     text: "",
      //     status: MessageStatus.recognizing);
      // if (audioData == null || audioData.isEmpty) {
      //   removeMessageById(_latestUserMessageId!);
      //   return;
      // }
      // final recognizedText =
      //     await _recognitionService.recognizeSpeech(audioData);
      // if (recognizedText == null || recognizedText.isEmpty) {
      //   removeMessageById(_latestUserMessageId!);
      //   return;
      // }
      // replaceMessage(
      //     id: _latestUserMessageId!,
      //     text: recognizedText,
      //     status: MessageStatus.normal);
      changeState(MessageServiceState.replying);
      await reply(recognizedText);
    } catch (e) {
      print(e);
    } finally {
      changeState(MessageServiceState.idle);
      _asrCompleter = null;
    }
  }

  int findMessageIndexById(String? id) {
    return id == null ? -1 : _messages.indexWhere((msg) => msg.id == id);
  }

  void replaceMessage({
    required String id,
    String? text,
    MessageStatus? status,
  }) {
    final index = findMessageIndexById(id);
    if (index == -1) {
      return;
    }
    final message = _messages[index];
    _messages[index] = ChatMessage(
      id: message.id,
      text: text ?? message.text,
      isUser: message.isUser,
      timestamp: message.timestamp,
      status: status ?? message.status,
    );
    notifyListeners();
  }

  Future<void> reply(String text) async {
    _latestAssistantMessageId = addMessage("", false, MessageStatus.thinking);
    bool isChinese = CommonUtil.containChinese(text);
    try {
      if (_isReplyAborted) {
        return;
      }
      final category = await _classificationService.classifyText(text);
      switch (category) {
        case -1:
          await occurError(isChinese);
          break;
        case 2:
          await handleVehicleControl(text, isChinese);
          break;
        case 4:
          await answerWrongQuestion(isChinese);
          break;
        default:
          await answerQuestion(text, isChinese);
          break;
      }
    } catch (e) {
      await occurError(isChinese);
    }
  }

  Future<void> handleVehicleControl(String text, bool isChinese) async {
    if (_isReplyAborted) {
      return;
    }
    final vehicleCommandResponse = await _vehicleCommandService.getCommandFromText(text);
    if (vehicleCommandResponse == null) {
      if (_isReplyAborted) {
        return;
      }
      String msg = isChinese
          ? "无法识别车辆控制命令，请重试"
          : "Cannot recognize the vehicle control command, please try again";
      replaceMessage(id: _latestAssistantMessageId!, text: msg, status: MessageStatus.normal);
    } else {
      if (_isReplyAborted) {
        return;
      }
      replaceMessage(
          id: _latestAssistantMessageId!,
          text: vehicleCommandResponse.tips!,
          status: MessageStatus.executing);
      if (!_isReplyAborted) {
        if (await TtsUtil.start(isChinese) == true) {
          TtsUtil.send(vehicleCommandResponse.tips!);
          Future.delayed(const Duration(milliseconds: 300), () => TtsUtil.complete());
        }
      }
      bool containOpenAC = false;
      List<String> successCommandList = [];
      for (var command in vehicleCommandResponse.commands) {
        if (_isReplyAborted) {
          return;
        }
        if (command.type == VehicleCommandType.unknown || command.error.isNotEmpty) {
          continue;
        }
        if (command.type == VehicleCommandType.openAC) {
          containOpenAC = true;
        }
        bool isSuccess;
        if (containOpenAC && command.type == VehicleCommandType.changeACTemp) {
          isSuccess = await Future.delayed(
              const Duration(milliseconds: 2000), () => processCommand(command, isChinese));
        } else {
          isSuccess = await processCommand(command, isChinese);
        }
        if (isSuccess) {
          successCommandList.add(isChinese ? command.type.chinese : command.type.english);
        }
      }
      replaceMessage(
          id: _latestAssistantMessageId!,
          text: vehicleCommandResponse.tips!,
          status: MessageStatus.normal);
      notifyListeners();
      if (_isReplyAborted || successCommandList.isEmpty) {
        return;
      }
      String controlResponse = await _vehicleCommandService.getControlResponse(successCommandList);
      if (_isReplyAborted || controlResponse.isEmpty) {
        return;
      }
      addMessage(controlResponse, false, MessageStatus.normal);
    }
  }

  Future<bool> processCommand(VehicleCommand command, bool isChinese) async {
    String msg = "";
    MessageStatus status = MessageStatus.normal;
    var commandObjc = VehicleCommand(type: command.type, params: command.params);
    var client = AIChatAssistantManager.instance.commandClient;
    if (client == null) {
      msg = isChinese ? "车辆控制服务未初始化" : "Vehicle control service is not initialized";
      status = MessageStatus.failure;
      addMessage(msg, false, status);
      return false;
    }
    final (isSuccess, result) = await client.executeCommand(commandObjc);
    if (command.type == VehicleCommandType.locateCar) {
      msg = isChinese ? "很抱歉，定位车辆位置失败" : "Sorry, locate the vehicle unsuccessfully";
      status = MessageStatus.failure;
      if (isSuccess && result != null && result.isNotEmpty) {
        String address = result['address'];
        if (address.isNotEmpty) {
          msg = isChinese ? "已为您找到车辆位置：\"$address\"" : "The vehicle location is \"$address\"";
          status = MessageStatus.success;
        }
      }
    } else {
      if (!isSuccess) {
        msg = isChinese
            ? "很抱歉，\"${command.type.chinese}\"失败"
            : "Sorry, execute \"${command.type.english}\" unsuccessfully";
        status = MessageStatus.failure;
      }
    }
    if (msg.isNotEmpty) {
      addMessage(msg, false, status);
    }
    return isSuccess;
  }

  Future<void> answerWrongQuestion(bool isChinese) async {
    if (_isReplyAborted) {
      return;
    }
    const chineseAnswer = "尊敬的ID.UNYX车主：\n" +
        "很抱歉，我暂时无法理解您的需求，请您更详细地描述，以便我能更好地为您服务。\n" +
        "作为您的智能助手，我专注于以下服务：\n" +
        "1. ID.UNYX车型功能咨询，例如：如何调节座椅记忆功能？\n" +
        "2. 日常用车问题解答，例如：充电注意事项有哪些？\n" +
        "3. 基础车辆控制协助，例如：帮我打开空调。";
    const englishAnswer = "Dear ID.UNYX Owner,\n" +
        "I'm sorry that unable to understand your request currently. Please describe it in more detail so that I can better assist you.\n" +
        "As your intelligent assistant, I specialize in the following services:\n" +
        "1. ID.UNYX model feature consultation, such as: How do I adjust the seat memory function?\n" +
        "2. Daily vehicle usage inquiries, such as: What are the charging precautions?\n" +
        "3. Basic vehicle control assistance, such as: Help me turn on the air conditioning.";
    replaceMessage(
        id: _latestAssistantMessageId!,
        text: isChinese ? chineseAnswer : englishAnswer,
        status: MessageStatus.normal);
  }

  Future<void> answerQuestion(String text, isChinese) async {
    if (_isReplyAborted) {
      return;
    }
    _chatSseService.request(
      messageId: _latestAssistantMessageId!,
      text: text,
      isChinese: isChinese,
      onStreamResponse: handleStreamResponse,
    );
  }

  Future<void> occurError(bool isChinese) async {
    if (_isReplyAborted) {
      return;
    }
    replaceMessage(
        id: _latestAssistantMessageId!,
        text: isChinese
            ? "很抱歉，众众暂时无法回答这个问题，请重试"
            : "Sorry, I can not answer this question for the moment, please try again",
        status: MessageStatus.normal);
  }

  void handleStreamResponse(String messageId, String responseText, bool isComplete) {
    if (_isReplyAborted) {
      return;
    }
    try {
      if (isComplete) {
        replaceMessage(
          id: messageId,
          text: responseText,
          status: MessageStatus.completed,
        );
      } else {
        replaceMessage(id: messageId, text: responseText, status: MessageStatus.thinking);
      }
    } catch (e) {
      abortReply();
    }
  }

  Future<void> abortReply() async {
    _isReplyAborted = true;
    _chatSseService.abort();
    int index = findMessageIndexById(_latestAssistantMessageId);
    if (index == -1 || messages[index].status != MessageStatus.thinking) {
      return;
    }
    replaceMessage(id: _latestAssistantMessageId!, status: MessageStatus.aborted);
  }

  void removeMessageById(String id) {
    _messages.removeWhere((msg) => msg.id == id);
    notifyListeners();
  }

  void clearMessages() {
    _messages.clear();
    notifyListeners();
  }

  void removeNonListeningMessages() {
    _messages.removeWhere((message) => message.status != MessageStatus.listening);
    notifyListeners();
  }
}
