import { useState, useRef, useEffect, useCallback } from 'react';
import Icon from './Icons';
import { API_BASE } from '../config';
import { getMqttStatus } from '../utils/mqtt';

/* =========================================================
   AI 智能助手对话面板 —— 文字 / 语音双模式
   · 文字：后端 /api/ai/chat（阿里云通义千问 + 工具调用）
   · 语音：本地录音 → 后端 /api/ai/asr（阿里云 paraformer）→ 进入对话流
   后端不可用时自动回退本地模拟（离线兜底）
   ========================================================= */

const QUICK_QUESTIONS = [
  '如何申请入驻园区？',
  '园区有哪些政策扶持？',
  '展示入驻企业卡片',
  'AI 赋能服务有哪些？',
  '切换到数字孪生页面',
];

/* 离线兜底回复（后端不可用时） */
const FALLBACK_REPLIES = [
  '园区提供「空间 + 孵化 + 融资 + 政策 + 资源 + AI 赋能 + 综合服务」七位一体服务，在园项目 158 家，累计带动就业 2,186 人，累计营收 2.08 亿元。',
  '入驻流程：提交申请 → 项目评审 → 签订协议 → 安排场地并对接导师服务。在园项目 158 家，累计孵化 208 余家。',
  '园区政策覆盖场地租金减免、创业补贴、税费优惠与高企认定申报辅导（在园高企 32 家）。',
  '园区按成长阶段分三个区域：加速区（A1–A12）、国际区（I1–I7）、成长区（G1–G8），共 39 家入驻企业。',
];
const pick = (arr) => arr[Math.floor(Math.random() * arr.length)];

/* 本地兜底识别题库（ASR 不可用时） */
const VOICE_SAMPLES = QUICK_QUESTIONS;

/* ---------- 消息 ---------- */
let msgId = 0;
const nextId = () => ++msgId;

/** 执行后端返回的工具调用。
    后端已通过 MQTT 广播（发布成功时所有大屏都会收到，本地跳过避免重复）；
    仅当 MQTT 发布失败 / 后端不可达时本地执行，保证当前屏幕也能响应 */
function executeLocalTools(tools, mqttPublished) {
  if (!Array.isArray(tools) || tools.length === 0) return;
  if (mqttPublished !== false) return;
  for (const tool of tools) {
    const type = tool.type;
    const params = tool.params || {};
    if (type === 'navigate' || type === 'control' || type === 'alert' || type === 'show_card') {
      window.dispatchEvent(new CustomEvent('dpm:mqtt-local', { detail: { action: type, params } }));
    }
  }
}

export default function AiChatPanel() {
  const [msgs, setMsgs] = useState(() => [{ id: nextId(), role: 'ai', text: '您好，我是 OPC 园区 AI 智能助手（阿里云通义千问）。\n\n支持文字与语音提问，可以为您解答入驻流程、政策扶持、场地服务、AI 赋能等问题，还可以通过语音或文字让我切换页面、展示企业卡片。' }]);
  const [input, setInput] = useState('');
  const [typing, setTyping] = useState(false);
  const [mode, setMode] = useState('text');
  const [voiceState, setVoiceState] = useState('idle'); // idle | recording | transcribing
  const scrollRef = useRef(null);
  const timerRef = useRef(null);
  const recorderRef = useRef(null);
  const chunksRef = useRef([]);
  const voiceStateRef = useRef(voiceState);

  useEffect(() => { voiceStateRef.current = voiceState; }, [voiceState]);

  useEffect(() => {
    const el = scrollRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [msgs, typing, mode, voiceState]);

  useEffect(() => {
    return () => {
      clearTimeout(timerRef.current);
      if (recorderRef.current && recorderRef.current.state !== 'inactive') {
        try { recorderRef.current.stop(); } catch { /* ignore */ }
      }
    };
  }, []);

  /** 发送消息 → 后端 LLM */
  const send = useCallback(async (raw, viaVoice = false) => {
    const text = String(raw || '').trim();
    if (!text || typing) return;
    setInput('');
    setMsgs((prev) => [...prev, { id: nextId(), role: 'me', text, voice: viaVoice }]);
    setTyping(true);

    let reply = null;
    let tools = [];
    try {
      const res = await fetch(`${API_BASE}/api/ai/chat`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ messages: [{ role: 'user', content: text }] }),
      });
      if (res.ok) {
        const data = await res.json();
        reply = data.reply;
        tools = data.tools || [];
      }
    } catch { /* 后端不可用 */ }

    if (!reply) reply = pick(FALLBACK_REPLIES);
    setTyping(false);
    setMsgs((prev) => [...prev, { id: nextId(), role: 'ai', text: reply }]);
    executeLocalTools(tools);
  }, [typing]);

  const clear = useCallback(() => {
    clearTimeout(timerRef.current);
    setTyping(false);
    setMsgs([{ id: nextId(), role: 'ai', text: '您好，我是 OPC 园区 AI 智能助手。有什么可以帮您？' }]);
  }, []);

  /* ================= 语音对话（录音 → 后端 ASR） ================= */

  const pickMimeType = () => {
    const types = ['audio/mp4', 'audio/webm;codecs=opus', 'audio/ogg;codecs=opus', 'audio/webm'];
    for (const t of types) {
      if (window.MediaRecorder && MediaRecorder.isTypeSupported(t)) return t;
    }
    return '';
  };

  const startRecording = useCallback(() => {
    const mime = pickMimeType();
    if (!window.MediaRecorder || !navigator.mediaDevices?.getUserMedia) {
      // 无录音能力：直接模拟
      setVoiceState('transcribing');
      timerRef.current = setTimeout(() => {
        setVoiceState('idle');
        send(pick(VOICE_SAMPLES), true);
      }, 1200);
      return;
    }
    navigator.mediaDevices.getUserMedia({ audio: true })
      .then((stream) => {
        const rec = new MediaRecorder(stream, mime ? { mimeType: mime } : undefined);
        chunksRef.current = [];
        rec.ondataavailable = (e) => { if (e.data && e.data.size > 0) chunksRef.current.push(e.data); };
        rec.onstop = async () => {
          stream.getTracks().forEach((t) => t.stop());
          setVoiceState('transcribing');
          const blob = new Blob(chunksRef.current, { type: mime || 'audio/webm' });
          try {
            const fmt = (mime || 'webm').split(';')[0].split('/')[1] || 'm4a';
            const form = new FormData();
            form.append('file', blob, `recording.${fmt === 'mp4' ? 'm4a' : fmt}`);
            form.append('format', fmt === 'mp4' ? 'm4a' : fmt);
            const res = await fetch(`${API_BASE}/api/ai/asr`, { method: 'POST', body: form });
            const data = await res.json();
            const text = (data && data.text || '').trim();
            if (text) {
              send(text, true);
            } else {
              setVoiceState('idle');
              setMsgs((prev) => [...prev, { id: nextId(), role: 'ai', text: '抱歉，没有听清您的问题，请再试一次，或改用文字输入。' }]);
            }
          } catch {
            // 后端不可用：回退本地模拟识别
            setVoiceState('transcribing');
            timerRef.current = setTimeout(() => {
              setVoiceState('idle');
              send(pick(VOICE_SAMPLES), true);
            }, 1000);
          }
        };
        rec.onerror = () => {
          stream.getTracks().forEach((t) => t.stop());
          setVoiceState('idle');
          send(pick(VOICE_SAMPLES), true);
        };
        recorderRef.current = rec;
        rec.start();
        setVoiceState('recording');
      })
      .catch(() => {
        // 麦克风权限被拒：模拟
        setVoiceState('transcribing');
        timerRef.current = setTimeout(() => {
          setVoiceState('idle');
          send(pick(VOICE_SAMPLES), true);
        }, 1200);
      });
  }, [send]);

  // MQTT 调度器 → AI 页操作：输入并发送 / 选择预设问题
  useEffect(() => {
    const onAiAction = (e) => {
      const { type, text, index } = e.detail || {};
      if (type === 'input' && text && String(text).trim()) {
        setInput(String(text).trim());
        void send(String(text).trim());
      } else if (type === 'preset') {
        const q = QUICK_QUESTIONS[Number(index)];
        if (q) void send(q);
      }
    };
    window.addEventListener('dpm:ai-action', onAiAction);
    return () => window.removeEventListener('dpm:ai-action', onAiAction);
  }, [send]);

  const toggleVoice = useCallback(() => {
    if (voiceStateRef.current === 'recording') {
      const rec = recorderRef.current;
      if (rec && rec.state === 'recording') {
        rec.stop(); // 触发 onstop → 上传识别
      } else {
        setVoiceState('idle');
      }
    } else if (voiceStateRef.current === 'idle') {
      startRecording();
    }
  }, [startRecording]);

  const switchMode = useCallback((m) => {
    setMode(m);
    if (voiceStateRef.current === 'recording') {
      try { recorderRef.current && recorderRef.current.stop(); } catch { /* ignore */ }
      setVoiceState('idle');
    }
  }, []);

  const voiceHint = {
    idle: '点击麦克风，说出你的问题',
    recording: '正在聆听… 再次点击结束',
    transcribing: '正在识别语音…',
  }[voiceState];

  return (
    <section className="bd-chat">
      {/* 头部 */}
      <div className="bd-chat-head">
        <span className="bd-chat-logo"><Icon name="robot" size={17} /></span>
        <div className="bd-chat-titles">
          <b>AI 智能助手</b>
          <span>阿里云通义千问 · 语音识别</span>
        </div>
        <div className="bd-chat-modes">
          <button className={mode === 'text' ? 'active' : ''} onClick={() => switchMode('text')} title="文字对话">
            <Icon name="message-circle" size={13} />文字
          </button>
          <button className={mode === 'voice' ? 'active' : ''} onClick={() => switchMode('voice')} title="语音对话">
            <Icon name="microphone" size={13} />语音
          </button>
        </div>
        <span className="bd-chat-model"><i />通义千问</span>
        <button className="bd-chat-clear" title="清空对话" onClick={clear}>
          <Icon name="eraser" size={15} />
        </button>
      </div>

      {/* 消息区 */}
      <div className="bd-chat-msgs" ref={scrollRef}>
        {msgs.map((m) => (
          <div className={`bd-msg ${m.role}`} key={m.id}>
            {m.role === 'ai' && <span className="bd-msg-avatar"><Icon name="robot" size={13} /></span>}
            <div className="bd-msg-bubble">
              {m.voice && <span className="bd-msg-voice-tag"><Icon name="microphone" size={10} />语音</span>}
              {m.text}
            </div>
          </div>
        ))}
        {typing && (
          <div className="bd-msg ai">
            <span className="bd-msg-avatar"><Icon name="robot" size={13} /></span>
            <div className="bd-msg-bubble bd-typing"><i /><i /><i /></div>
          </div>
        )}
      </div>

      {/* 文字模式 */}
      {mode === 'text' && (
        <>
          <div className="bd-chat-quick">
            {QUICK_QUESTIONS.map((q) => (
              <button key={q} onClick={() => send(q)}>
                <Icon name="sparkles" size={12} />
                {q}
              </button>
            ))}
          </div>
          <div className="bd-chat-input">
            <input
              value={input}
              placeholder="输入你的问题，如：展示入驻企业卡片"
              onChange={(e) => setInput(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === 'Enter' && !e.nativeEvent.isComposing) {
                  e.preventDefault();
                  send(input);
                }
              }}
            />
            <button className="bd-chat-send" disabled={!input.trim() || typing} onClick={() => send(input)} title="发送">
              <Icon name="send" size={16} />
            </button>
          </div>
        </>
      )}

      {/* 语音模式 */}
      {mode === 'voice' && (
        <div className="bd-chat-voice">
          <div className={`bd-chat-voice-hint ${voiceState}`}>
            {voiceState === 'recording' && <span className="bd-voice-wave"><i /><i /><i /><i /><i /></span>}
            {voiceHint}
          </div>
          <button
            className={`bd-chat-mic ${voiceState}`}
            onClick={toggleVoice}
            title={voiceState === 'recording' ? '结束并发送' : '开始语音提问'}
          >
            {voiceState === 'recording' && <span className="bd-mic-ring r1" />}
            {voiceState === 'recording' && <span className="bd-mic-ring r2" />}
            <Icon
              name={voiceState === 'recording' ? 'microphone-filled' : 'microphone'}
              size={30}
            />
          </button>
          <div className="bd-chat-voice-tip">
            {voiceState === 'recording' ? '再次点击结束并识别' : '点击开始说话 · 阿里云语音识别'}
          </div>
        </div>
      )}
    </section>
  );
}
