import { create } from "zustand";
import { loadState, saveState } from "../api/tauri";
import {
  AppState,
  DEFAULT_STATE,
  PomodoroConfig,
  Settings,
  Shortcut,
  Task,
} from "./types";

/**
 * 全局应用状态：所有持久化字段集中在这里。
 * 任何写入操作都会触发一次 debounce 的整体保存到 JSON 文件。
 */
interface Store extends AppState {
  ready: boolean;
  activePanel: "tasks" | "shortcuts" | "pomodoro" | "settings" | null;
  collapsed: boolean;
  /** 任务钉子模式：透明穿透 overlay，仅展示未完成任务 */
  taskPinMode: boolean;

  // lifecycle
  hydrate: () => Promise<void>;

  // ui
  setActivePanel: (p: Store["activePanel"]) => void;
  toggleCollapsed: () => void;
  toggleTaskPinMode: () => void;

  // tasks
  addTask: (title: string) => void;
  toggleTask: (id: string) => void;
  updateTask: (id: string, title: string) => void;
  removeTask: (id: string) => void;
  reorderTasks: (orderedIds: string[]) => void;
  clearDoneTasks: () => void;

  // shortcuts
  addShortcut: (s: Omit<Shortcut, "id">) => void;
  updateShortcut: (id: string, patch: Partial<Shortcut>) => void;
  removeShortcut: (id: string) => void;
  reorderShortcuts: (orderedIds: string[]) => void;

  // pomodoro config
  updatePomodoro: (patch: Partial<PomodoroConfig>) => void;

  // settings
  updateSettings: (patch: Partial<Settings>) => void;
}

const newId = () =>
  globalThis.crypto?.randomUUID?.() ??
  `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;

let saveTimer: number | null = null;
/** 把当前 state 落盘（防抖 300ms） */
function scheduleSave(getSnapshot: () => AppState) {
  if (saveTimer) window.clearTimeout(saveTimer);
  saveTimer = window.setTimeout(async () => {
    const snap = getSnapshot();
    try {
      await saveState(JSON.stringify(snap, null, 2));
    } catch (e) {
      console.error("[DeskFloat] save failed", e);
    }
  }, 300);
}

export const useAppStore = create<Store>((set, get) => {
  /** 取出仅持久化字段 */
  const snapshot = (): AppState => {
    const s = get();
    return {
      tasks: s.tasks,
      shortcuts: s.shortcuts,
      pomodoro: s.pomodoro,
      settings: s.settings,
    };
  };

  const persist = () => scheduleSave(snapshot);

  return {
    ...DEFAULT_STATE,
    ready: false,
    activePanel: null,
    collapsed: false,
    taskPinMode: false,

    /** 启动时从 Rust 后端读取 JSON */
    async hydrate() {
      try {
        const json = await loadState();
        const parsed = JSON.parse(json) as Partial<AppState>;
        set({
          tasks: parsed.tasks ?? [],
          shortcuts: parsed.shortcuts ?? [],
          pomodoro: { ...DEFAULT_STATE.pomodoro, ...(parsed.pomodoro ?? {}) },
          settings: {
            ...DEFAULT_STATE.settings,
            ...(parsed.settings ?? {}),
            globalHotkeys: {
              ...DEFAULT_STATE.settings.globalHotkeys,
              ...((parsed.settings as Settings | undefined)?.globalHotkeys ?? {}),
            },
          },
          ready: true,
        });
      } catch (e) {
        console.error("[DeskFloat] hydrate failed", e);
        set({ ready: true });
      }
    },

    setActivePanel(p) {
      set({ activePanel: get().activePanel === p ? null : p });
    },

    toggleCollapsed() {
      set({ collapsed: !get().collapsed, activePanel: null });
    },

    /** 切换任务钉子模式（进入时关闭抽屉） */
    toggleTaskPinMode() {
      const next = !get().taskPinMode;
      set({
        taskPinMode: next,
        activePanel: next ? null : get().activePanel,
        collapsed: false,
      });
    },

    // ============= tasks =============
    addTask(title) {
      const t = title.trim();
      if (!t) return;
      const max = get().tasks.reduce((m, x) => Math.max(m, x.order), -1);
      const task: Task = {
        id: newId(),
        title: t,
        done: false,
        createdAt: Date.now(),
        order: max + 1,
      };
      set({ tasks: [...get().tasks, task] });
      persist();
    },
    toggleTask(id) {
      set({
        tasks: get().tasks.map((x) => (x.id === id ? { ...x, done: !x.done } : x)),
      });
      persist();
    },
    updateTask(id, title) {
      const t = title.trim();
      if (!t) return;
      set({
        tasks: get().tasks.map((x) => (x.id === id ? { ...x, title: t } : x)),
      });
      persist();
    },
    removeTask(id) {
      set({ tasks: get().tasks.filter((x) => x.id !== id) });
      persist();
    },
    reorderTasks(orderedIds) {
      const map = new Map(get().tasks.map((t) => [t.id, t]));
      const next: Task[] = [];
      orderedIds.forEach((id, idx) => {
        const t = map.get(id);
        if (t) next.push({ ...t, order: idx });
      });
      set({ tasks: next });
      persist();
    },
    clearDoneTasks() {
      set({ tasks: get().tasks.filter((x) => !x.done) });
      persist();
    },

    // ============= shortcuts =============
    addShortcut(s) {
      set({ shortcuts: [...get().shortcuts, { ...s, id: newId() }] });
      persist();
    },
    updateShortcut(id, patch) {
      set({
        shortcuts: get().shortcuts.map((x) => (x.id === id ? { ...x, ...patch } : x)),
      });
      persist();
    },
    removeShortcut(id) {
      set({ shortcuts: get().shortcuts.filter((x) => x.id !== id) });
      persist();
    },
    reorderShortcuts(orderedIds) {
      const map = new Map(get().shortcuts.map((s) => [s.id, s]));
      const next: Shortcut[] = [];
      orderedIds.forEach((id) => {
        const s = map.get(id);
        if (s) next.push(s);
      });
      set({ shortcuts: next });
      persist();
    },

    // ============= pomodoro config =============
    updatePomodoro(patch) {
      set({ pomodoro: { ...get().pomodoro, ...patch } });
      persist();
    },

    // ============= settings =============
    updateSettings(patch) {
      const cur = get().settings;
      const next: Settings = {
        ...cur,
        ...patch,
        globalHotkeys: {
          ...cur.globalHotkeys,
          ...(patch.globalHotkeys ?? {}),
        },
      };
      set({ settings: next });
      persist();
    },
  };
});
