import 'dart:async';
import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter_pcm_sound/flutter_pcm_sound.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

import '../../config/minimax_config.dart';
import '../../models/character_model.dart';
import 'tts_engine.dart';
import 'ws_client.dart';

/// MiniMax TTS 引擎 (PCM 流式版本 - 带预连接优化)
/// 
/// 优化特性：
/// - 预连接：提前建立 WebSocket 连接
/// - 连接复用：一个连接处理多次 TTS 请求
/// - 自动重连：连接断开后自动重连
class MiniMaxTtsEngine implements TtsEngine {
  WebSocketChannel? _channel;
  StreamSubscription? _wsSub;
  Timer? _timeoutTimer;
  Timer? _keepAliveTimer;

  bool _isInitialized = false;
  bool _isDisposed = false;
  bool _isCancelled = false;
  bool _isPlaying = false;

  // 连接状态
  bool _isConnected = false;
  bool _isTaskReady = false;  // task_started 状态
  Completer<void>? _connectCompleter;
  Completer<void>? _speakCompleter;

  // 当前任务的文本
  String? _pendingText;

  VoidCallback? _onStart;
  VoidCallback? _onComplete;
  Function(dynamic)? _onError;

  // 统计信息
  int _chunkCount = 0;
  int _totalBytes = 0;
  final Stopwatch _stopwatch = Stopwatch();

  // 跟踪播放完成
  bool _isFinalReceived = false;

  @override
  Future<void> init() async {
    if (_isInitialized) return;
    
    // 初始化 PCM 播放器
    await FlutterPcmSound.setup(
      sampleRate: MinimaxConfig.sampleRate,
      channelCount: MinimaxConfig.channels,
    );
    
    FlutterPcmSound.setLogLevel(LogLevel.none);
    FlutterPcmSound.setFeedCallback(_onFeedCallback);
    
    _isInitialized = true;
    debugPrint('✅ MiniMaxTtsEngine initialized (PCM streaming mode)');
  }

  /// 预连接 WebSocket
  /// 在语音页面打开时调用，提前建立连接
  @override
  Future<void> preconnect() async {
    if (!_isInitialized) await init();
    if (_isConnected && _isTaskReady) {
      debugPrint('⚡ TTS 连接已就绪，无需重连');
      return;
    }
    
    debugPrint('🔌 TTS 预连接中...');
    await _ensureConnection();
    debugPrint('⚡ TTS 预连接完成，已就绪');
  }

  /// 确保 WebSocket 连接已建立且处于就绪状态
  Future<void> _ensureConnection() async {
    if (_isConnected && _isTaskReady) return;
    
    // 清理旧连接
    await _cleanupConnection();
    
    _connectCompleter = Completer<void>();
    
    try {
      final channel = connectTtsSocket(
        Uri.parse(MinimaxConfig.wsUrl),
        {
          'Authorization': 'Bearer ${MinimaxConfig.apiKey}',
        },
      );
      _channel = channel;
      
      // 监听消息
      _wsSub = channel.stream.listen(
        _handleConnectionMessage,
        onError: (error) {
          debugPrint('❌ TTS WebSocket 错误: $error');
          _handleDisconnect();
        },
        onDone: () {
          debugPrint('⚠️ TTS WebSocket 连接关闭');
          _handleDisconnect();
        },
        cancelOnError: false,
      );
      
      // 等待连接就绪（connected_success + task_started）
      // 设置超时
      _timeoutTimer?.cancel();
      _timeoutTimer = Timer(const Duration(seconds: 10), () {
        if (_connectCompleter != null && !_connectCompleter!.isCompleted) {
          _connectCompleter!.completeError('连接超时');
          _handleDisconnect();
        }
      });
      
      await _connectCompleter!.future;
      _timeoutTimer?.cancel();
      
      // 启动保活
      _startKeepAlive();
      
    } catch (e) {
      debugPrint('❌ TTS 连接失败: $e');
      _handleDisconnect();
      rethrow;
    }
  }

  void _handleConnectionMessage(dynamic message) {
    if (_isDisposed) return;
    
    try {
      final Map<String, dynamic> data = jsonDecode(message as String);
      final String? event = data['event'] as String?;
      
      if (event == 'connected_success') {
        debugPrint('📥 TTS connected_success');
        _isConnected = true;
        // 发送 task_start 进入就绪状态
        _sendTaskStart();
        return;
      }
      
      if (event == 'task_started') {
        debugPrint('📥 TTS task_started (就绪)');
        _isTaskReady = true;
        
        // 如果是预连接，完成连接
        if (_connectCompleter != null && !_connectCompleter!.isCompleted) {
          _connectCompleter!.complete();
        }
        
        // 如果有待发送的文本，立即发送
        if (_pendingText != null) {
          _sendText(_pendingText!);
          _pendingText = null;
        }
        return;
      }
      
      if (event == 'task_continued') {
        // 正常的流式响应
      }
      
      if (event == 'task_failed') {
        final errorInfo = data['base_resp'] ?? data;
        debugPrint('❌ TTS task_failed: ${jsonEncode(errorInfo)}');
        _handleTaskError('task_failed: ${jsonEncode(errorInfo)}');
        return;
      }
      
      // 处理音频数据
      if (data['data'] != null && data['data'] is Map<String, dynamic>) {
        final audioData = data['data'] as Map<String, dynamic>;
        final audioHex = audioData['audio'];
        
        if (audioHex is String && audioHex.isNotEmpty) {
          final bytes = _hexToBytes(audioHex);
          _chunkCount++;
          _totalBytes += bytes.length;
          
          _feedAudioData(bytes);
          
          if (_chunkCount % 20 == 0) {
            debugPrint('📥 已接收 $_chunkCount 块 ($_totalBytes bytes)');
          }
        }
      }
      
      // 任务完成
      if (data['is_final'] == true) {
        _handleTaskComplete();
      }
      
    } catch (e) {
      debugPrint('❌ TTS 消息解析错误: $e');
    }
  }

  void _sendTaskStart() {
    if (_channel == null) return;
    
    final payload = {
      'event': 'task_start',
      'model': MinimaxConfig.model,
      'voice_setting': {
        'voice_id': MinimaxConfig.defaultVoiceId,
        'speed': 1,
        'vol': 1,
        'pitch': 0,
        'english_normalization': false,
      },
      'audio_setting': {
        'sample_rate': MinimaxConfig.sampleRate,
        'format': MinimaxConfig.format,
        'channel': MinimaxConfig.channels,
      },
    };
    
    _channel!.sink.add(jsonEncode(payload));
  }

  void _sendText(String text) {
    if (_channel == null || !_isTaskReady) return;
    
    debugPrint('📤 发送文本: "$text"');
    _channel!.sink.add(jsonEncode({
      'event': 'task_continue',
      'text': text,
    }));
    _isPlaying = true;
  }

  void _handleTaskComplete() {
    _stopwatch.stop();
    _isFinalReceived = true;
    _isTaskReady = false;
    
    debugPrint('');
    debugPrint('═══════════════════════════════════════');
    debugPrint('📊 TTS 完成: $_chunkCount 块, $_totalBytes bytes, ${_stopwatch.elapsedMilliseconds}ms');
    debugPrint('═══════════════════════════════════════');
    
    // 发送 task_finish
    _channel?.sink.add(jsonEncode({'event': 'task_finish'}));
    
    // 完成当前任务
    if (_speakCompleter != null && !_speakCompleter!.isCompleted) {
      _speakCompleter!.complete();
    }
    
    // 准备下一次任务：重新发送 task_start
    Future.delayed(const Duration(milliseconds: 100), () {
      if (_isConnected && !_isDisposed && !_isCancelled) {
        _sendTaskStart();
      }
    });
  }

  void _handleTaskError(String error) {
    _isTaskReady = false;
    
    if (_speakCompleter != null && !_speakCompleter!.isCompleted) {
      _speakCompleter!.completeError(TtsEngineException(error));
    }
    
    if (_onError != null) _onError!(error);
    
    // 尝试重新进入就绪状态
    Future.delayed(const Duration(milliseconds: 500), () {
      if (_isConnected && !_isDisposed) {
        _sendTaskStart();
      }
    });
  }

  void _handleDisconnect() {
    final wasConnected = _isConnected;
    _isConnected = false;
    _isTaskReady = false;
    _keepAliveTimer?.cancel();
    
    if (_connectCompleter != null && !_connectCompleter!.isCompleted) {
      _connectCompleter!.completeError('连接断开');
    }
    
    if (_speakCompleter != null && !_speakCompleter!.isCompleted) {
      _speakCompleter!.completeError(const TtsEngineException('连接断开'));
    }
    
    // 如果之前是连接状态，静默自动重连（为下次 TTS 做准备）
    if (wasConnected && !_isDisposed && !_isCancelled) {
      Future.delayed(const Duration(milliseconds: 500), () {
        if (!_isDisposed && !_isCancelled) {
          debugPrint('🔄 TTS 自动重连...');
          _ensureConnection().then((_) {
            debugPrint('⚡ TTS 重连成功');
          }).catchError((e) {
            debugPrint('⚠️ TTS 重连失败: $e (下次 speak 时会重试)');
          });
        }
      });
    }
  }

  void _startKeepAlive() {
    _keepAliveTimer?.cancel();
    // 每 30 秒检查连接状态
    _keepAliveTimer = Timer.periodic(const Duration(seconds: 30), (_) {
      if (!_isConnected && !_isDisposed) {
        debugPrint('🔄 TTS 重连中...');
        _ensureConnection().catchError((e) {
          debugPrint('❌ TTS 重连失败: $e');
        });
      }
    });
  }

  void _onFeedCallback(int remainingFrames) {
    if (_isFinalReceived && remainingFrames == 0 && _isPlaying) {
      _isPlaying = false;
      debugPrint('🔊 PCM 播放完成');
      if (_onComplete != null) {
        _onComplete!();
      }
    }
  }

  @override
  Future<void> speak(
    String text, {
    AiVoiceConfig? voiceConfig,
  }) async {
    if (!_isInitialized) await init();
    if (_isDisposed) return;

    final trimmed = text.trim();
    if (trimmed.isEmpty) return;

    if (!MinimaxConfig.isEnabled) {
      throw const TtsEngineException('MiniMax API key is missing');
    }

    // 重置状态
    _isCancelled = false;
    _isFinalReceived = false;
    _chunkCount = 0;
    _totalBytes = 0;
    _stopwatch.reset();
    _stopwatch.start();

    debugPrint('');
    debugPrint('═══════════════════════════════════════');
    debugPrint('🎤 TTS: "$trimmed"');
    debugPrint('═══════════════════════════════════════');

    _speakCompleter = Completer<void>();

    try {
      // 确保连接已就绪
      if (!_isConnected || !_isTaskReady) {
        debugPrint('⏳ 等待连接就绪...');
        await _ensureConnection();
      }
      
      // 发送文本
      if (_isTaskReady) {
        _sendText(trimmed);
        if (_onStart != null) _onStart!();
      } else {
        // 连接还在建立中，设置待发送文本
        _pendingText = trimmed;
        if (_onStart != null) _onStart!();
      }

      // 设置超时
      _timeoutTimer?.cancel();
      _timeoutTimer = Timer(const Duration(seconds: 30), () {
        if (_speakCompleter != null && !_speakCompleter!.isCompleted) {
          _handleTaskError('TTS 超时');
        }
      });

      // 等待任务完成
      await _speakCompleter!.future;
      _timeoutTimer?.cancel();

    } catch (e) {
      debugPrint('❌ TTS 异常: $e');
      if (_onError != null) _onError!(e);
      rethrow;
    }
  }

  void _feedAudioData(Uint8List pcmBytes) {
    if (_isCancelled || _isDisposed) return;
    
    final int16List = <int>[];
    for (var i = 0; i < pcmBytes.length - 1; i += 2) {
      final int16Value = (pcmBytes[i + 1] << 8) | pcmBytes[i];
      final signed = int16Value >= 32768 ? int16Value - 65536 : int16Value;
      int16List.add(signed);
    }
    
    FlutterPcmSound.feed(PcmArrayInt16.fromList(int16List));
  }

  Uint8List _hexToBytes(String hex) {
    final cleaned = hex.trim();
    final len = cleaned.length;
    if (len == 0) return Uint8List(0);
    if (len % 2 != 0) {
      throw const FormatException('Invalid hex string length');
    }

    final bytes = Uint8List(len ~/ 2);
    for (var i = 0; i < len; i += 2) {
      bytes[i ~/ 2] = int.parse(cleaned.substring(i, i + 2), radix: 16);
    }
    return bytes;
  }

  Future<void> _cleanupConnection() async {
    _wsSub?.cancel();
    _wsSub = null;
    _channel?.sink.close();
    _channel = null;
    _isConnected = false;
    _isTaskReady = false;
  }

  @override
  Future<void> stop() async {
    if (_isDisposed) return;
    _isCancelled = true;
    _isPlaying = false;
    _isFinalReceived = false;
    _pendingText = null;
    _timeoutTimer?.cancel();
    
    // 停止 PCM 播放器
    await FlutterPcmSound.release();
    
    // 重新设置播放器
    if (_isInitialized) {
      await FlutterPcmSound.setup(
        sampleRate: MinimaxConfig.sampleRate,
        channelCount: MinimaxConfig.channels,
      );
      FlutterPcmSound.setFeedCallback(_onFeedCallback);
    }
    
    // 注意：不断开 WebSocket 连接，保持复用
    // 如果有进行中的任务，发送 task_finish
    if (_isTaskReady && _channel != null) {
      _channel!.sink.add(jsonEncode({'event': 'task_finish'}));
      _isTaskReady = false;
      // 准备下一次任务
      Future.delayed(const Duration(milliseconds: 100), () {
        if (_isConnected && !_isDisposed) {
          _sendTaskStart();
        }
      });
    }
    
    debugPrint('🛑 TTS 已停止');
  }

  @override
  void setCompletionHandler(VoidCallback handler) {
    _onComplete = handler;
  }

  @override
  void setErrorHandler(Function(dynamic) handler) {
    _onError = handler;
  }

  @override
  void setStartHandler(VoidCallback handler) {
    _onStart = handler;
  }

  @override
  void dispose() {
    _isDisposed = true;
    _keepAliveTimer?.cancel();
    _timeoutTimer?.cancel();
    _cleanupConnection();
    FlutterPcmSound.release();
    debugPrint('🗑️ MiniMaxTtsEngine disposed');
  }
}
