import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:record/record.dart';

import '../theme.dart';

/// 聊天底部输入栏：
/// 左侧麦克风/键盘切换、中间输入框（语音模式变成「按住 说话」）、右侧表情和加号。
/// 有文字时加号变成「发送」按钮（微信式交互）。
class ChatInputBar extends StatefulWidget {
  /// 发送文字
  final void Function(String text) onSendText;

  /// 发送语音（本地文件路径 + 秒数）
  final void Function(String path, int duration) onSendVoice;

  /// 从相册选图片发送
  final VoidCallback onPickImage;

  /// 选文件发送
  final VoidCallback onPickFile;

  /// 发起语音通话（群聊为 null，不显示该入口）
  final VoidCallback? onVoiceCall;

  const ChatInputBar({
    super.key,
    required this.onSendText,
    required this.onSendVoice,
    required this.onPickImage,
    required this.onPickFile,
    this.onVoiceCall,
  });

  @override
  State<ChatInputBar> createState() => _ChatInputBarState();
}

class _ChatInputBarState extends State<ChatInputBar> {
  final TextEditingController _ctrl = TextEditingController();
  final FocusNode _focus = FocusNode();
  final AudioRecorder _recorder = AudioRecorder();

  bool _voiceMode = false;
  bool _panelOpen = false;
  bool _recording = false;
  bool _hasText = false;
  String? _recordPath;
  int _recordStart = 0;
  Timer? _recordTimer;

  /// 最长录音 60 秒
  static const int _maxRecordSec = 60;

  /// 常用表情（表情按钮点开的小面板，不加第三方表情包）
  static const List<String> _emojis = [
    '😀', '😄', '😂', '🤣', '😊', '😍', '🤔', '😅',
    '👍', '👌', '🙏', '👏', '💪', '🎉', '❤️', '😢',
  ];

  @override
  void dispose() {
    _recordTimer?.cancel();
    _recorder.dispose();
    _ctrl.dispose();
    _focus.dispose();
    super.dispose();
  }

  void _sendText() {
    final text = _ctrl.text.trim();
    if (text.isEmpty) return;
    widget.onSendText(text);
    _ctrl.clear();
    setState(() => _hasText = false);
  }

  // ---------------- 录音 ----------------

  Future<void> _startRecord() async {
    try {
      if (!await _recorder.hasPermission()) {
        _toast('需要麦克风权限才能发语音');
        return;
      }
      final dir = await getApplicationDocumentsDirectory();
      final path = '${dir.path}/voice/${DateTime.now().millisecondsSinceEpoch}.m4a';
      await File(path).create(recursive: true);
      await _recorder.start(const RecordConfig(), path: path);
      _recordPath = path;
      _recordStart = DateTime.now().millisecondsSinceEpoch;
      setState(() => _recording = true);
      _recordTimer?.cancel();
      _recordTimer = Timer(const Duration(seconds: _maxRecordSec), () => _stopRecord(send: true));
    } catch (_) {
      _toast('录音启动失败，请重试');
    }
  }

  Future<void> _stopRecord({required bool send}) async {
    _recordTimer?.cancel();
    _recordTimer = null;
    if (!await _recorder.isRecording()) {
      if (mounted) setState(() => _recording = false);
      return;
    }
    await _recorder.stop();
    if (mounted) setState(() => _recording = false);
    final path = _recordPath;
    if (!send || path == null) return;
    final duration = (DateTime.now().millisecondsSinceEpoch - _recordStart) ~/ 1000;
    if (duration < 1) {
      _toast('说话时间太短');
      return;
    }
    widget.onSendVoice(path, duration);
  }

  void _toast(String text) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(text), duration: const Duration(seconds: 2)));
  }

  // ---------------- 表情面板 ----------------

  void _showEmojiPanel() {
    _focus.unfocus();
    showModalBottomSheet(
      context: context,
      builder: (ctx) => SafeArea(
        child: GridView.count(
          crossAxisCount: 8,
          shrinkWrap: true,
          padding: const EdgeInsets.all(AppGap.x3),
          children: _emojis
              .map(
                (e) => InkWell(
                  onTap: () {
                    _ctrl.text += e;
                    _ctrl.selection = TextSelection.collapsed(offset: _ctrl.text.length);
                    setState(() => _hasText = true);
                    Navigator.of(ctx).pop();
                  },
                  child: Center(child: Text(e, style: const TextStyle(fontSize: 24))),
                ),
              )
              .toList(),
        ),
      ),
    );
  }

  // ---------------- 界面 ----------------

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          color: AppColors.pageBg,
          padding: const EdgeInsets.symmetric(horizontal: AppGap.x2, vertical: AppGap.x2),
          child: Row(
            children: [
              // 麦克风 / 键盘切换
              _circleButton(
                _voiceMode ? Icons.keyboard_outlined : Icons.mic_none,
                () => setState(() => _voiceMode = !_voiceMode),
              ),
              const SizedBox(width: AppGap.x2),
              Expanded(child: _voiceMode ? _holdToTalk() : _textField()),
              const SizedBox(width: AppGap.x2),
              _circleButton(Icons.sentiment_satisfied_alt, _showEmojiPanel),
              const SizedBox(width: AppGap.x2),
              if (_hasText)
                FilledButton(
                  onPressed: _sendText,
                  style: FilledButton.styleFrom(
                    backgroundColor: AppColors.primary,
                    padding: const EdgeInsets.symmetric(horizontal: AppGap.x4),
                    minimumSize: const Size(0, 40),
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
                  ),
                  child: const Text('发送', style: TextStyle(fontSize: AppFont.sub)),
                )
              else
                _circleButton(Icons.add_circle_outline, () {
                  _focus.unfocus();
                  setState(() => _panelOpen = !_panelOpen);
                }),
            ],
          ),
        ),
        if (_panelOpen) _plusPanel(),
      ],
    );
  }

  Widget _circleButton(IconData icon, VoidCallback onTap) {
    return InkWell(
      onTap: onTap,
      borderRadius: BorderRadius.circular(20),
      child: Padding(
        padding: const EdgeInsets.all(AppGap.x1),
        child: Icon(icon, size: 28, color: AppColors.textPrimary),
      ),
    );
  }

  Widget _textField() {
    return Container(
      constraints: const BoxConstraints(minHeight: 40),
      decoration: BoxDecoration(
        color: AppColors.searchBg,
        borderRadius: BorderRadius.circular(8),
      ),
      child: TextField(
        controller: _ctrl,
        focusNode: _focus,
        textInputAction: TextInputAction.send,
        onSubmitted: (_) => _sendText(),
        onChanged: (v) => setState(() => _hasText = v.trim().isNotEmpty),
        onTap: () => setState(() => _panelOpen = false),
        maxLines: 4,
        minLines: 1,
        decoration: const InputDecoration(
          border: InputBorder.none,
          isDense: true,
          contentPadding: EdgeInsets.symmetric(horizontal: AppGap.x3, vertical: 10),
        ),
      ),
    );
  }

  /// 语音模式下的「按住 说话」按钮
  Widget _holdToTalk() {
    return GestureDetector(
      onLongPressStart: (_) => _startRecord(),
      onLongPressEnd: (_) => _stopRecord(send: true),
      onLongPressCancel: () => _stopRecord(send: false),
      child: Container(
        height: 40,
        alignment: Alignment.center,
        decoration: BoxDecoration(
          color: _recording ? AppColors.primary : AppColors.searchBg,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Text(
          _recording ? '松开 发送' : '按住 说话',
          style: TextStyle(
            fontSize: AppFont.body,
            color: _recording ? Colors.white : AppColors.textPrimary,
          ),
        ),
      ),
    );
  }

  /// 加号面板：图片 / 文件 / 语音通话（单聊）
  Widget _plusPanel() {
    return Container(
      color: AppColors.chatBg,
      padding: const EdgeInsets.all(AppGap.x6),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _panelItem(Icons.image_outlined, '图片', widget.onPickImage),
          _panelItem(Icons.insert_drive_file_outlined, '文件', widget.onPickFile),
          if (widget.onVoiceCall != null) _panelItem(Icons.phone_outlined, '语音通话', widget.onVoiceCall!),
        ],
      ),
    );
  }

  Widget _panelItem(IconData icon, String label, VoidCallback onTap) {
    return Padding(
      padding: const EdgeInsets.only(right: AppGap.x6),
      child: InkWell(
        onTap: () {
          setState(() => _panelOpen = false);
          onTap();
        },
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              width: 56,
              height: 56,
              decoration: BoxDecoration(
                color: AppColors.pageBg,
                borderRadius: BorderRadius.circular(12),
              ),
              child: Icon(icon, size: 28, color: AppColors.textPrimary),
            ),
            const SizedBox(height: AppGap.x1),
            Text(label, style: const TextStyle(fontSize: AppFont.small, color: AppColors.textSecondary)),
          ],
        ),
      ),
    );
  }
}
