import React, { useState, useEffect, useRef } from 'react';
import { useTool } from '../context/ToolContext';
import DevChatInput from '../tools/dev_chatbot/ChatInput.jsx';
import { marked } from 'marked';
marked.setOptions({ mangle:false, headerIds:false });
import { fetchOpenAIChat, fetchOpenAIImage, classifyRequest } from '../services/openaiService';
import { useAuth } from '../context/AuthContext';
import { API_BASE_URL } from '../config';

// === Chat History Panel 컴포넌트 추가 ===
function ChatHistoryPanel({ toolId }) {
  const [open, setOpen] = React.useState(false);
  const [messages, setMessages] = React.useState([]);

  // 패널이 열릴 때마다 로컬스토리지에서 메시지 불러오기
  React.useEffect(() => {
    if (!open) return;
    try {
      const saved = JSON.parse(localStorage.getItem(`messages_${toolId}`) || '[]');
      setMessages(Array.isArray(saved) ? saved : []);
    } catch {
      setMessages([]);
    }
  }, [toolId, open]);

  return (
    <>
      <button className="chat-history-toggle" onClick={() => setOpen(!open)} aria-label="대화 히스토리 토글">
        <span></span>
        <span></span>
        <span></span>
      </button>
      <div className={`chat-history-panel ${open ? 'show' : ''}`}>
        <div style={{ padding: '12px', fontWeight: 'bold', borderBottom: '1px solid #ffe8d5' }}>대화 히스토리</div>
        <ul className="chat-history-list">
          {messages.length === 0 && (
            <li style={{ padding: '12px', color: '#999' }}>대화 기록이 없습니다.</li>
          )}
          {messages.map((m, idx) => (
            <li key={idx} className="history-item">
              <div className="history-content">{String(m.content).slice(0, 36)}{String(m.content).length > 36 ? '…' : ''}</div>
              <div className="history-time">{m.time}</div>
            </li>
          ))}
        </ul>
      </div>
    </>
  );
}

function FileSidebar() {
  const [files, setFiles] = useState([]);

  const loadFiles = async () => {
    try {
      const res = await fetch(`${API_BASE_URL}/files`);
      const data = await res.json();
      setFiles(data.files || []);
    } catch (_) {}
  };

  useEffect(() => {
    loadFiles();
  }, []);

  const handleDelete = async (fname) => {
    if (!window.confirm(`${fname} 파일을 삭제하시겠습니까?`)) return;
    await fetch(`${API_BASE_URL}/file?filename=${encodeURIComponent(fname)}`, { method: 'DELETE' });
    loadFiles();
  };

  const handleUpload = async (e) => {
    const files = Array.from(e.target.files || []);
    if (!files.length) return;
    const formData = new FormData();
    files.forEach((f) => formData.append('files', f));
    await fetch(`${API_BASE_URL}/upload_pdf`, { method: 'POST', body: formData });
    loadFiles();
  };

  return (
    <div className="file-sidebar">
      <div className="file-sidebar-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <span>파일 리스트</span>
        <button className="file-add-btn" onClick={() => document.getElementById('dev-file-input').click()}>+</button>
        <input id="dev-file-input" type="file" multiple style={{ display: 'none' }} onChange={handleUpload} />
      </div>
      <ul className="file-list">
        {files.map((f) => (
          <li key={f} title={f} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f}</span>
            <button className="file-del-btn" onClick={() => handleDelete(f)}>
              ✕
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default function ChatPage() {
  const { selectedTool } = useTool();
  const { user } = useAuth();
  const [messages, setMessages] = useState(() => {
    try {
      const toolIdInitial = selectedTool?.id || 'chatgpt';
      const saved = JSON.parse(localStorage.getItem(`messages_${toolIdInitial}`) || '[]');
      return Array.isArray(saved) ? saved.filter(m=>m.type!=='loading') : [];
    } catch {
      return [];
    }
  });
  const [input, setInput] = useState('');
  const [chatModel, setChatModel] = useState('GPT-5');
  const inputRef = useRef(null);
  const chatEndRef = useRef(null);
  const [sending, setSending] = useState(false);

  // 기본 카드: ChatGPT (도구 목록에서 제거되었기 때문에 selectedTool 이 없으면 ChatGPT로 동작)
  const defaultChatTool = {
    id: 'chatgpt',
    name: 'Recipe Engine Demo',
    description: '영양/질환/약물 제약을 포함해 “설명 가능한” 레시피 추천을 만드는 데모입니다. (모델 선택 가능)',
  };
  const activeTool = selectedTool || defaultChatTool;

  // 히스토리 패널용 공통 값
  const toolId = selectedTool?.id || 'chatgpt';
  const historyPanel = <ChatHistoryPanel toolId={toolId} />;

  useEffect(() => {
    // 카드 전환 시 해당 카드의 저장된 대화 불러오기 (기본: chatgpt)
    const toolId = selectedTool?.id || 'chatgpt';
    try {
      const key = `messages_${toolId}`;
      const saved = JSON.parse(localStorage.getItem(key) || '[]');
      setMessages(Array.isArray(saved) ? saved.filter(m=>m.type!=='loading') : []);
    } catch {
      setMessages([]);
    }
  }, [selectedTool?.id]);

  useEffect(() => {
    // scroll to bottom
    chatEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  // 대화 변경 시 로컬스토리지에 저장 (기본: chatgpt)
  useEffect(() => {
    const toolId = selectedTool?.id || 'chatgpt';
    try { localStorage.setItem(`messages_${toolId}`, JSON.stringify(messages)); } catch {}
  }, [messages, selectedTool?.id]);


  // (iframe으로 제공하는 도구는 더 이상 없음)

  if (selectedTool && selectedTool.id === 'dev_chatbot') {
    return (
      <section className="page page-chat has-file-sidebar" style={{ flex: 1, position: 'relative', display:'flex', justifyContent:'flex-start', alignItems:'stretch' }}>
        {historyPanel}
        <FileSidebar />
        {/* DevChatInput renders header, messages, input */}
        <DevChatInput />
      </section>
    );
  }

  // 문서번역 도구: Word 파일 업로드/목록/다운로드/삭제 + 실시간 텍스트 번역 지원
  if (selectedTool && selectedTool.id === 'doc_translation') {
    return (
      <section className="page page-chat has-file-sidebar" style={{ flex: 1, position: 'relative', display:'flex', justifyContent:'flex-start', alignItems:'stretch' }}>
        {historyPanel}
        <DocTranslationSidebar />
        <DocTranslationChat />
      </section>
    );
  }

  const sendMessage = async () => {
    if (sending) return;
    if (!user) {
      alert('로그인이 필요합니다');
      return;
    }
    setSending(true);
    if (!input.trim()) { setSending(false); return; }
    const userMsg = { type: 'user', content: input.trim(), time: new Date().toLocaleTimeString() };
    setMessages((prev) => [...prev, userMsg]);
    setInput('');
    if (inputRef.current) {
      inputRef.current.style.height = '32px';
    }

    // loading placeholder
    const loadingMsg = { type: 'loading', start: Date.now() };
    setMessages((prev) => [...prev, loadingMsg]);

    // interval to update elapsed seconds
    const loadingInterval = setInterval(() => {
      setMessages((prev) => {
        const last = prev[prev.length - 1];
        if (last && last.type === 'loading') return [...prev]; // trigger rerender
        clearInterval(loadingInterval);
        return prev;
      });
    }, 1000);

    // backend 호출
    try {
      let botContent = '';
      if (activeTool.id === 'chatgpt') {
        const modelMap = {
          'GPT-5': 'gpt-5',
          'GPT-5-mini': 'gpt-5-mini',
          'GPT-5-nano': 'gpt-5-nano',
          'GPT-4o': 'gpt-4o',
          'GPT-4.1-mini': 'gpt-4o-mini',
          'o4-mini': 'o4-mini',
        };
        const model = modelMap[chatModel] || modelMap['GPT-5'];
        const sysPrompt = `당신은 한국어로 답하는 뛰어난 AI 어시스턴트입니다.

✅ 반드시 사실(팩트)에 기반하여 거짓 정보 없이 답하십시오.
✅ 먼저 내부적으로 생각(Chain-of-Thought)을 수행한 뒤, 이용자에게는 정리된 결과만 보여 주세요.
✅ 충분한 길이(최소 5문단)로, 필요 시 제목·소제목·순서/불릿 목록·코드 블록을 포함한 **Markdown** 형식을 사용하십시오.
✅ 이해를 돕기 위해 😃, 📌, 💡 등 적절한 이모지를 활용하십시오.
✅ 요약만 제시하지 말고, 예시·배경 설명·추가 정보를 상세히 제공합니다.
✅ 가능하다면 신뢰할 수 있는 공개 출처 URL 또는 참고문헌을 맨 아래에 제시하십시오.`;
        // 이미지 생성 의도 간단 감지 (예: 이미지/그려줘/생성해줘/그림/사진 등 키워드)
        // 1차: 키워드 룰기반, 2차: 모델 분류기로 보강 (샘플코드 방식)
        let wantsImage = /\b(이미지|그려줘|그림|사진|image|draw|generate\s+image|그려|create\s+an?\s+image|render)\b/i.test(userMsg.content);
        if (!wantsImage) {
          try {
            const cls = await classifyRequest(userMsg.content, 'gpt-5');
            wantsImage = cls === 'image';
          } catch (_) { /* ignore */ }
        }
        if (wantsImage) {
          try {
            const dataUrl = await fetchOpenAIImage(userMsg.content, 'gpt-image-1', { size: '1024x1024' });
            // 이미지 응답은 전용 타입으로 렌더링
            clearInterval(loadingInterval);
            const botMsg = { type: 'image', content: dataUrl, time: new Date().toLocaleTimeString() };
            setMessages((prev) => {
              const copy = [...prev];
              const idx = copy.findIndex((m) => m.type === 'loading');
              if (idx !== -1) copy[idx] = botMsg; else copy.push(botMsg);
              return copy;
            });
            return; // 조기 반환 (텍스트 처리 불필요)
          } catch (err) {
            // 이미지 생성 실패 시 텍스트 답변으로 폴백
            botContent = await fetchOpenAIChat([
              { role: 'system', content: sysPrompt },
              { role: 'user', content: userMsg.content },
            ], model, { });
          }
        } else {
          botContent = await fetchOpenAIChat([
            { role: 'system', content: sysPrompt },
            { role: 'user', content: userMsg.content },
          ], model, { });
        }
      } else {
        const formData = new FormData();
        formData.append('message', userMsg.content);
        formData.append('tool_id', activeTool.id);
        const res = await fetch(`${API_BASE_URL}/chat`, { method: 'POST', body: formData });
        const data = await res.json();
        botContent = data.response;
      }
      clearInterval(loadingInterval);
      const botMsg = { type: 'bot', content: botContent, time: new Date().toLocaleTimeString(), markdown:true };
      // replace loading placeholder
      setMessages((prev) => {
        const copy = [...prev];
        const idx = copy.findIndex((m) => m.type === 'loading');
        if (idx !== -1) copy[idx] = botMsg;
        return copy;
      });
    } catch (e) {
      setMessages((prev) => [...prev, { type: 'bot', content: '서버 오류', time: new Date().toLocaleTimeString() }]);
    }
    setSending(false);
  };

  return (
    <section className="page page-chat" style={{ flex: 1, display:'flex', flexDirection:'column', position:'relative' }}>
      {historyPanel}
      <div className="chat-center" style={{ width: '100%', maxWidth: 800 }}>
        <div className="tool-chat-header">
          <div className="tool-chat-title">{activeTool.name}</div>
          <div className="tool-chat-desc">{activeTool.description}</div>
        </div>
        {messages.map((m, idx) => (
          <div key={idx} className={`chat-message ${
            m.type === 'user' ? 'user-message' : (
              m.type === 'bot' || m.type === 'image' ? 'bot-message' : 'bot-message progress'
            )}`}>
            {m.type==='loading' ? (
              <div className="message-content" style={{color:'#888',fontStyle:'italic'}}>생각중...</div>
            ) : m.type==='image' ? (
              <div className="message-content"><img src={m.content} alt="generated" style={{ maxWidth:'100%', borderRadius:12 }}/></div>
            ) : m.markdown ? (
              <div className="message-content" dangerouslySetInnerHTML={{ __html: marked.parse(m.content) }} />
            ) : (
              <div className="message-content">{m.content}</div>
            )}
            <div className="message-time">{ m.type==='loading' ? `${Math.floor((Date.now()-m.start)/1000)}s` : m.time}</div>
          </div>
        ))}
        <div ref={chatEndRef} />
      </div>

      <div className="chat-input-wrapper">
        <div className="chat-input-area">
          {activeTool.id==='chatgpt' && (
            <select value={chatModel} onChange={(e)=>setChatModel(e.target.value)} style={{ marginRight:12, height:36, borderRadius:12, border:'1px solid #ffd6c2', color:'#ff6b4a' }}>
              <option value="GPT-5">GPT-5</option>
              <option value="GPT-5-mini">GPT-5-mini</option>
              <option value="GPT-5-nano">GPT-5-nano</option>
              <option value="GPT-4o">GPT-4o</option>
              <option value="GPT-4.1-mini">GPT-4.1-mini</option>
              <option value="o4-mini">o4-mini</option>
            </select>
          )}
          <textarea
            ref={inputRef}
            className="chat-input"
            rows={1}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onInput={(e)=>{ e.target.style.height='auto'; e.target.style.height=Math.min(e.target.scrollHeight,240)+"px"; }}
            placeholder="조건을 입력해 보세요 (예: 40대 남성 · 당뇨 전단계 · 저녁 · 나트륨 제한 · 한식 선호)"
            style={{ flex: 1, resize: 'none', border: 'none', outline: 'none', overflowY:'auto' }}
            onKeyDown={(e) => {
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendMessage();
              }
            }}
          />
          <button className="chat-send" onClick={sendMessage} disabled={!input.trim() || sending}>
            ↑
          </button>
        </div>
      </div>
    </section>
  );
} 

function DocTranslationSidebar() {
  const [files, setFiles] = useState([]);

  const extractRealFilename = (filename) => {
    const regex = /^\[doc_translation\]_admin_\d{14,17}_(.+)$/;
    const match = filename.match(regex);
    return match ? match[1] : filename;
  };

  const loadFiles = async () => {
    try {
      const res = await fetch(`${API_BASE_URL}/doc_translation/files`);
      const data = await res.json();
      setFiles(Array.isArray(data) ? data : []);
    } catch (_) {}
  };

  useEffect(() => { loadFiles(); }, []);

  const handleUpload = async () => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.doc,.docx';
    input.multiple = true;
    input.style.display = 'none';
    document.body.appendChild(input);
    input.onchange = async () => {
      const files = Array.from(input.files || []);
      if (!files.length) return;
      const formData = new FormData();
      files.forEach((f) => formData.append('files', f));
      try {
        await fetch(`${API_BASE_URL}/doc_translation/upload_doc`, { method: 'POST', body: formData });
      } finally {
        document.body.removeChild(input);
        loadFiles();
      }
    };
    input.click();
  };

  const handleDelete = async (serverFilename) => {
    if (!window.confirm(`${extractRealFilename(serverFilename)} 파일을 삭제하시겠습니까?`)) return;
    await fetch(`${API_BASE_URL}/doc_translation/files/${encodeURIComponent(serverFilename)}`, { method: 'DELETE' });
    loadFiles();
  };

  const handleDownload = async (filename) => {
    const res = await fetch(`${API_BASE_URL}/doc_translation/download/${encodeURIComponent(filename)}`);
    if (!res.ok) return alert('다운로드 실패');
    const blob = await res.blob();
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = extractRealFilename(filename);
    document.body.appendChild(a);
    a.click();
    URL.revokeObjectURL(url);
    document.body.removeChild(a);
  };

  return (
    <div className="file-sidebar">
      <div className="file-sidebar-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <span>파일 리스트</span>
        <button className="file-add-btn" onClick={handleUpload}>+</button>
      </div>
      <ul className="file-list">
        {files.map((f) => (
          <li key={f.filename} className={f.has_result ? 'translation-result-item' : ''} data-fname={f.filename} title={extractRealFilename(f.filename)}>
            {f.has_result ? (
              <div className="file-item-content">
                <div className="original-file">{extractRealFilename(f.filename)}</div>
                <div className="file-actions">
                  <a href="#" className="download-original-link" onClick={(e)=>{e.preventDefault(); handleDownload(f.filename);}}>[원본다운]</a>
                  <a href="#" className="download-result-link" onClick={(e)=>{e.preventDefault(); handleDownload(f.result_filename);}}>[결과다운]</a>
                  <button className="file-del-btn" onClick={()=>handleDelete(f.filename)}>✕</button>
                </div>
              </div>
            ) : (
              <>
                <span className="translating">번역중...</span>
                <button className="file-del-btn" onClick={()=>handleDelete(f.filename)}>✕</button>
              </>
            )}
          </li>
        ))}
      </ul>
    </div>
  );
}

function DocTranslationChat() {
  const { user } = useAuth();
  const { selectedTool } = useTool();
  const [messages, setMessages] = useState([]);
  const [sending, setSending] = useState(false);
  const [input, setInput] = useState('');
  const [model, setModel] = useState('internal'); // internal | external
  const inputRef2 = useRef(null);
  const chatEndRef = useRef(null);

  // 카드 전환 시 저장된 대화 불러오기
  useEffect(() => {
    try {
      const saved = JSON.parse(localStorage.getItem('messages_doc_translation') || '[]');
      setMessages(Array.isArray(saved) ? saved : []);
    } catch { setMessages([]); }
  }, [selectedTool?.id]);
  useEffect(() => { chatEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages]);
  // 변경 시 저장
  useEffect(() => {
    try { localStorage.setItem('messages_doc_translation', JSON.stringify(messages)); } catch {}
  }, [messages]);

  const sendMessage = async () => {
    if (sending) return;
    if (!user) {
      alert('로그인이 필요합니다');
      return;
    }
    setSending(true);
    if (!input.trim()) { setSending(false); return; }
    const userMsg = { type: 'user', content: input.trim(), time: new Date().toLocaleTimeString() };
    setMessages((prev) => [...prev, userMsg, { type: 'loading', start: Date.now() }]);
    setInput('');
    if (inputRef2.current) inputRef2.current.style.height = '32px';
    try {
      const form = new FormData();
      form.append('message', userMsg.content);
      // ChatPage 공통 /chat 엔드포인트의 문서번역 분기와 동일 동작을 위해 model 전달
      form.append('tool_id', 'doc_translation');
      form.append('model', model === 'internal' ? 'internal' : 'gpt-4o');
      const res = await fetch(`${API_BASE_URL}/chat`, { method: 'POST', body: form });
      const data = await res.json();
      const botContent = data.response;
      setMessages((prev) => {
        const copy = [...prev];
        const idx = copy.findIndex((m) => m.type === 'loading');
        const botMsg = { type: 'bot', content: botContent, time: new Date().toLocaleTimeString(), markdown: true };
        if (idx !== -1) copy[idx] = botMsg; else copy.push(botMsg);
        return copy;
      });
    } catch (e) {
      setMessages((prev) => [...prev, { type: 'bot', content: '서버 오류', time: new Date().toLocaleTimeString() }]);
    }
    setSending(false);
  };

  return (
    <>
      <div className="chat-center" style={{ width: '100%', maxWidth: 800 }}>
        <div className="tool-chat-header">
          <div className="tool-chat-title">문서번역</div>
          <div className="tool-chat-desc">MS Word 문서를 업로드하면 한글을 영어로 번역합니다.</div>
        </div>
        {messages.map((m, idx) => (
          <div key={idx} className={`chat-message ${m.type === 'user' ? 'user-message' : (m.type==='bot' ? 'bot-message' : 'bot-message progress')}`}>
            {m.type==='loading' ? (
              <div className="message-content" style={{color:'#888',fontStyle:'italic'}}>생각중...</div>
            ) : m.markdown ? (
              <div className="message-content" dangerouslySetInnerHTML={{ __html: marked.parse(m.content) }} />
            ) : (
              <div className="message-content">{m.content}</div>
            )}
            <div className="message-time">{ m.type==='loading' ? `${Math.floor((Date.now()-m.start)/1000)}s` : m.time}</div>
          </div>
        ))}
        <div ref={chatEndRef} />
      </div>

      <div className="chat-input-wrapper">
        <div className="chat-input-area">
          <select value={model} onChange={(e)=>setModel(e.target.value)} style={{ marginRight:12, height:36, borderRadius:12, border:'1px solid #ffd6c2', color:'#ff6b4a' }}>
            <option value="internal">자체모델</option>
            <option value="external">외부모델</option>
          </select>
          <textarea
            ref={inputRef2}
            className="chat-input"
            rows={1}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onInput={(e)=>{ e.target.style.height='auto'; e.target.style.height=Math.min(e.target.scrollHeight,240)+"px"; }}
            placeholder="번역할 한국어 텍스트를 입력하세요"
            style={{ flex: 1, resize: 'none', border: 'none', outline: 'none', overflowY:'auto' }}
            onKeyDown={(e) => {
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendMessage();
              }
            }}
          />
          <button className="chat-send" onClick={sendMessage} disabled={!input.trim() || sending}>
            ↑
          </button>
        </div>
      </div>
    </>
  );
}