'use client';

import { useState } from 'react';
import { Check, Copy } from 'lucide-react';
import { plansApi } from '@/components/plans/plans-api';
import { cn } from '@/lib/utils';

/**
 * 企微话术视图 —— **一整块可直接复制发送的消息**。
 *
 * ⚠️ 步骤时间线(ScriptDeepProcess)由**外层统一渲染**(电话/企微共用那一处),
 *   ⛔ 本组件里不要再画一遍 —— 实测重复渲染成了两组一模一样的「规划大纲/撰写话术/安全自检」。
 *
 * ⚠️ 与电话稿的三个视图(伴飞/卡片/原文)不是同一套东西:那三个是"同一份分段稿的不同看法";
 *   这里根本没有段,它就是一条消息。所以⛔ 不复用 `ScriptView`。
 *
 * ⛔ **本组件不提供生成按钮** —— 生成走顶栏那一个入口(与电话稿同一个)。
 *   两个"生成"按钮意味着两条路径、两套状态,而它们必然会不一致
 *   (点了这个转圈、点了那个也转圈,而流只有一条)。
 *
 * ⚠️ **失败态如实显示**,⛔ 不回落去显示电话稿 —— 电话稿是口语分段的,
 *   复制发给患者会很怪,而客服不会注意到自己发错了东西。
 */
export function WecomScriptView({
  planId,
  script,
  streamedContent,
  streaming,
}: {
  planId: string;
  /** 存量稿(聚合响应);只要 content + status */
  script: { content: string | null; status: string } | null;
  /** 本次流式产出的正文(流中/刚完成时优先用它) */
  streamedContent: string;
  streaming: boolean;
}) {
  const [copied, setCopied] = useState(false);

  const stored = script?.status === 'ready' ? (script.content ?? '') : '';
  const content = streamedContent || stored;
  const failed = !streaming && !content && script?.status === 'failed';

  /**
   * 写剪贴板 —— 两条路,⛔ 别只用 `navigator.clipboard`。
   *
   * 🔴 实测:PAC 跑在 `http://` 或**嵌在宿主 iframe** 里时,`clipboard.writeText`
   *   直接 `NotAllowedError`。原来的写法把 `setCopied` 也放在它后面,于是复制按钮
   *   **点了毫无反应**(不报错、不变文案)—— 客服会以为按钮坏了,而这正是企微稿的主路径。
   * ⇒ 失败回落到 `execCommand('copy')`(老 API,http/iframe 下仍可用)。
   */
  const writeClipboard = async (text: string): Promise<boolean> => {
    try {
      await navigator.clipboard.writeText(text);
      return true;
    } catch {
      /* 落到下面的回落路径 */
    }
    try {
      const ta = document.createElement('textarea');
      ta.value = text;
      // 移出视口 + readOnly:避免闪一下输入框、避免移动端弹键盘
      ta.style.cssText = 'position:fixed;left:-9999px;top:0;opacity:0';
      ta.readOnly = true;
      document.body.appendChild(ta);
      ta.select();
      ta.setSelectionRange(0, text.length);
      const ok = document.execCommand('copy');
      document.body.removeChild(ta);
      return ok;
    } catch {
      return false;
    }
  };

  const copy = async () => {
    if (!content) return;
    /**
     * ⭐ 埋点在**最前面**,与剪贴板成没成功**解耦**。
     *
     * 记的是「客服点了复制」这个**意图** —— 复制 = 我们能观测到的最接近"真的用了"
     * 的信号(复制完他就离开 PAC 去发微信了;生成完没人点 = 生成了但没人用)。
     * ⛔ 别挪到 `writeClipboard` 成功之后:剪贴板在 http/iframe 下会被拒,
     *   而那时客服往往改成手动选中复制 —— 真的用了,我们却一条都没记到。
     * ⚠️ **不 await、失败静默**:埋点是旁路,不能拖慢或打断复制这个动作。
     */
    void plansApi.reportScriptCopy(planId, 'wecom').catch(() => {});

    const ok = await writeClipboard(content);
    if (!ok) return; // 两条路都失败 → 保持原样,客服可以手动选中复制
    setCopied(true);
    // 2 秒后复原 —— ⛔ 不弹 toast:复制是高频动作,每次弹一条是噪音,
    //   按钮本身变成「已复制」已经是足够的反馈。
    setTimeout(() => setCopied(false), 2000);
  };

  return (
    <div className="flex h-full flex-col gap-2">
      {content ? (
        <>
          <div className="flex flex-none items-center justify-end">
            <button
              type="button"
              onClick={copy}
              disabled={streaming}
              className={cn(
                'inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-[11px] font-medium transition-colors disabled:opacity-50',
                copied ? 'bg-emerald-50 text-emerald-700' : 'bg-brand-600 text-white hover:bg-brand-700',
              )}
            >
              {copied ? <Check className="h-3 w-3" /> : <Copy className="h-3 w-3" />}
              {copied ? '已复制' : '复制'}
            </button>
          </div>
          {/*
            ⚠️ 用 `whitespace-pre-wrap` 原样呈现,⛔ 不过 markdown 渲染器:
            客服复制的必须是**他看到的那些字**。经 markdown 渲染后 `**加粗**` 之类会变成样式,
            复制出来却带着星号发给患者 —— 所见与所复制不一致,而他不会逐字校对。
          */}
          <div className="min-h-0 flex-1 overflow-y-auto rounded-md bg-slate-50/70 p-3">
            <p className="whitespace-pre-wrap text-[13px] leading-relaxed text-slate-800">{content}</p>
          </div>
        </>
      ) : (
        !streaming && (
          <div className="flex h-full min-h-[160px] flex-col items-center justify-center gap-2 text-center text-slate-400">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="h-8 w-8">
              <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" />
            </svg>
            <p className="text-[13px] text-slate-500">{failed ? '企微话术生成失败' : '尚未生成企微话术'}</p>
            <p className="text-[12px] text-slate-400">
              {failed ? '可以重试,或这次自己写一条' : '点击右上角「重新生成」按本患者生成'}
            </p>
          </div>
        )
      )}
    </div>
  );
}
