import { FormEvent, useEffect, useMemo, useRef, useState } from 'react';
import { buildWelcomeText, getQuickPrompts, runMockAgent } from './mockAgent';
import type { DemoLocale, DemoMessage, DemoMode, DemoTabId, ProgressStep, TraceItem } from './types';
import VoiceDemoPanel from './VoiceDemoPanel';
import MarketingStudioPanel from './MarketingStudioPanel';
import InvoiceDemoPanel from './InvoiceDemoPanel';
import MarketplaceDemoPanel from './MarketplaceDemoPanel';
import ChatFeatureDemo from './ChatFeatureDemo';
import { runLiveAgent } from './liveAgent';

const TAB_DEFINITIONS: Record<DemoLocale, Array<{ id: DemoTabId; label: string; subtitle: string }>> = {
  en: [
    { id: 'chat', label: 'Chat Agent', subtitle: 'Tool-first orchestration' },
    { id: 'voice', label: 'Voice Agent', subtitle: 'Speech-style actions' },
    { id: 'marketing', label: 'Marketing Studio', subtitle: 'Copy + visual workflow' },
    { id: 'invoice', label: 'Invoice AI', subtitle: 'OCR + extraction demo' },
    { id: 'marketplace', label: 'Marketplace', subtitle: 'Search + ranking + stats' },
  ],
  'zh-TW': [
    { id: 'chat', label: '聊天代理', subtitle: '工具優先協作流程' },
    { id: 'voice', label: '語音代理', subtitle: '語音式操作流程' },
    { id: 'marketing', label: '行銷工作室', subtitle: '文案 + 視覺素材流程' },
    { id: 'invoice', label: '發票 AI', subtitle: 'OCR + 欄位擷取示範' },
    { id: 'marketplace', label: '市集探索', subtitle: '搜尋 + 排名 + 統計' },
  ],
};

const APP_COPY = {
  en: {
    eyebrow: 'Farm2Market Demo',
    title: 'Agent Workspace',
    statusRunning: 'Running',
    statusIdle: 'Idle',
    hideControls: 'Hide Controls',
    showControls: 'Show Controls',
    tabAria: 'Agent tabs',
    controlsTitle: 'Controls',
    controlsSubtitle: 'Switch scenario and prompt packs.',
    demoMode: 'Demo Mode',
    modeMock: 'Mock (stable)',
    modeLive: 'Live (backend)',
    language: 'Language',
    english: 'English',
    traditionalChinese: 'Traditional Chinese',
    tryPrompts: 'Try Prompts',
    progressTitle: 'Model Progress',
    progressRunning: 'In progress',
    progressDone: 'Completed',
    structuredOutput: 'Structured Output',
    workingMessage: 'Working through the request…',
    composerPlaceholder: 'Describe what to demo, e.g. search eggs below 200',
    clearPanels: 'Clear Panels',
    runningAction: 'Running…',
    runDemo: 'Run Demo',
    traceTitle: 'Agent Trace',
    traceLive: 'Live events',
    traceLast: 'Last run summary',
    tracePayload: 'payload',
    traceWaiting: 'Waiting for trace events…',
    unknownError: 'Unknown runtime error',
    roleLabels: {
      user: 'user',
      assistant: 'assistant',
      system: 'system',
    },
    kindLabels: {
      planner: 'planner',
      tool: 'tool',
      validator: 'validator',
      renderer: 'renderer',
    },
  },
  'zh-TW': {
    eyebrow: 'Farm2Market 示範',
    title: '代理工作台',
    statusRunning: '執行中',
    statusIdle: '待命',
    hideControls: '隱藏控制',
    showControls: '顯示控制',
    tabAria: '代理分頁',
    controlsTitle: '控制面板',
    controlsSubtitle: '切換情境與提示組合。',
    demoMode: '示範模式',
    modeMock: '模擬（穩定）',
    modeLive: '即時（後端）',
    language: '語言',
    english: '英文',
    traditionalChinese: '繁體中文',
    tryPrompts: '快速提示',
    progressTitle: '模型處理進度',
    progressRunning: '執行中',
    progressDone: '完成',
    structuredOutput: '結構化輸出',
    workingMessage: '正在處理中，請稍候…',
    composerPlaceholder: '描述你要示範的功能，例如：幫我搜尋 200 以下雞蛋',
    clearPanels: '清除面板',
    runningAction: '執行中…',
    runDemo: '執行示範',
    traceTitle: '代理追蹤',
    traceLive: '即時事件',
    traceLast: '最近一次摘要',
    tracePayload: '載荷',
    traceWaiting: '等待追蹤事件…',
    unknownError: '未知執行錯誤',
    roleLabels: {
      user: '使用者',
      assistant: '助理',
      system: '系統',
    },
    kindLabels: {
      planner: '規劃',
      tool: '工具',
      validator: '驗證',
      renderer: '輸出',
    },
  },
} as const;

function timestampLabel(): string {
  return new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}

function createMessage(
  role: DemoMessage['role'],
  text: string,
  extra?: Pick<DemoMessage, 'cards' | 'jsonPayload'>
): DemoMessage {
  return {
    id: `${role}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 7)}`,
    role,
    text,
    timestamp: timestampLabel(),
    cards: extra?.cards,
    jsonPayload: extra?.jsonPayload,
  };
}

function statusIcon(status: ProgressStep['status']): string {
  if (status === 'completed') return '✓';
  if (status === 'error') return '!';
  if (status === 'in_progress') return '●';
  return '○';
}

function App() {
  const [activeTab, setActiveTab] = useState<DemoTabId>('chat');
  const [mode, setMode] = useState<DemoMode>('mock');
  const [locale, setLocale] = useState<DemoLocale>('en');
  const [input, setInput] = useState('');
  const [isWorking, setIsWorking] = useState(false);
  const [progressSteps, setProgressSteps] = useState<ProgressStep[]>([]);
  const [traceItems, setTraceItems] = useState<TraceItem[]>([]);
  const [progressVisible, setProgressVisible] = useState(false);
  const [mobileControlsOpen, setMobileControlsOpen] = useState(false);
  const [queuedVoicePrompt, setQueuedVoicePrompt] = useState<string | null>(null);
  const [queuedMarketingPrompt, setQueuedMarketingPrompt] = useState<string | null>(null);
  const [queuedInvoicePrompt, setQueuedInvoicePrompt] = useState<string | null>(null);
  const [queuedMarketplacePrompt, setQueuedMarketplacePrompt] = useState<string | null>(null);

  const [messages, setMessages] = useState<DemoMessage[]>([
    createMessage('system', buildWelcomeText('chat', 'en')),
  ]);

  const firstRenderRef = useRef(true);
  const threadRef = useRef<HTMLDivElement | null>(null);

  const copy = APP_COPY[locale];
  const tabs = TAB_DEFINITIONS[locale];
  const quickPrompts = useMemo(() => getQuickPrompts(activeTab, locale), [activeTab, locale]);
  const showTracePanel = isWorking || traceItems.length > 0;

  useEffect(() => {
    if (firstRenderRef.current) {
      firstRenderRef.current = false;
      return;
    }

    setMessages((prev) => [...prev, createMessage('system', buildWelcomeText(activeTab, locale))]);
    setProgressSteps([]);
    setTraceItems([]);
    setInput('');
    setQueuedVoicePrompt(null);
    setQueuedMarketingPrompt(null);
    setQueuedInvoicePrompt(null);
    setQueuedMarketplacePrompt(null);
    setIsWorking(false);
  }, [activeTab, locale]);

  useEffect(() => {
    if (isWorking) {
      setProgressVisible(true);
      return;
    }

    if (!progressSteps.length) {
      setProgressVisible(false);
      return;
    }

    const timer = window.setTimeout(() => {
      setProgressVisible(false);
    }, 2000);

    return () => window.clearTimeout(timer);
  }, [isWorking, progressSteps]);

  useEffect(() => {
    if (activeTab === 'voice' || activeTab === 'marketing' || activeTab === 'invoice' || activeTab === 'marketplace') return;
    if (!threadRef.current) return;
    threadRef.current.scrollTo({ top: threadRef.current.scrollHeight, behavior: 'smooth' });
  }, [activeTab, messages, progressSteps, isWorking]);

  const updateStepStatus = (stepId: string, status: ProgressStep['status'], detail?: string) => {
    setProgressSteps((prev) =>
      prev.map((step) => (step.id === stepId ? { ...step, status, detail: detail ?? step.detail } : step))
    );
  };

  const pushTrace = (item: TraceItem) => {
    setTraceItems((prev) => [...prev, item].slice(-20));
  };

  const clearPanels = () => {
    setTraceItems([]);
    setProgressSteps([]);
  };

  async function handleSubmit(event: FormEvent) {
    event.preventDefault();
    if (isWorking) return;

    const trimmed = input.trim();
    if (!trimmed) return;

    setMessages((prev) => [...prev, createMessage('user', trimmed)]);
    setInput('');
    setTraceItems([]);
    setIsWorking(true);

    try {
      const result =
        mode === 'live'
          ? await runLiveAgent({
              tab: activeTab,
              input: trimmed,
              locale,
              onWorkflowInit: (steps) => {
                setProgressSteps(steps);
              },
              onStepStatus: (stepId, status, detail) => {
                updateStepStatus(stepId, status, detail);
              },
              onTrace: (item) => {
                pushTrace(item);
              },
            })
          : await runMockAgent({
              tab: activeTab,
              input: trimmed,
              locale,
              mode,
              onWorkflowInit: (steps) => {
                setProgressSteps(steps);
              },
              onStepStatus: (stepId, status, detail) => {
                updateStepStatus(stepId, status, detail);
              },
              onTrace: (item) => {
                pushTrace(item);
              },
            });

      setMessages((prev) => [
        ...prev,
        createMessage('assistant', result.summary, {
          cards: result.cards,
          jsonPayload: result.payload,
        }),
      ]);
    } catch (error) {
      const message = error instanceof Error ? error.message : copy.unknownError;
      setMessages((prev) => [
        ...prev,
        createMessage(
          'assistant',
          locale === 'zh-TW'
            ? `執行時發生錯誤：${message}`
            : `The demo run failed with an error: ${message}`
        ),
      ]);
      setProgressSteps((prev) =>
        prev.map((step) => (step.status === 'in_progress' ? { ...step, status: 'error', detail: message } : step))
      );
    } finally {
      setIsWorking(false);
    }
  }

  return (
    <div className={`demo-root ${showTracePanel ? 'trace-open' : 'trace-hidden'} ${mobileControlsOpen ? 'controls-open' : ''}`}>
      <div className="bg-orb bg-orb-a" />
      <div className="bg-orb bg-orb-b" />

      <header className="topbar">
        <div>
          <p className="eyebrow">{copy.eyebrow}</p>
          <h1>{copy.title}</h1>
        </div>

        <div className="topbar-actions">
          <span className={`status-pill ${isWorking ? 'busy' : 'idle'}`}>{isWorking ? copy.statusRunning : copy.statusIdle}</span>
          <button className="ghost-btn mobile-only" type="button" onClick={() => setMobileControlsOpen((prev) => !prev)}>
            {mobileControlsOpen ? copy.hideControls : copy.showControls}
          </button>
        </div>
      </header>

      <nav className="tab-row" aria-label={copy.tabAria}>
        {tabs.map((tab) => (
          <button
            key={tab.id}
            type="button"
            className={`tab-btn ${activeTab === tab.id ? 'active' : ''}`}
            onClick={() => setActiveTab(tab.id)}
          >
            <span>{tab.label}</span>
            <small>{tab.subtitle}</small>
          </button>
        ))}
      </nav>

      <div className="workspace">
        <aside className="panel controls-panel">
          <div className="panel-header">
            <h2>{copy.controlsTitle}</h2>
            <p>{copy.controlsSubtitle}</p>
          </div>

          <label className="field">
            <span>{copy.demoMode}</span>
            <select value={mode} onChange={(event) => setMode(event.target.value as DemoMode)}>
              <option value="mock">{copy.modeMock}</option>
              <option value="live">{copy.modeLive}</option>
            </select>
          </label>

          <label className="field">
            <span>{copy.language}</span>
            <select value={locale} onChange={(event) => setLocale(event.target.value as DemoLocale)}>
              <option value="en">{copy.english}</option>
              <option value="zh-TW">{copy.traditionalChinese}</option>
            </select>
          </label>

          <section className="prompt-bank">
            <h3>{copy.tryPrompts}</h3>
            <div className="chip-list">
              {quickPrompts.map((prompt) => (
                <button
                  key={prompt}
                  type="button"
                  className="prompt-chip"
                  onClick={() => {
                    if (activeTab === 'voice') {
                      setQueuedVoicePrompt(prompt);
                      setMobileControlsOpen(false);
                      return;
                    }
                    if (activeTab === 'marketing') {
                      setQueuedMarketingPrompt(prompt);
                      setMobileControlsOpen(false);
                      return;
                    }
                    if (activeTab === 'invoice') {
                      setQueuedInvoicePrompt(prompt);
                      setMobileControlsOpen(false);
                      return;
                    }
                    if (activeTab === 'marketplace') {
                      setQueuedMarketplacePrompt(prompt);
                      setMobileControlsOpen(false);
                      return;
                    }
                    setInput(prompt);
                    setMobileControlsOpen(false);
                  }}
                >
                  {prompt}
                </button>
              ))}
            </div>
          </section>
        </aside>

        <section className="panel conversation-panel">
          {progressVisible && progressSteps.length > 0 ? (
            <section className="progress-panel" aria-live="polite">
              <header>
                <h3>{copy.progressTitle}</h3>
                <span>{isWorking ? copy.progressRunning : copy.progressDone}</span>
              </header>
              <ul>
                {progressSteps.map((step) => (
                  <li key={step.id} className={`step-${step.status}`}>
                    <span className={`step-icon ${step.status === 'in_progress' ? 'spin' : ''}`}>{statusIcon(step.status)}</span>
                    <div>
                      <strong>{step.label}</strong>
                      <small>{step.detail}</small>
                    </div>
                  </li>
                ))}
              </ul>
            </section>
          ) : null}

          {activeTab === 'voice' ? (
            <VoiceDemoPanel
              mode={mode}
              locale={locale}
              onWorkingChange={setIsWorking}
              onWorkflowInit={setProgressSteps}
              onStepStatus={updateStepStatus}
              onTrace={pushTrace}
              onClearPanels={clearPanels}
              queuedPrompt={queuedVoicePrompt}
              onConsumeQueuedPrompt={() => setQueuedVoicePrompt(null)}
            />
          ) : activeTab === 'marketing' ? (
            <MarketingStudioPanel
              mode={mode}
              locale={locale}
              onWorkingChange={setIsWorking}
              onWorkflowInit={setProgressSteps}
              onStepStatus={updateStepStatus}
              onTrace={pushTrace}
              onClearPanels={clearPanels}
              queuedPrompt={queuedMarketingPrompt}
              onConsumeQueuedPrompt={() => setQueuedMarketingPrompt(null)}
            />
          ) : activeTab === 'invoice' ? (
            <InvoiceDemoPanel
              mode={mode}
              locale={locale}
              onWorkingChange={setIsWorking}
              onWorkflowInit={setProgressSteps}
              onStepStatus={updateStepStatus}
              onTrace={pushTrace}
              onClearPanels={clearPanels}
              queuedPrompt={queuedInvoicePrompt}
              onConsumeQueuedPrompt={() => setQueuedInvoicePrompt(null)}
            />
          ) : activeTab === 'marketplace' ? (
            <MarketplaceDemoPanel
              mode={mode}
              locale={locale}
              onWorkingChange={setIsWorking}
              onWorkflowInit={setProgressSteps}
              onStepStatus={updateStepStatus}
              onTrace={pushTrace}
              onClearPanels={clearPanels}
              queuedPrompt={queuedMarketplacePrompt}
              onConsumeQueuedPrompt={() => setQueuedMarketplacePrompt(null)}
            />
          ) : (
            <>
              <ChatFeatureDemo locale={locale} isBusy={isWorking} />

              <div className="thread" ref={threadRef}>
                {messages.map((message) => (
                  <article key={message.id} className={`message ${message.role}`}>
                    <header>
                      <span>{copy.roleLabels[message.role]}</span>
                      <time>{message.timestamp}</time>
                    </header>
                    <p>{message.text}</p>

                    {message.cards && message.cards.length > 0 ? (
                      <div className="result-grid">
                        {message.cards.map((card) => (
                          <section className="result-card" key={`${message.id}-${card.title}`}>
                            <h4>{card.title}</h4>
                            {card.subtitle ? <p>{card.subtitle}</p> : null}

                            {card.metrics && card.metrics.length > 0 ? (
                              <div className="metric-grid">
                                {card.metrics.map((metric) => (
                                  <div key={`${card.title}-${metric.label}`}>
                                    <span>{metric.label}</span>
                                    <strong>{metric.value}</strong>
                                  </div>
                                ))}
                              </div>
                            ) : null}

                            {card.tags && card.tags.length > 0 ? (
                              <div className="tag-row">
                                {card.tags.map((tag) => (
                                  <span key={`${card.title}-${tag}`}>#{tag}</span>
                                ))}
                              </div>
                            ) : null}

                            {card.actions && card.actions.length > 0 ? (
                              <div className="action-row">
                                {card.actions.map((action) => (
                                  <button key={`${card.title}-${action}`} type="button" className="mini-btn">
                                    {action}
                                  </button>
                                ))}
                              </div>
                            ) : null}
                          </section>
                        ))}
                      </div>
                    ) : null}

                    {message.jsonPayload ? (
                      <details className="payload-viewer">
                        <summary>{copy.structuredOutput}</summary>
                        <pre>{JSON.stringify(message.jsonPayload, null, 2)}</pre>
                      </details>
                    ) : null}
                  </article>
                ))}

                {isWorking ? (
                  <article className="message assistant loading">
                    <header>
                      <span>{copy.roleLabels.assistant}</span>
                      <time>{timestampLabel()}</time>
                    </header>
                    <p>{copy.workingMessage}</p>
                    <div className="typing-dots" aria-hidden="true">
                      <span />
                      <span />
                      <span />
                    </div>
                  </article>
                ) : null}
              </div>

              <form className="composer" onSubmit={handleSubmit}>
                <textarea
                  value={input}
                  onChange={(event) => setInput(event.target.value)}
                  rows={3}
                  placeholder={
                    copy.composerPlaceholder
                  }
                />
                <div className="composer-actions">
                  <button type="button" className="ghost-btn" onClick={clearPanels} disabled={isWorking}>
                    {copy.clearPanels}
                  </button>
                  <button type="submit" className="primary-btn" disabled={isWorking || !input.trim()}>
                    {isWorking ? copy.runningAction : copy.runDemo}
                  </button>
                </div>
              </form>
            </>
          )}
        </section>

        {showTracePanel ? (
          <aside className="panel trace-panel">
            <div className="panel-header">
              <h2>{copy.traceTitle}</h2>
              <p>{isWorking ? copy.traceLive : copy.traceLast}</p>
            </div>

            {traceItems.length ? (
              <ul className="trace-list">
                {traceItems.map((item) => (
                  <li key={item.id} className={`trace-${item.status}`}>
                    <header>
                      <span className="kind">{copy.kindLabels[item.kind]}</span>
                      <strong>{item.title}</strong>
                      <time>{item.timestamp}</time>
                    </header>
                    <p>{item.detail}</p>
                    {item.payload ? (
                      <details>
                        <summary>{copy.tracePayload}</summary>
                        <pre>{JSON.stringify(item.payload, null, 2)}</pre>
                      </details>
                    ) : null}
                  </li>
                ))}
              </ul>
            ) : (
              <div className="trace-empty">
                <p>{copy.traceWaiting}</p>
              </div>
            )}
          </aside>
        ) : null}
      </div>
    </div>
  );
}

export default App;
