import { useEffect, useMemo, useState } from 'react';
import type { DemoLocale } from './types';

type VoiceScene = {
  id: 'listen' | 'route' | 'cards';
  durationMs: number;
};

type VoiceFeatureDemoProps = {
  locale: DemoLocale;
  isBusy: boolean;
};

const COPY = {
  en: {
    title: 'Voice Demo',
    busy: 'Running',
    hidden: 'Hidden',
    play: 'Play',
    pause: 'Pause',
    replay: 'Replay',
    hide: 'Hide',
    show: 'Show',
    videoName: 'voice_demo.webm',
    step: 'Step',
    lanes: {
      listen: 'Listen',
      route: 'Route',
      cards: 'Cards',
    },
    routeWords: {
      nodes: ['Parse', 'Plan', 'Call'],
      chips: ['Stock', 'Price', 'Store', 'Safe'],
    },
    captions: {
      listen: 'Capture voice and intent',
      route: 'Plan tool sequence',
      cards: 'Return voice cards',
    },
    stepCopy: {
      listen: {
        title: 'Live Voice Capture',
        body:
          'Microphone audio is sampled in real time, normalized for volume variance, and segmented into phrase-sized chunks for stable transcript quality.',
        detail:
          'Noise suppression, language hinting, and intent candidate extraction run before any tool is called.',
      },
      route: {
        title: 'Tool Route Planning',
        body:
          'The planner maps your spoken goal into executable actions, selects the best tool chain, and prepares argument payloads with guardrails.',
        detail:
          'Validation checks include category filters, price constraints, availability context, and fallback routing when confidence is low.',
      },
      cards: {
        title: 'Structured Voice Response',
        body:
          'Results are transformed into concise spoken output plus visual cards so users can confirm key data without opening raw payloads.',
        detail:
          'Action chips are attached for immediate follow-up tasks such as editing stock, opening product details, or triggering the next workflow.',
      },
    },
    cardVisual: {
      summaryTitle: 'Assistant Summary',
      summaryBody: 'I updated stock to 48, synced pickup details, and prepared two follow-up actions.',
      actions: ['Open Product', 'Edit Again', 'Share Update'],
      statsTitle: 'Result Snapshot',
      stats: [
        { label: 'Confidence', value: '96%' },
        { label: 'Tool Calls', value: '3' },
        { label: 'Latency', value: '1.2s' },
      ],
      statsNote: 'Structured payload attached to voice response card.',
    },
  },
  'zh-TW': {
    title: '語音導覽',
    busy: '執行中',
    hidden: '已隱藏',
    play: '播放',
    pause: '暫停',
    replay: '重播',
    hide: '隱藏',
    show: '顯示',
    videoName: '語音導覽影片.webm',
    step: '步驟',
    lanes: {
      listen: '收音',
      route: '路由',
      cards: '結果',
    },
    routeWords: {
      nodes: ['解析', '規劃', '呼叫'],
      chips: ['庫存', '價格', '店家', '安全'],
    },
    captions: {
      listen: '接收語音與意圖',
      route: '規劃工具流程',
      cards: '回傳語音卡片',
    },
    stepCopy: {
      listen: {
        title: '即時語音收音',
        body: '系統會即時擷取麥克風音訊，先做音量與分段標準化，再輸出更穩定的語音文字片段。',
        detail: '在呼叫工具前，會先完成降噪、語系判斷與初步意圖分類。',
      },
      route: {
        title: '工具路由規劃',
        body: '規劃器會把語音目標轉成可執行步驟，選擇最佳工具鏈並組裝對應參數。',
        detail: '同時檢查分類、價格、庫存與容錯路由，確保低信心情況也能安全回應。',
      },
      cards: {
        title: '語音結果封裝',
        body: '最終回覆會整合口語摘要與視覺卡片，讓使用者快速理解結果而不必直接讀 JSON。',
        detail: '卡片會附帶後續操作按鈕，例如更新庫存、查看商品頁、或直接進入下一步。',
      },
    },
    cardVisual: {
      summaryTitle: '語音摘要',
      summaryBody: '已更新庫存為 48，補上取貨資訊，並整理兩個後續操作。',
      actions: ['查看商品', '再次編輯', '分享更新'],
      statsTitle: '結果快照',
      stats: [
        { label: '信心值', value: '96%' },
        { label: '工具數', value: '3' },
        { label: '延遲', value: '1.2s' },
      ],
      statsNote: '已將結構化載荷附加到語音卡片。',
    },
  },
} as const;

const SCENES: VoiceScene[] = [
  { id: 'listen', durationMs: 1700 },
  { id: 'route', durationMs: 1750 },
  { id: 'cards', durationMs: 1700 },
];

export default function VoiceFeatureDemo({ locale, isBusy }: VoiceFeatureDemoProps) {
  const copy = COPY[locale];
  const scenes = useMemo(() => SCENES, []);

  const [sceneIndex, setSceneIndex] = useState(0);
  const [elapsedMs, setElapsedMs] = useState(0);
  const [isPlaying, setIsPlaying] = useState(true);
  const [isCollapsed, setIsCollapsed] = useState(false);
  const [reducedMotion, setReducedMotion] = useState(false);

  useEffect(() => {
    const media = window.matchMedia('(prefers-reduced-motion: reduce)');
    const apply = () => setReducedMotion(media.matches);

    apply();
    if (media.addEventListener) {
      media.addEventListener('change', apply);
      return () => media.removeEventListener('change', apply);
    }

    media.addListener(apply);
    return () => media.removeListener(apply);
  }, []);

  useEffect(() => {
    if (reducedMotion) setIsPlaying(false);
  }, [reducedMotion]);

  useEffect(() => {
    setSceneIndex(0);
    setElapsedMs(0);
    setIsCollapsed(false);
    if (!reducedMotion) setIsPlaying(true);
  }, [locale, reducedMotion]);

  useEffect(() => {
    if (!isBusy) return;
    setIsCollapsed(true);
    setIsPlaying(false);
  }, [isBusy]);

  useEffect(() => {
    if (!isPlaying || isCollapsed || isBusy || reducedMotion) return;

    const timer = window.setInterval(() => {
      setElapsedMs((prev) => {
        const scene = scenes[sceneIndex];
        if (!scene) return 0;
        const next = prev + 120;
        if (next < scene.durationMs) return next;
        setSceneIndex((current) => (current + 1) % scenes.length);
        return 0;
      });
    }, 120);

    return () => window.clearInterval(timer);
  }, [isPlaying, isCollapsed, isBusy, reducedMotion, scenes, sceneIndex]);

  const activeScene = scenes[sceneIndex] ?? scenes[0];
  const totalDuration = scenes.reduce((sum, scene) => sum + scene.durationMs, 0);
  const previousDuration = scenes.slice(0, sceneIndex).reduce((sum, scene) => sum + scene.durationMs, 0);
  const progress = totalDuration > 0 ? Math.round(((previousDuration + elapsedMs) / totalDuration) * 100) : 0;
  const sceneCaption = copy.captions[activeScene.id];

  const replay = () => {
    setSceneIndex(0);
    setElapsedMs(0);
    if (!reducedMotion && !isBusy) setIsPlaying(true);
  };

  if (isCollapsed) {
    return (
      <section className="voice-walk-collapsed" aria-live="polite">
        <div className="voice-walk-mini-markers" aria-hidden="true">
          <span />
          <span />
          <span />
        </div>
        <p>{isBusy ? copy.busy : copy.hidden}</p>
        {!isBusy ? (
          <button
            type="button"
            className="ghost-btn"
            onClick={() => {
              setIsCollapsed(false);
              replay();
            }}
          >
            {copy.show}
          </button>
        ) : null}
      </section>
    );
  }

  return (
    <section className="voice-walk-video" aria-label={copy.title}>
      <header className="voice-walk-head">
        <div>
          <h3>{copy.title}</h3>
          <small>
            {copy.step} {sceneIndex + 1}/{scenes.length}
          </small>
        </div>
        <div className="voice-walk-actions">
          <button
            type="button"
            className="voice-walk-icon-btn"
            onClick={() => setIsPlaying((prev) => !prev)}
            disabled={isBusy || reducedMotion}
            aria-label={isPlaying ? copy.pause : copy.play}
          >
            {isPlaying ? '||' : '>'}
          </button>
          <button type="button" className="voice-walk-icon-btn" onClick={replay} disabled={isBusy} aria-label={copy.replay}>
            R
          </button>
          <button type="button" className="voice-walk-icon-btn" onClick={() => setIsCollapsed(true)} aria-label={copy.hide}>
            X
          </button>
        </div>
      </header>

      <div className="voice-walk-frame" data-scene={activeScene.id}>
        <div className="voice-walk-windowbar">
          <span />
          <span />
          <span />
          <small>{copy.videoName}</small>
        </div>

        <div className="voice-walk-canvas">
          <section className="voice-walk-lane listen">
            <span className="voice-walk-lane-index">1</span>
            <small className="voice-walk-lane-label">{copy.lanes.listen}</small>
            <div className="voice-walk-wave">
              {Array.from({ length: 10 }).map((_, index) => (
                <span key={`wave-${index}`} style={{ animationDelay: `${index * 0.08}s` }} />
              ))}
            </div>
            <div className="voice-walk-mic">
              <span />
            </div>
            <div className="voice-walk-step-copy">
              <strong>{copy.stepCopy.listen.title}</strong>
              <p>{copy.stepCopy.listen.body}</p>
              <small>{copy.stepCopy.listen.detail}</small>
            </div>
          </section>

          <section className="voice-walk-lane route">
            <span className="voice-walk-lane-index">2</span>
            <small className="voice-walk-lane-label">{copy.lanes.route}</small>
            <div className="voice-walk-route-nodes">
              {copy.routeWords.nodes.map((word) => (
                <span key={word}>{word}</span>
              ))}
            </div>
            <div className="voice-walk-route-flow">
              <span />
            </div>
            <div className="voice-walk-route-chips">
              {copy.routeWords.chips.map((word) => (
                <span key={word}>{word}</span>
              ))}
            </div>
            <div className="voice-walk-step-copy">
              <strong>{copy.stepCopy.route.title}</strong>
              <p>{copy.stepCopy.route.body}</p>
              <small>{copy.stepCopy.route.detail}</small>
            </div>
          </section>

          <section className="voice-walk-lane cards">
            <span className="voice-walk-lane-index">3</span>
            <small className="voice-walk-lane-label">{copy.lanes.cards}</small>
            <article className="voice-walk-card">
              <header className="voice-walk-card-head">
                <strong>{copy.cardVisual.summaryTitle}</strong>
              </header>
              <p className="voice-walk-card-body">{copy.cardVisual.summaryBody}</p>
              <div className="voice-walk-chip-row">
                {copy.cardVisual.actions.map((action) => (
                  <span key={action}>{action}</span>
                ))}
              </div>
            </article>
            <article className="voice-walk-card">
              <header className="voice-walk-card-head">
                <strong>{copy.cardVisual.statsTitle}</strong>
              </header>
              <div className="voice-walk-grid">
                {copy.cardVisual.stats.map((item) => (
                  <span key={item.label}>
                    <small>{item.label}</small>
                    <strong>{item.value}</strong>
                  </span>
                ))}
              </div>
              <p className="voice-walk-card-note">{copy.cardVisual.statsNote}</p>
            </article>
            <div className="voice-walk-step-copy">
              <strong>{copy.stepCopy.cards.title}</strong>
              <p>{copy.stepCopy.cards.body}</p>
              <small>{copy.stepCopy.cards.detail}</small>
            </div>
          </section>
        </div>
      </div>

      <footer className="voice-walk-meta">
        <div className="voice-walk-progress-track" aria-hidden="true">
          <span style={{ width: `${Math.min(100, Math.max(0, progress))}%` }} />
        </div>
        <p className="voice-walk-caption">{sceneCaption}</p>
        <div className="voice-walk-scene-dots">
          {scenes.map((scene, index) => (
            <button
              key={scene.id}
              type="button"
              className={`voice-walk-scene-dot ${index === sceneIndex ? 'active' : index < sceneIndex ? 'complete' : ''}`}
              onClick={() => {
                setSceneIndex(index);
                setElapsedMs(0);
              }}
              aria-label={`${copy.step} ${index + 1}`}
            >
              <span />
            </button>
          ))}
        </div>
      </footer>
    </section>
  );
}
