import { useCallback, useEffect, useRef, useState, type CSSProperties, type MouseEvent as ReactMouseEvent, type TouchEvent as ReactTouchEvent } from "react";
import { ApartmentOutlined, DownOutlined, RobotOutlined, ThunderboltOutlined } from "@ant-design/icons";
import "../../styles/pages/dialog-generator.css";

type DialogStyle = "style1" | "style2" | "style3" | "style4";
type GenerationMode = "dialog" | "video";

interface DialogItem {
  id: number;
  style: DialogStyle;
  x: number;
  y: number;
  text: string;
  color: string;
  confirmed: boolean;
}

interface DragState {
  id: number;
  offsetX: number;
  offsetY: number;
}

const dialogStyles: Array<{
  key: DialogStyle;
  label: string;
  description: string;
  swatchClass: string;
}> = [
  { key: "style1", label: "白色圆角对话框", description: "适合浅色说明与标注", swatchClass: "is-white" },
  { key: "style2", label: "蓝色气泡对话框", description: "适合角色台词与重点提示", swatchClass: "is-blue" },
  { key: "style3", label: "黄色提示对话框", description: "适合醒目提醒与强调", swatchClass: "is-amber" },
  { key: "style4", label: "灰色简约对话框", description: "适合信息备注与辅助说明", swatchClass: "is-gray" },
];

const textColorOptions = [
  { value: "#ffffff", label: "白色" },
  { value: "#111827", label: "黑色" },
  { value: "#ef4444", label: "红色" },
  { value: "#f59e0b", label: "黄色" },
  { value: "#165dff", label: "蓝色" },
  { value: "#00ff88", label: "绿色" },
];

const dialogModelOptions = [
  { id: "gemini", label: "Gemini" },
  { id: "wanxian", label: "万相" },
  { id: "deepseek", label: "DeepSeek" },
];

const thinkingSpeedOptions = [
  { id: "default", label: "默认" },
  { id: "high", label: "高" },
  { id: "ultra", label: "急速" },
];

const thinkingDepthOptions = [
  { id: "default", label: "默认" },
  { id: "strong", label: "强" },
  { id: "extreme", label: "极限" },
];

const videoDurationOptions = [
  { value: "5", label: "5s" },
  { value: "6", label: "6s" },
  { value: "7", label: "7s" },
  { value: "8", label: "8s" },
  { value: "9", label: "9s" },
  { value: "10", label: "10s" },
  { value: "11", label: "11s" },
  { value: "12", label: "12s" },
  { value: "13", label: "13s" },
  { value: "14", label: "14s" },
  { value: "15", label: "15s" },
];

function DialogGeneratorPage() {
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const previewRef = useRef<HTMLDivElement | null>(null);
  const dragRef = useRef<DragState | null>(null);
  const nextIdRef = useRef(0);
  const controlsRef = useRef<HTMLDivElement>(null);
  const [backgroundUrl, setBackgroundUrl] = useState("");
  const [dialogs, setDialogs] = useState<DialogItem[]>([]);
  const [selectedTextColor, setSelectedTextColor] = useState(textColorOptions[0].value);
  const [activeDragId, setActiveDragId] = useState<number | null>(null);

  // ── Generation state ──
  const [generationMode, setGenerationMode] = useState<GenerationMode>("dialog");
  const [dialogModel, setDialogModel] = useState(dialogModelOptions[0].id);
  const [thinkingSpeed, setThinkingSpeed] = useState(thinkingSpeedOptions[0].id);
  const [thinkingDepth, setThinkingDepth] = useState(thinkingDepthOptions[0].id);
  const [videoDuration, setVideoDuration] = useState(videoDurationOptions[0].value);
  const [activeDropdown, setActiveDropdown] = useState<string | null>(null);
  const [isGenerating, setIsGenerating] = useState(false);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (controlsRef.current && !controlsRef.current.contains(event.target as Node)) {
        setActiveDropdown(null);
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  const handleFile = useCallback((file?: File | null) => {
    if (!file || !file.type.startsWith("image/")) return;
    const reader = new FileReader();
    reader.onload = () => {
      if (typeof reader.result === "string") {
        setBackgroundUrl(reader.result);
      }
    };
    reader.readAsDataURL(file);
  }, []);

  const addDialog = useCallback((style: DialogStyle) => {
    nextIdRef.current += 1;
    const id = nextIdRef.current;
    setDialogs((current) => [
      ...current,
      {
        id,
        style,
        x: 30 + (id * 25) % 200,
        y: 30 + (id * 20) % 150,
        text: "",
        color: selectedTextColor,
        confirmed: false,
      },
    ]);
  }, [selectedTextColor]);

  const updateDialog = useCallback((id: number, patch: Partial<DialogItem>) => {
    setDialogs((current) => current.map((item) => (item.id === id ? { ...item, ...patch } : item)));
  }, []);

  const deleteDialog = useCallback((id: number) => {
    setDialogs((current) => current.filter((item) => item.id !== id));
  }, []);

  const startDrag = useCallback((id: number, clientX: number, clientY: number) => {
    const dialogEl = document.querySelector<HTMLElement>(`[data-dialog-id="${id}"]`);
    if (!dialogEl) return;
    const rect = dialogEl.getBoundingClientRect();
    dragRef.current = {
      id,
      offsetX: clientX - rect.left,
      offsetY: clientY - rect.top,
    };
    setActiveDragId(id);
  }, []);

  const moveDrag = useCallback((clientX: number, clientY: number) => {
    const drag = dragRef.current;
    const preview = previewRef.current;
    if (!drag || !preview) return;
    const dialogEl = document.querySelector<HTMLElement>(`[data-dialog-id="${drag.id}"]`);
    if (!dialogEl) return;

    const bounds = preview.getBoundingClientRect();
    const nextX = Math.max(0, Math.min(clientX - drag.offsetX - bounds.left, bounds.width - dialogEl.offsetWidth));
    const nextY = Math.max(0, Math.min(clientY - drag.offsetY - bounds.top, bounds.height - dialogEl.offsetHeight));
    updateDialog(drag.id, { x: nextX, y: nextY });
  }, [updateDialog]);

  const endDrag = useCallback(() => {
    dragRef.current = null;
    setActiveDragId(null);
  }, []);

  const handleCanvasMouseMove = useCallback((event: ReactMouseEvent<HTMLDivElement>) => {
    moveDrag(event.clientX, event.clientY);
  }, [moveDrag]);

  const handleCanvasTouchMove = useCallback((event: ReactTouchEvent<HTMLDivElement>) => {
    const touch = event.touches[0];
    if (!touch) return;
    moveDrag(touch.clientX, touch.clientY);
  }, [moveDrag]);

  return (
    <section className="dialog-generator-page page-motion">
      <div className="dialog-generator-shell">
        <aside className="dialog-generator-panel">
          <div className="dialog-generator-heading">
            <span className="dialog-generator-kicker">Interactive Dialog</span>
            <h1>交互式对话框生成器</h1>
            <p>上传背景图，在画面上添加可拖拽、可编辑的文字图层，用于图片标注、剧情分镜和互动内容设计。</p>
          </div>

          <div className="dialog-generator-section">
            <h2>上传背景图片</h2>
            <button
              type="button"
              className="dialog-generator-drop"
              onClick={() => fileInputRef.current?.click()}
              onDragOver={(event) => {
                event.preventDefault();
              }}
              onDrop={(event) => {
                event.preventDefault();
                handleFile(event.dataTransfer.files[0]);
              }}
            >
              <span className="dialog-generator-drop-icon">🖼</span>
              <strong>点击或拖拽图片到此处</strong>
              <small>支持 JPG、PNG、WEBP 格式</small>
            </button>
            <input
              ref={fileInputRef}
              type="file"
              accept="image/*"
              hidden
              onChange={(event) => handleFile(event.target.files?.[0])}
            />
          </div>

          <div className="dialog-generator-section">
            <h2>点击添加文字</h2>
            <p className="dialog-generator-hint">每点一次即在预览区新增一个可编辑文字图层。</p>
            <div className="dialog-generator-color-picker" role="radiogroup" aria-label="文字颜色">
              {textColorOptions.map((item) => (
                <button
                  key={item.value}
                  type="button"
                  className={`dialog-generator-color${selectedTextColor === item.value ? " is-active" : ""}`}
                  style={{ "--text-color": item.value } as CSSProperties}
                  aria-checked={selectedTextColor === item.value}
                  role="radio"
                  onClick={() => setSelectedTextColor(item.value)}
                >
                  <span />
                  <strong>{item.label}</strong>
                </button>
              ))}
            </div>
            <div className="dialog-generator-style-list">
              {dialogStyles.map((item) => (
                <button key={item.key} type="button" className="dialog-generator-style" onClick={() => addDialog(item.key)}>
                  <span className={`dialog-generator-swatch ${item.swatchClass}`} />
                  <span>
                    <strong>{item.label}</strong>
                    <small>{item.description}</small>
                  </span>
                </button>
              ))}
            </div>
          </div>

          <div className="dialog-generator-section">
            <h2>生成设置</h2>
            <div className="dialog-generator-mode-switch" role="radiogroup" aria-label="生成模式">
              <button
                type="button"
                className={`dialog-generator-mode${generationMode === "dialog" ? " is-active" : ""}`}
                role="radio"
                aria-checked={generationMode === "dialog"}
                onClick={() => setGenerationMode("dialog")}
              >
                对话模式
              </button>
              <button
                type="button"
                className={`dialog-generator-mode${generationMode === "video" ? " is-active" : ""}`}
                role="radio"
                aria-checked={generationMode === "video"}
                onClick={() => setGenerationMode("video")}
              >
                视频模式
              </button>
            </div>

            <div className="dialog-generator-controls" ref={controlsRef}>
              {generationMode === "dialog" ? (
                <>
                  <div className="dialog-generator-pills">
                    <button
                      type="button"
                      className={`dialog-generator-pill${activeDropdown === "model" ? " is-open" : ""}`}
                      onClick={() => setActiveDropdown(activeDropdown === "model" ? null : "model")}
                    >
                      <RobotOutlined />
                      {dialogModelOptions.find((m) => m.id === dialogModel)?.label ?? "模型选择"}
                      <DownOutlined />
                    </button>
                    {activeDropdown === "model" && (
                      <div className="dialog-generator-dropdown">
                        {dialogModelOptions.map((m) => (
                          <button
                            key={m.id}
                            type="button"
                            className={`dialog-generator-dropdown__item${dialogModel === m.id ? " is-active" : ""}`}
                            onClick={() => { setDialogModel(m.id); setActiveDropdown(null); }}
                          >
                            {m.label}
                          </button>
                        ))}
                      </div>
                    )}
                  </div>
                  <div className="dialog-generator-pills">
                    <button
                      type="button"
                      className={`dialog-generator-pill${activeDropdown === "speed" ? " is-open" : ""}`}
                      onClick={() => setActiveDropdown(activeDropdown === "speed" ? null : "speed")}
                    >
                      <ThunderboltOutlined />
                      {thinkingSpeedOptions.find((s) => s.id === thinkingSpeed)?.label ?? "思考速度"}
                      <DownOutlined />
                    </button>
                    {activeDropdown === "speed" && (
                      <div className="dialog-generator-dropdown">
                        {thinkingSpeedOptions.map((s) => (
                          <button
                            key={s.id}
                            type="button"
                            className={`dialog-generator-dropdown__item${thinkingSpeed === s.id ? " is-active" : ""}`}
                            onClick={() => { setThinkingSpeed(s.id); setActiveDropdown(null); }}
                          >
                            {s.label}
                          </button>
                        ))}
                      </div>
                    )}
                  </div>
                  <div className="dialog-generator-pills">
                    <button
                      type="button"
                      className={`dialog-generator-pill${activeDropdown === "depth" ? " is-open" : ""}`}
                      onClick={() => setActiveDropdown(activeDropdown === "depth" ? null : "depth")}
                    >
                      <ApartmentOutlined />
                      {thinkingDepthOptions.find((d) => d.id === thinkingDepth)?.label ?? "思考深度"}
                      <DownOutlined />
                    </button>
                    {activeDropdown === "depth" && (
                      <div className="dialog-generator-dropdown">
                        {thinkingDepthOptions.map((d) => (
                          <button
                            key={d.id}
                            type="button"
                            className={`dialog-generator-dropdown__item${thinkingDepth === d.id ? " is-active" : ""}`}
                            onClick={() => { setThinkingDepth(d.id); setActiveDropdown(null); }}
                          >
                            {d.label}
                          </button>
                        ))}
                      </div>
                    )}
                  </div>
                </>
              ) : (
                <div className="dialog-generator-duration">
                  <span className="dialog-generator-duration__label">视频时长</span>
                  <div className="dialog-generator-duration__options">
                    {videoDurationOptions.map((opt) => (
                      <button
                        key={opt.value}
                        type="button"
                        className={`dialog-generator-duration__btn${videoDuration === opt.value ? " is-active" : ""}`}
                        onClick={() => setVideoDuration(opt.value)}
                      >
                        {opt.label}
                      </button>
                    ))}
                  </div>
                </div>
              )}
            </div>

            <button
              type="button"
              className="dialog-generator-run"
              disabled={isGenerating}
              onClick={() => {
                setIsGenerating(true);
                // TODO: wire to actual generation API
                setTimeout(() => setIsGenerating(false), 2000);
              }}
            >
              {isGenerating ? "生成中..." : "生成"}
            </button>
          </div>

          <button type="button" className="dialog-generator-clear" onClick={() => setDialogs([])}>
            清空全部文字
          </button>
        </aside>

        <main className="dialog-generator-preview-card">
          <div className="dialog-generator-preview-head">
            <div>
              <span>Preview</span>
              <h2>预览区域</h2>
            </div>
            <p>拖动文字定位，输入文字后点击确认，确认后只保留文字图层，双击可重新编辑。</p>
          </div>

          <div
            ref={previewRef}
            className="dialog-generator-preview"
            onMouseMove={handleCanvasMouseMove}
            onMouseUp={endDrag}
            onMouseLeave={endDrag}
            onTouchMove={handleCanvasTouchMove}
            onTouchEnd={endDrag}
          >
            {backgroundUrl ? <div className="dialog-generator-image" style={{ backgroundImage: `url(${backgroundUrl})` }} /> : null}
            {!backgroundUrl ? (
              <div className="dialog-generator-empty">
                <span>🖼</span>
                <p>上传图片后开始编辑</p>
              </div>
            ) : null}

            {dialogs.map((dialog) => (
              <div
                key={dialog.id}
                data-dialog-id={dialog.id}
                className={`dialog-generator-bubble ${dialog.style}${dialog.confirmed ? " is-confirmed" : ""}${activeDragId === dialog.id ? " is-dragging" : ""}`}
                style={{ left: dialog.x, top: dialog.y, "--dialog-text-color": dialog.color } as CSSProperties}
                onMouseDown={(event) => {
                  const target = event.target as HTMLElement;
                  if (target.closest("textarea,button")) return;
                  startDrag(dialog.id, event.clientX, event.clientY);
                  event.preventDefault();
                }}
                onTouchStart={(event) => {
                  const target = event.target as HTMLElement;
                  if (target.closest("textarea,button")) return;
                  const touch = event.touches[0];
                  if (touch) startDrag(dialog.id, touch.clientX, touch.clientY);
                }}
                onDoubleClick={() => {
                  if (dialog.confirmed) updateDialog(dialog.id, { confirmed: false });
                }}
              >
                {!dialog.confirmed ? (
                  <button type="button" className="dialog-generator-delete" onClick={() => deleteDialog(dialog.id)} aria-label="删除文字">
                    ×
                  </button>
                ) : null}
                {dialog.confirmed ? (
                  <div className="dialog-generator-text-display">{dialog.text}</div>
                ) : (
                  <textarea
                    className="dialog-generator-text"
                    rows={2}
                    placeholder="输入文本..."
                    value={dialog.text}
                    onChange={(event) => updateDialog(dialog.id, { text: event.target.value })}
                  />
                )}
                {!dialog.confirmed ? (
                  <div className="dialog-generator-bubble-bottom">
                    <button
                      type="button"
                      className="dialog-generator-confirm"
                      onClick={() => {
                        if (dialog.text.trim()) {
                          updateDialog(dialog.id, { text: dialog.text.trim(), confirmed: true });
                        }
                      }}
                    >
                      ✓ 确认
                    </button>
                  </div>
                ) : null}
              </div>
            ))}
          </div>
        </main>
      </div>
    </section>
  );
}

export default DialogGeneratorPage;
