import {
  useEffect,
  useLayoutEffect,
  useMemo,
  useRef,
  useState,
  type KeyboardEvent,
} from "react";
import clsx from "clsx";
import {
  CheckSquare,
  Plus,
  Trash2,
  Pencil,
  Trash,
  GripHorizontal,
  ListTodo,
  CheckCircle2,
  Pin,
} from "lucide-react";
import {
  DndContext,
  closestCenter,
  PointerSensor,
  useSensor,
  useSensors,
  type DragEndEvent,
} from "@dnd-kit/core";
import {
  SortableContext,
  arrayMove,
  useSortable,
  verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { useAppStore } from "../../store/useAppStore";
import type { Task } from "../../store/types";
import styles from "./TasksPanel.module.css";

type View = "active" | "done";

/**
 * 工具栏上的"任务"按钮（含未完成徽标）
 */
export function TasksTrigger({
  active,
  onClick,
  disabled = false,
}: {
  active: boolean;
  onClick: () => void;
  disabled?: boolean;
}) {
  const pending = useAppStore((s) => s.tasks.filter((t) => !t.done).length);
  const taskPinMode = useAppStore((s) => s.taskPinMode);
  const toggleTaskPinMode = useAppStore((s) => s.toggleTaskPinMode);

  return (
    <div className={styles.triggerGroup}>
      <button
        className={clsx(styles.trigger, active && styles.triggerActive)}
        title={disabled ? "已锁定" : "任务列表"}
        onClick={onClick}
        disabled={disabled}
      >
        <CheckSquare size={16} />
        <span>任务</span>
        {pending > 0 && <span className={styles.badge}>{pending}</span>}
      </button>
      <button
        type="button"
        className={clsx(styles.pinTrigger, taskPinMode && styles.pinTriggerOn)}
        title="钉子模式：透明悬浮，仅显示未完成任务，点击穿透下层"
        disabled={disabled}
        onClick={(e) => {
          e.stopPropagation();
          if (!disabled) toggleTaskPinMode();
        }}
      >
        <Pin size={14} />
      </button>
    </div>
  );
}

/**
 * 展开的任务面板：active(未完成) / done(已完成) 两个视图切换
 * - active：输入框 + 未完成列表（默认）
 * - done：已完成列表 + 一键清除
 */
export function TasksPanel() {
  const tasks = useAppStore((s) => s.tasks);
  const addTask = useAppStore((s) => s.addTask);
  const reorderTasks = useAppStore((s) => s.reorderTasks);
  const clearDoneTasks = useAppStore((s) => s.clearDoneTasks);

  const [view, setViewRaw] = useState<View>("active");
  const inputRef = useRef<HTMLInputElement>(null);
  const [draft, setDraft] = useState("");

  // 底部滑块动画：测量当前激活 tab 的位置/宽度，给滑块设 transform + width
  const tabsRef = useRef<HTMLDivElement>(null);
  const [indicator, setIndicator] = useState({ left: 0, width: 0 });
  useLayoutEffect(() => {
    if (!tabsRef.current) return;
    const el = tabsRef.current.querySelector(
      `[data-tab="${view}"]`
    ) as HTMLElement | null;
    if (!el) return;
    setIndicator({ left: el.offsetLeft, width: el.offsetWidth });
  }, [view, tasks.length]); // tasks 变化会改变徽标宽度，需要重测

  /** 幂等切换：当前已是目标 view 时直接 return，避免重复点击触发任何 re-render/动画 */
  const setView = (next: View) => {
    if (next === view) return;
    setViewRaw(next);
  };

  // 响应全局快捷键的聚焦事件，并自动切回 active 视图
  useEffect(() => {
    const handler = () => {
      setViewRaw("active");
      setTimeout(() => inputRef.current?.focus(), 0);
    };
    window.addEventListener("deskfloat:focus-new-task", handler);
    if (view === "active") inputRef.current?.focus();
    return () =>
      window.removeEventListener("deskfloat:focus-new-task", handler);
  }, [view]);

  const activeTasks = useMemo(
    () => tasks.filter((t) => !t.done).sort((a, b) => a.order - b.order),
    [tasks]
  );
  const doneTasks = useMemo(
    () => tasks.filter((t) => t.done).sort((a, b) => b.createdAt - a.createdAt),
    [tasks]
  );

  const visibleTasks = view === "active" ? activeTasks : doneTasks;
  const ids = useMemo(() => visibleTasks.map((t) => t.id), [visibleTasks]);

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 4 } })
  );

  /** 仅 active 视图允许拖拽排序 */
  function onDragEnd(e: DragEndEvent) {
    if (view !== "active") return;
    const { active, over } = e;
    if (!over || active.id === over.id) return;
    const oldIndex = ids.indexOf(active.id as string);
    const newIndex = ids.indexOf(over.id as string);
    if (oldIndex < 0 || newIndex < 0) return;
    // 仅对未完成任务重排序，已完成位置保持不变
    const newActiveIds = arrayMove(ids, oldIndex, newIndex);
    const doneIds = doneTasks.map((t) => t.id);
    reorderTasks([...newActiveIds, ...doneIds]);
  }

  function onSubmit() {
    addTask(draft);
    setDraft("");
    inputRef.current?.focus();
  }

  function onKey(e: KeyboardEvent<HTMLInputElement>) {
    if (e.key === "Enter") onSubmit();
  }

  function handleClearDone() {
    if (doneTasks.length === 0) return;
    if (window.confirm(`确认清除 ${doneTasks.length} 条已完成任务？`)) {
      clearDoneTasks();
      // 清完跳回 active
      setView("active");
    }
  }

  return (
    <div className={styles.panel}>
      <div className={styles.tabs} ref={tabsRef}>
        <button
          data-tab="active"
          className={clsx(styles.tab, view === "active" && styles.tabActive)}
          onClick={() => setView("active")}
        >
          <ListTodo size={14} />
          <span>进行中</span>
          <span className={styles.tabCount}>{activeTasks.length}</span>
        </button>
        <button
          data-tab="done"
          className={clsx(styles.tab, view === "done" && styles.tabActive)}
          onClick={() => setView("done")}
        >
          <CheckCircle2 size={14} />
          <span>已完成</span>
          {doneTasks.length > 0 && (
            <span
              className={clsx(styles.tabCount, styles.tabCountAlert)}
              title="待清理"
            >
              {doneTasks.length}
            </span>
          )}
        </button>

        {/* 底部滑块指示器：transform 平滑滑动 */}
        <div
          className={styles.tabIndicator}
          style={{
            transform: `translateX(${indicator.left}px)`,
            width: indicator.width,
          }}
        />

        {view === "done" && doneTasks.length > 0 && (
          <button
            className={styles.clearBtn}
            onClick={handleClearDone}
            title="一键清除所有已完成任务"
          >
            <Trash size={12} />
            <span>一键清除</span>
          </button>
        )}
      </div>

      {view === "active" && (
        <div className={styles.inputRow}>
          <input
            ref={inputRef}
            value={draft}
            onChange={(e) => setDraft(e.target.value)}
            onKeyDown={onKey}
            placeholder="新增任务（回车保存）"
          />
          <button className={styles.addBtn} onClick={onSubmit} title="新增">
            <Plus size={16} />
          </button>
        </div>
      )}

      <div className={styles.list}>
        {visibleTasks.length === 0 ? (
          <div className={styles.empty}>
            {view === "active"
              ? "暂无进行中的任务，回车快速新增 ↑"
              : "还没有完成的任务，加油 💪"}
          </div>
        ) : view === "active" ? (
          <DndContext
            sensors={sensors}
            collisionDetection={closestCenter}
            onDragEnd={onDragEnd}
          >
            <SortableContext items={ids} strategy={verticalListSortingStrategy}>
              {visibleTasks.map((t) => (
                <TaskRow key={t.id} task={t} sortable />
              ))}
            </SortableContext>
          </DndContext>
        ) : (
          visibleTasks.map((t) => <TaskRow key={t.id} task={t} sortable={false} />)
        )}
      </div>
    </div>
  );
}

/** 单行任务渲染。sortable=false 时去掉拖拽柄 */
function TaskRow({ task, sortable }: { task: Task; sortable: boolean }) {
  const toggleTask = useAppStore((s) => s.toggleTask);
  const removeTask = useAppStore((s) => s.removeTask);
  const updateTask = useAppStore((s) => s.updateTask);

  const [editing, setEditing] = useState(false);
  const [text, setText] = useState(task.title);

  const sortableHook = useSortable({ id: task.id, disabled: !sortable });

  const style = sortable
    ? {
        transform: CSS.Transform.toString(sortableHook.transform),
        transition: sortableHook.transition,
        opacity: sortableHook.isDragging ? 0.6 : 1,
      }
    : {};

  function commit() {
    if (text.trim() && text !== task.title) updateTask(task.id, text);
    setEditing(false);
  }

  return (
    <div
      ref={sortable ? sortableHook.setNodeRef : undefined}
      style={style}
      className={clsx(styles.row, task.done && styles.rowDone)}
    >
      {sortable && (
        <button
          className={styles.grip}
          {...sortableHook.attributes}
          {...sortableHook.listeners}
          title="拖动排序"
        >
          <GripHorizontal size={12} />
        </button>
      )}

      <label className={styles.check}>
        <input
          type="checkbox"
          checked={task.done}
          onChange={() => toggleTask(task.id)}
        />
        <span />
      </label>

      {editing ? (
        <input
          autoFocus
          className={styles.editInput}
          value={text}
          onChange={(e) => setText(e.target.value)}
          onBlur={commit}
          onKeyDown={(e) => {
            if (e.key === "Enter") commit();
            if (e.key === "Escape") {
              setText(task.title);
              setEditing(false);
            }
          }}
        />
      ) : (
        <div
          className={styles.title2}
          onDoubleClick={() => setEditing(true)}
          title="双击编辑"
        >
          {task.title}
        </div>
      )}

      <div className={styles.actions}>
        {!task.done && (
          <button
            className={styles.iconBtn}
            onClick={() => setEditing((v) => !v)}
            title="编辑"
          >
            <Pencil size={12} />
          </button>
        )}
        <button
          className={clsx(styles.iconBtn, styles.danger)}
          onClick={() => removeTask(task.id)}
          title="删除"
        >
          <Trash2 size={12} />
        </button>
      </div>
    </div>
  );
}
