(function () {
  'use strict';

  const T = window.STOCK_TOKENS;

  // ─── Template formatters ──────────────────────────────────────────────────

  function formatStockPick(data) {
    const {
      code, name, score, score_breakdown: sb, current_price,
      entry_low, entry_high, target_short, stop_loss, themes, llm_card,
    } = data;
    return `## 深問：${code} ${name}（推薦指數 ${score}/100）

### 推薦資訊
- 當前價：${current_price}
- 進場區間：${entry_low} - ${entry_high}
- 目標價（短線）：${target_short}
- 停損：${stop_loss}
- 題材：${(themes || []).join(', ')}

### 評分組成
- 基本面：${sb?.fundamentals ?? '—'}/30
- 技術面：${sb?.technical ?? '—'}/30
- 籌碼面：${sb?.chip ?? '—'}/20
- 新聞面：${sb?.news ?? '—'}/10
- 動能：${sb?.momentum ?? '—'}/10

### AI 推薦理由
${llm_card ?? '（無）'}

---
請以上資料分析此股短期進場合理性、估算合理目標價區間、指出我可能忽略的風險。`;
  }

  function formatDeepAnalysis(data) {
    const { code, name, current_price, themes, raw_metrics: rm, llm_card } = data;
    const metricsOrder = [
      ['基本面', rm?.fundamentals],
      ['技術面', rm?.technical],
      ['籌碼', rm?.chip],
      ['月營收', rm?.monthly_revenue],
      ['融資融券', rm?.margin],
      ['借券', rm?.short_lending],
      ['行事曆', rm?.calendar],
      ['主力', rm?.major_player],
      ['產業強弱', rm?.industry_strength],
    ];
    const metricsBlock = metricsOrder
      .map(([label, val]) => {
        const text = val == null
          ? '（無資料）'
          : typeof val === 'object'
            ? JSON.stringify(val, null, 2)
            : String(val);
        return `#### ${label}\n${text}`;
      })
      .join('\n\n');

    return `## 深問：${code} ${name} 9 面向分析

- 當前價：${current_price ?? '—'}
- 題材：${(themes || []).join(', ')}

### 9 面向指標

${metricsBlock}

### AI 摘要
${llm_card ?? '（無）'}

---
請以上 9 面向資料判斷此股 1-3 個月趨勢，並給出「該不該續抱」建議。`;
  }

  function formatBriefing(data) {
    const { date, market_indices: mi, top_picks, themes_top5, self_watchlist_alerts } = data;
    const indicesBlock = mi
      ? Object.entries(mi)
          .map(([k, v]) => `- ${k}：${v}`)
          .join('\n')
      : '（無）';
    const picksBlock = (top_picks || [])
      .map((p, i) => `${i + 1}. **${p.code} ${p.name}**：${p.reason ?? ''}`)
      .join('\n');
    const themesBlock = (themes_top5 || []).map((t) => `- ${t}`).join('\n');
    const alertsBlock = (self_watchlist_alerts || [])
      .map((a) => `- ${a.code} ${a.name}：${a.message ?? ''}`)
      .join('\n') || '（無異常）';

    return `## 今日盤前簡報（${date ?? ''}）

### 大盤指數
${indicesBlock}

### 今日推薦
${picksBlock || '（無）'}

### 熱門題材 Top 5
${themesBlock || '（無）'}

### 自選股警示
${alertsBlock}

---
請以上盤前資料指出今日台股最該關注的 3 件事，以及我手上自選股的影響。`;
  }

  function formatReview(data) {
    const { period, kpi, group_analysis, individual_review } = data;
    const kpiBlock = kpi
      ? `| 指標 | 值 |\n|------|----|\n` +
        Object.entries(kpi)
          .map(([k, v]) => `| ${k} | ${v} |`)
          .join('\n')
      : '（無）';

    const groupBlock = (group_analysis || [])
      .map((g) => `- ${g.group}：勝率 ${g.win_rate ?? '—'}，平均報酬 ${g.avg_return ?? '—'}`)
      .join('\n') || '（無）';

    const indivBlock = (individual_review || [])
      .map(
        (r) =>
          `| ${r.code} ${r.name ?? ''} | ${r.decision ?? ''} | ${r.entry ?? ''} | ${r.exit ?? ''} | ${r.return ?? ''} | ${r.note ?? ''} |`,
      )
      .join('\n');
    const indivTable = individual_review?.length
      ? `| 股票 | 決策 | 進場 | 出場 | 報酬 | 備註 |\n|------|------|------|------|------|------|\n${indivBlock}`
      : '（無個股資料）';

    return `## 交易檢討（${period ?? ''}）

### KPI
${kpiBlock}

### 分群分析
${groupBlock}

### 個股逐支檢討
${indivTable}

---
請以上半月檢討表深入分析我的交易盲點，給出 3 個具體改進建議。`;
  }

  function formatIndustry(data) {
    const { industry_name, fund_inflow, top_stocks, trigger_events } = data;
    const stocksBlock = (top_stocks || [])
      .map(
        (s, i) =>
          `${i + 1}. **${s.code} ${s.name}**${s.reason ? '：' + s.reason : ''}`,
      )
      .join('\n');
    const eventsBlock = (trigger_events || []).map((e) => `- ${e}`).join('\n');

    return `## 產業深問：${industry_name ?? ''}

- 資金流入：${fund_inflow ?? '—'}

### 重點個股
${stocksBlock || '（無）'}

### 觸發事件
${eventsBlock || '（無）'}

---
請以上資料判斷此產業現處輪動週期哪一階段，未來 1-3 個月可能上漲的個股。`;
  }

  function formatAlert(data) {
    const { code, name, alert_type, trigger_value, current_price } = data;
    const alertLabels = {
      volume_spike: '成交量暴增',
      breakout: '突破關鍵價位',
      inst_buy_streak: '法人連續買超',
      news: '重大新聞',
      target_hit: '觸達目標價',
      stop_loss_hit: '觸達停損價',
    };
    const label = alertLabels[alert_type] ?? alert_type;

    return `## 警示深問：${code} ${name}

### 警示資訊
- 類型：${label}
- 觸發值：${trigger_value ?? '—'}
- 當前價：${current_price ?? '—'}

---
請判斷此 alert 訊號是否值得進場/加碼/減碼，以及進場後該設的停損點。`;
  }

  // ─── Template dispatch ────────────────────────────────────────────────────

  const FORMATTERS = {
    'stock-pick':     formatStockPick,
    'deep-analysis':  formatDeepAnalysis,
    'briefing':       formatBriefing,
    'review':         formatReview,
    'industry':       formatIndustry,
    'alert':          formatAlert,
  };

  function buildMarkdown(template, data) {
    const fn = FORMATTERS[template];
    if (!fn) return `（未知 template：${template}）`;
    try {
      return fn(data || {});
    } catch (e) {
      return `（格式化失敗：${e.message}）`;
    }
  }

  // ─── Clipboard helpers ────────────────────────────────────────────────────

  async function copyToClipboard(text) {
    // 優先使用 Clipboard API（需 HTTPS）
    if (navigator.clipboard && navigator.clipboard.writeText) {
      await navigator.clipboard.writeText(text);
      return;
    }
    // Fallback：textarea + execCommand
    const ta = document.createElement('textarea');
    ta.value = text;
    ta.style.cssText = 'position:fixed;top:-9999px;left:-9999px;opacity:0';
    document.body.appendChild(ta);
    ta.focus();
    ta.select();
    const ok = document.execCommand('copy');
    document.body.removeChild(ta);
    if (!ok) {
      // 最後手段：alert 讓使用者手動複製
      window.alert('自動複製失敗，請手動複製以下內容：\n\n' + text);
      throw new Error('execCommand copy failed');
    }
  }

  // ─── Icon ─────────────────────────────────────────────────────────────────

  function ClipboardIcon({ size = 13 }) {
    return (
      <svg
        width={size}
        height={size}
        viewBox="0 0 16 16"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.5"
        strokeLinecap="round"
        strokeLinejoin="round"
        style={{ display: 'block', flexShrink: 0 }}
        aria-hidden="true"
      >
        <rect x="5" y="2" width="9" height="12" rx="1.5" />
        <path d="M5 4H3.5A1.5 1.5 0 002 5.5v8A1.5 1.5 0 003.5 15H10a1.5 1.5 0 001.5-1.5V13" />
      </svg>
    );
  }

  function CheckIcon({ size = 13 }) {
    return (
      <svg
        width={size}
        height={size}
        viewBox="0 0 16 16"
        fill="none"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
        style={{ display: 'block', flexShrink: 0 }}
        aria-hidden="true"
      >
        <polyline points="3 8 6.5 12 13 4" />
      </svg>
    );
  }

  // ─── DeepPromptButton ─────────────────────────────────────────────────────

  function DeepPromptButton({
    template,
    data,
    buttonText = '複製深問提示',
    variant = 'ghost',
    size = 'sm',
    className,
  }) {
    const [copied, setCopied] = React.useState(false);
    const [busy, setBusy] = React.useState(false);
    const timerRef = React.useRef(null);

    React.useEffect(() => {
      return () => { if (timerRef.current) clearTimeout(timerRef.current); };
    }, []);

    async function handleClick() {
      if (busy) return;
      setBusy(true);
      try {
        const md = buildMarkdown(template, data);
        await copyToClipboard(md);
        setCopied(true);
        timerRef.current = setTimeout(() => {
          setCopied(false);
          setBusy(false);
        }, 2000);
      } catch {
        // alert 已在 copyToClipboard 裡顯示，這裡只需恢復狀態
        setBusy(false);
      }
    }

    // ── 尺寸 & 變體 ──
    const sizes = {
      sm: { fs: 13, py: 6, px: 12, gap: 5 },
      md: { fs: 14, py: 8, px: 14, gap: 6 },
    };
    const s = sizes[size] || sizes.sm;

    const variants = {
      primary: {
        bg:       T ? T.text : '#1a1a2e',
        color:    'white',
        border:   'transparent',
        hoverBg:  T ? 'oklch(0.30 0.01 250)' : '#2a2a3e',
      },
      ghost: {
        bg:       'transparent',
        color:    T ? T.text3 : '#888',
        border:   T ? T.border : '#ddd',
        hoverBg:  T ? T.hover : '#f5f5f5',
        hoverColor: T ? T.primary : '#3355cc',
      },
    };
    const v = variants[variant] || variants.ghost;

    // 成功態：暫時覆寫顏色
    const successColor   = T ? T.down : '#22863a';   // 台股「綠」 = 跌 = oklab 綠
    const successBg      = T ? T.downSoft : '#e6ffed';
    const successBorder  = T ? 'oklch(0.78 0.10 155)' : '#a2d9b1';

    const isSuccess = copied && !busy;

    const btnStyle = {
      display:        'inline-flex',
      alignItems:     'center',
      gap:            s.gap,
      fontFamily:     T ? T.fontSans : 'system-ui, sans-serif',
      fontSize:       s.fs,
      fontWeight:     500,
      lineHeight:     1,
      padding:        `${s.py}px ${s.px}px`,
      background:     isSuccess ? successBg : v.bg,
      color:          isSuccess ? successColor : v.color,
      border:         `1px solid ${isSuccess ? successBorder : v.border}`,
      borderRadius:   T ? T.radiusSm : 4,
      cursor:         busy ? 'wait' : 'pointer',
      opacity:        1,
      transition:     'background 0.15s, color 0.15s, border-color 0.15s, transform 0.08s',
      userSelect:     'none',
      whiteSpace:     'nowrap',
      outline:        'none',
    };

    // hover 用 CSS var trick — inline style 沒 :hover，用 onMouse* 模擬
    const [hovered, setHovered] = React.useState(false);
    if (hovered && !isSuccess && !busy && variant === 'ghost') {
      btnStyle.background   = v.hoverBg;
      btnStyle.color        = v.hoverColor;
      btnStyle.borderColor  = T ? T.borderStrong : '#bbb';
    }

    const icon = isSuccess
      ? <CheckIcon size={s.fs} />
      : <ClipboardIcon size={s.fs} />;

    const label = isSuccess ? '已複製 ✓' : buttonText;

    return (
      <button
        type="button"
        style={btnStyle}
        className={className}
        onClick={handleClick}
        disabled={busy && !copied}
        title={`複製「${template}」深問提示到剪貼簿`}
        aria-label={label}
        onMouseEnter={() => setHovered(true)}
        onMouseLeave={() => setHovered(false)}
        onMouseDown={(e) => { e.currentTarget.style.transform = 'scale(0.97)'; }}
        onMouseUp={(e)   => { e.currentTarget.style.transform = ''; }}
      >
        {icon}
        {label}
      </button>
    );
  }

  window.DeepPromptButton = DeepPromptButton;

})();
