"use client";

import { useEffect, useId, useRef, useState } from "react";
import {
  ChevronDown,
  HelpCircle,
  PenLine,
  RefreshCw,
  Sparkles,
  Square,
  Wand2,
  WrapText,
} from "lucide-react";

import { Button } from "@/components/ui/Button";
import { Eyebrow } from "@/components/ui/Eyebrow";
import { SectionHeader } from "@/components/ui/SectionHeader";
import { StatusNote } from "@/components/ui/StatusNote";
import { TextArea } from "@/components/ui/TextArea";
import { PLOT_PRESETS, STYLE_PRESETS, type Preset } from "@/lib/workbench/directive";
import { buttonClass, focusRing } from "@/lib/ui/variants";

interface DirectivePanelProps {
  directive: string;
  onDirectiveChange: (value: string) => void;
  presetIds: readonly string[];
  onTogglePreset: (id: string) => void;
  // 空章默认展开（新手最需要看到输入框的时机）；满章默认收起以让出编辑视野。
  defaultOpen: boolean;
  // 发送键 = 写本章：把已选文风/剧情 + 自定义要求组装后逐字流式写进正文（不改成聊天气泡）。
  streaming: boolean;
  onWrite: () => void;
  onStop: () => void;
}

// 本章写作指令面板（P0-2 / P3-3 提升）：正文正上方常驻的「和 AI 说话」输入条。
// 眉题「和 AI 说话」+ 主标题「告诉 AI 这章想怎么写」+ HITL 微文案 +「?这是什么」常驻可见；
// 主 CTA「写本章」突出（md 尺寸、独占右侧），空章默认展开露出输入框。
// 发送键即「写本章」，沿用 composeDirective + 文风/剧情 chips + 流式打字机写进正文。
export function DirectivePanel({
  directive,
  onDirectiveChange,
  presetIds,
  onTogglePreset,
  defaultOpen,
  streaming,
  onWrite,
  onStop,
}: DirectivePanelProps) {
  const panelId = useId();
  const [open, setOpen] = useState(defaultOpen);
  const activeCount = presetIds.length + (directive.trim().length > 0 ? 1 : 0);
  return (
    <section className="border-b border-line bg-panel px-4 py-4 sm:px-6">
      <div className="flex items-start justify-between gap-4">
        <div className="min-w-0">
          <Eyebrow className="mb-1">和 AI 说话</Eyebrow>
          <button
            type="button"
            onClick={() => setOpen((v) => !v)}
            aria-expanded={open}
            aria-controls={panelId}
            className={`group flex min-w-0 cursor-pointer items-center gap-2 rounded text-left font-serif text-title-md text-ink transition-colors duration-fast ease-standard hover:text-cinnabar ${focusRing}`}
          >
            <ChevronDown
              className={`h-4 w-4 shrink-0 text-muted-soft transition-transform duration-fast ease-standard group-hover:text-cinnabar ${
                open ? "rotate-180" : ""
              }`}
              aria-hidden="true"
            />
            <span className="truncate">告诉 AI 这章想怎么写</span>
          </button>
        </div>
        <div className="flex shrink-0 items-center gap-2">
          {activeCount > 0 ? (
            <span className="hidden rounded-full border border-line bg-bg px-2.5 py-0.5 text-2xs text-ink-soft sm:inline">
              {activeCount} 项指令
            </span>
          ) : null}
          {/* 常驻主 CTA = 写本章：始终可见（折叠时也在），md 尺寸凸显为本条主动作，逐字流式写进正文。 */}
          {streaming ? (
            <Button onClick={onStop} variant="danger" size="md">
              <Square className="h-4 w-4" aria-hidden="true" />
              停
            </Button>
          ) : (
            <Button onClick={onWrite} variant="primary" size="md">
              <PenLine className="h-4 w-4" aria-hidden="true" />
              写本章
              <span className="text-2xs font-normal text-panel/75">
                整章·从头写
              </span>
            </Button>
          )}
          <HitlHelp />
        </div>
      </div>
      <p className="mt-2 text-caption text-muted-soft">
        AI 给草稿，你决定采不采用，原文永远你说了算。
      </p>
      {open ? (
        <div id={panelId} className="mt-4 space-y-4">
          <SectionHeader
            title="你的写作要求"
            description="选文风、点剧情需求、写自己的要求，只影响本次生成。"
          />
          <PresetGroup
            label="文风"
            presets={STYLE_PRESETS}
            presetIds={presetIds}
            onToggle={onTogglePreset}
          />
          <PresetGroup
            label="剧情需求"
            presets={PLOT_PRESETS}
            presetIds={presetIds}
            onToggle={onTogglePreset}
          />
          <label className="block">
            <span className="mb-1 block text-sm text-ink-soft">自己的要求</span>
            <TextArea
              value={directive}
              onChange={(e) => onDirectiveChange(e.target.value)}
              rows={2}
              placeholder="写点要求，AI 更懂你（留空则按大纲写）"
            />
          </label>
          {activeCount > 0 ? (
            <StatusNote variant="info">
              写本章时会把已选文风/剧情预设和你的要求合并进本次生成请求。
            </StatusNote>
          ) : null}
        </div>
      ) : null}
    </section>
  );
}

interface AiVerbsRowProps {
  streaming: boolean;
  onContinue: () => void;
  onRefineSelection: () => void;
  onRewrite: () => void;
  onToolbox: () => void;
}

// 「或让 AI:」次级动作行（P1-1 / P3-3）：常驻贴在中央输入条下方，把续写/润色/整章重写/工具箱
// 归为「同一个 AI 的其它用法」（act-on-chapter 与导航分家）。用较浅面色 + 更软分隔成组，
// 与上方主指令条拉开层级。每个动词带可见范围提示（P1-4）。生成中禁用（避免与流式写章并发）。
export function AiVerbsRow({
  streaming,
  onContinue,
  onRefineSelection,
  onRewrite,
  onToolbox,
}: AiVerbsRowProps) {
  return (
    <div className="flex flex-wrap items-center gap-x-3 gap-y-2 border-b border-line-soft bg-surface-soft px-4 py-2.5 sm:px-6">
      <span className="text-eyebrow uppercase tracking-wide text-muted-soft">
        或让 AI
      </span>
      <VerbButton
        icon={WrapText}
        label="续写"
        hint="接着往下写"
        disabled={streaming}
        onClick={onContinue}
      />
      <VerbButton
        icon={Wand2}
        label="润色选段"
        hint="选中段·打磨"
        disabled={streaming}
        onClick={onRefineSelection}
      />
      <VerbButton
        icon={RefreshCw}
        label="整章重写"
        hint="整章·基于现有重写"
        disabled={streaming}
        onClick={onRewrite}
      />
      <VerbButton
        icon={Sparkles}
        label="工具箱"
        disabled={streaming}
        onClick={onToolbox}
      />
    </div>
  );
}

interface VerbButtonProps {
  icon: typeof WrapText;
  label: string;
  // 可见（非 hover-only）范围提示：让作者点前就能预判对草稿的影响（P1-4）。工具箱无范围提示。
  hint?: string;
  disabled: boolean;
  onClick: () => void;
}

function VerbButton({ icon: Icon, label, hint, disabled, onClick }: VerbButtonProps) {
  return (
    <Button onClick={onClick} disabled={disabled} variant="secondary" size="sm">
      <Icon className="h-4 w-4" aria-hidden="true" />
      {label}
      {hint ? <span className="text-2xs text-ink-soft">{hint}</span> : null}
    </Button>
  );
}

// 「?这是什么」：常驻、可再发现的说明（非一次性 coach）——解释「和 AI 说话」的闭环。
// 按钮 + 轻量弹层，Esc / 点击外部关闭，还原焦点。
function HitlHelp() {
  const [open, setOpen] = useState(false);
  const popId = useId();
  const rootRef = useRef<HTMLDivElement>(null);
  const buttonRef = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    if (!open) return;
    const onKeyDown = (e: KeyboardEvent): void => {
      if (e.key === "Escape") {
        setOpen(false);
        buttonRef.current?.focus();
      }
    };
    const onPointerDown = (e: PointerEvent): void => {
      const target = e.target;
      if (target instanceof Node && !rootRef.current?.contains(target)) {
        setOpen(false);
      }
    };
    window.addEventListener("keydown", onKeyDown);
    window.addEventListener("pointerdown", onPointerDown);
    return () => {
      window.removeEventListener("keydown", onKeyDown);
      window.removeEventListener("pointerdown", onPointerDown);
    };
  }, [open]);

  return (
    <div ref={rootRef} className="relative">
      <button
        ref={buttonRef}
        type="button"
        aria-haspopup="dialog"
        aria-expanded={open}
        aria-controls={popId}
        onClick={() => setOpen((v) => !v)}
        className={buttonClass({
          variant: "ghost",
          size: "sm",
          className: "gap-1 text-xs text-ink-soft",
        })}
      >
        <HelpCircle className="h-4 w-4" aria-hidden="true" />
        这是什么
      </button>
      {open ? (
        <div
          id={popId}
          role="dialog"
          aria-label="怎么和 AI 说话"
          className="absolute right-0 z-30 mt-2 w-72 max-w-[80vw] rounded-lg border border-line bg-panel p-4 text-sm text-ink-soft shadow-paper"
        >
          <p className="mb-1 font-serif text-title-md text-ink">怎么和 AI 说话</p>
          <p className="leading-6">
            在这条写下要求，点「写本章」——AI 会把草稿逐字写进正文。草稿随时能改；
            满意了去「审稿」验收。原文永远你说了算。
          </p>
        </div>
      ) : null}
    </div>
  );
}

interface PresetGroupProps {
  label: string;
  presets: readonly Preset[];
  presetIds: readonly string[];
  onToggle: (id: string) => void;
}

// 一组预设 chips（文风 / 剧情需求）：点选 toggle，选中高亮。id 统一进 presetIds。
function PresetGroup({ label, presets, presetIds, onToggle }: PresetGroupProps) {
  return (
    <div>
      <p className="mb-1 text-sm text-ink-soft">{label}</p>
      <div className="flex flex-wrap gap-2" role="group" aria-label={label}>
        {presets.map((preset) => {
          const active = presetIds.includes(preset.id);
          return (
            <Button
              key={preset.id}
              type="button"
              aria-pressed={active}
              onClick={() => onToggle(preset.id)}
              variant={active ? "outline" : "secondary"}
              size="sm"
            >
              {preset.label}
            </Button>
          );
        })}
      </div>
    </div>
  );
}
