/**
 * 品牌全局状态 Store (Zustand)
 *
 * 与 SWR 互补：
 * - SWR 管理服务端缓存（品牌列表数据获取、缓存、重验证）
 * - 此 Store 管理客户端侧状态：
 *   1. 当前选中品牌（跨页面共享）
 *   2. 乐观更新（操作先更新本地，API 失败再回滚）
 *   3. 品牌列表的本地增删（配合 SWR mutate）
 */

import { create } from "zustand";
import { fetchWithAuth } from "@/lib/api/client";
import { brandsApi } from "@/lib/api/brands";
import type {
  BrandListItem,
  BrandListResponse,
} from "@/types/brand";
import type { CreateBrandPayload, UpdateBrandPayload } from "@/lib/api/brands";
import { useNotificationStore } from "./notification-store";

// ── 类型定义 ────────────────────────────────────────────────────────────────────

export interface BrandState {
  /** 当前选中品牌 ID */
  selectedBrandId: string | null;
  /** 当前选中品牌名称（方便 UI 直接显示） */
  selectedBrandName: string | null;
  /** 品牌列表本地副本（用于乐观更新时的临时状态） */
  localBrands: BrandListItem[];
  /** 正在进行乐观更新的操作类型 */
  optimisticAction: "creating" | "updating" | "deleting" | null;
}

export interface BrandActions {
  /** 选中品牌 */
  selectBrand: (brandId: string, brandName?: string) => void;
  /** 清除选中品牌 */
  clearSelection: () => void;
  /** 从 SWR 数据同步品牌列表到本地副本 */
  syncFromSWR: (brands: BrandListItem[]) => void;

  // ── 乐观更新操作 ──────────────────────────────────────────────────────────
  /**
   * 乐观创建品牌：
   * 1. 先在本地列表添加临时条目
   * 2. 异步调用 API
   * 3. 成功 → 用真实数据替换临时条目（配合 SWR mutate）
   * 4. 失败 → 回滚本地列表，显示错误通知
   */
  optimisticCreate: (
    token: string,
    payload: CreateBrandPayload,
    /** SWR mutate 回调，用于刷新服务端缓存 */
    swrMutate?: () => void,
  ) => Promise<BrandListItem | null>;

  /**
   * 乐观更新品牌：
   * 1. 先在本地列表更新条目
   * 2. 异步调用 API
   * 3. 成功 → 配合 SWR mutate
   * 4. 失败 → 回滚本地列表
   */
  optimisticUpdate: (
    token: string,
    brandId: string,
    payload: UpdateBrandPayload,
    swrMutate?: () => void,
  ) => Promise<BrandListItem | null>;

  /**
   * 乐观删除品牌：
   * 1. 先从本地列表移除条目
   * 2. 异步调用 API
   * 3. 成功 → 配合 SWR mutate
   * 4. 失败 → 恢复本地列表条目
   */
  optimisticDelete: (
    token: string,
    brandId: string,
    swrMutate?: () => void,
  ) => Promise<boolean>;
}

// ── 辅助 ────────────────────────────────────────────────────────────────────────

/** 生成临时 ID（乐观创建用） */
function generateTempId(): string {
  return `temp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}

// ── 默认值 ──────────────────────────────────────────────────────────────────────

const INITIAL_STATE: BrandState = {
  selectedBrandId: null,
  selectedBrandName: null,
  localBrands: [],
  optimisticAction: null,
};

// ── Store ───────────────────────────────────────────────────────────────────────

export const useBrandStore = create<BrandState & BrandActions>()((set, get) => ({
  ...INITIAL_STATE,

  selectBrand: (brandId, brandName) => {
    set({
      selectedBrandId: brandId,
      selectedBrandName: brandName ?? null,
    });
  },

  clearSelection: () => {
    set({ selectedBrandId: null, selectedBrandName: null });
  },

  syncFromSWR: (brands) => {
    set({ localBrands: brands });
  },

  // ── 乐观创建 ────────────────────────────────────────────────────────────
  optimisticCreate: async (token, payload, swrMutate) => {
    const { localBrands } = get();
    const notificationStore = useNotificationStore.getState();

    // 1. 创建临时条目
    const tempBrand: BrandListItem = {
      id: generateTempId(),
      name: payload.name,
      aliases: payload.aliases ?? [],
      platforms: payload.platforms ?? [],
      frequency: (payload.frequency ?? "weekly") as BrandListItem["frequency"],
      status: "pending",
      score: null,
      last_queried_at: null,
      next_query_at: null,
      created_at: new Date().toISOString(),
    };

    set({
      localBrands: [...localBrands, tempBrand],
      optimisticAction: "creating",
    });

    // 2. 异步调用 API
    try {
      const created = await brandsApi.create(token, payload as CreateBrandPayload) as BrandListItem;

      // 3. 成功 → 用真实数据替换临时条目
      set((state) => ({
        localBrands: state.localBrands.map((b) =>
          b.id === tempBrand.id ? created : b
        ),
        optimisticAction: null,
      }));

      notificationStore.addNotification({
        type: "success",
        message: `品牌「${created.name}」创建成功`,
      });

      // 触发 SWR 重新获取，保证服务端缓存同步
      swrMutate?.();

      return created;
    } catch (err) {
      // 4. 失败 → 回滚
      set((state) => ({
        localBrands: state.localBrands.filter((b) => b.id !== tempBrand.id),
        optimisticAction: null,
      }));

      const message = err instanceof Error ? err.message : "创建品牌失败";
      notificationStore.addNotification({ type: "error", message });

      return null;
    }
  },

  // ── 乐观更新 ────────────────────────────────────────────────────────────
  optimisticUpdate: async (token, brandId, payload, swrMutate) => {
    const { localBrands } = get();
    const notificationStore = useNotificationStore.getState();

    // 1. 保存原始数据用于回滚
    const originalBrand = localBrands.find((b) => b.id === brandId);
    if (!originalBrand) {
      // 本地没有此品牌，无法乐观更新，直接走 API
      try {
        const updated = await brandsApi.update(token, brandId, payload as UpdateBrandPayload) as BrandListItem;
        swrMutate?.();
        return updated;
      } catch (err) {
        const message = err instanceof Error ? err.message : "更新品牌失败";
        notificationStore.addNotification({ type: "error", message });
        return null;
      }
    }

    // 2. 乐观更新本地列表
    const optimisticBrand = {
      ...originalBrand,
      ...payload,
      id: brandId, // 确保 ID 不被覆盖
    } as BrandListItem;

    set({
      localBrands: localBrands.map((b) =>
        b.id === brandId ? optimisticBrand : b
      ),
      optimisticAction: "updating",
    });

    // 3. 异步调用 API
    try {
      const updated = await brandsApi.update(token, brandId, payload as UpdateBrandPayload) as BrandListItem;

      set({
        localBrands: get().localBrands.map((b) =>
          b.id === brandId ? updated : b
        ),
        optimisticAction: null,
      });

      notificationStore.addNotification({
        type: "success",
        message: `品牌「${updated.name}」更新成功`,
      });

      swrMutate?.();

      return updated;
    } catch (err) {
      // 4. 失败 → 回滚到原始数据
      set((state) => ({
        localBrands: state.localBrands.map((b) =>
          b.id === brandId ? originalBrand : b
        ),
        optimisticAction: null,
      }));

      const message = err instanceof Error ? err.message : "更新品牌失败";
      notificationStore.addNotification({ type: "error", message });

      return null;
    }
  },

  // ── 乐观删除 ────────────────────────────────────────────────────────────
  optimisticDelete: async (token, brandId, swrMutate) => {
    const { localBrands, selectedBrandId } = get();
    const notificationStore = useNotificationStore.getState();

    // 1. 保存原始数据用于回滚
    const originalBrand = localBrands.find((b) => b.id === brandId);
    if (!originalBrand) {
      // 本地没有此品牌，直接走 API
      try {
        await brandsApi.delete(token, brandId);
        swrMutate?.();
        return true;
      } catch (err) {
        const message = err instanceof Error ? err.message : "删除品牌失败";
        notificationStore.addNotification({ type: "error", message });
        return false;
      }
    }

    // 2. 乐观删除：从本地列表移除
    set({
      localBrands: localBrands.filter((b) => b.id !== brandId),
      optimisticAction: "deleting",
      // 如果删除的是当前选中品牌，清除选择
      selectedBrandId: selectedBrandId === brandId ? null : selectedBrandId,
      selectedBrandName: selectedBrandId === brandId ? null : get().selectedBrandName,
    });

    // 3. 异步调用 API
    try {
      await brandsApi.delete(token, brandId);

      set({ optimisticAction: null });

      notificationStore.addNotification({
        type: "success",
        message: `品牌「${originalBrand.name}」已删除`,
      });

      swrMutate?.();

      return true;
    } catch (err) {
      // 4. 失败 → 恢复原始条目
      set((state) => ({
        localBrands: [...state.localBrands, originalBrand],
        optimisticAction: null,
      }));

      const message = err instanceof Error ? err.message : "删除品牌失败";
      notificationStore.addNotification({ type: "error", message });

      return false;
    }
  },
}));