'use client';
import { create } from 'zustand';
import { loadServerData, saveServerData, SERVER_DATA_CACHE_MS } from '@/lib/server-data';
import {
  mergeDailySnapshotCacheForSave,
  mergeInsightCacheForSave,
  upsertDailySnapshot,
  upsertInsight,
  type XiaobaoRiskInsightCacheItem,
} from '@/lib/xiaobao-risk-cache';
import type { XiaobaoRiskSnapshot } from '@/lib/xiaobao-risk-trend';

interface XiaobaoRiskState {
  snapshots: XiaobaoRiskSnapshot[];
  insights: XiaobaoRiskInsightCacheItem[];
  pendingInsightKeys: string[];
  insightRequestAttempts: Record<string, string>;
  riskDataLoaded: boolean;
  error?: string;
  fetchRiskData: () => Promise<void>;
  saveSnapshot: (item: XiaobaoRiskSnapshot) => Promise<void>;
  saveInsight: (item: XiaobaoRiskInsightCacheItem) => Promise<void>;
  beginInsightUpdate: (key: string) => void;
  finishInsightUpdate: (key: string) => void;
}

async function loadSnapshots(): Promise<XiaobaoRiskSnapshot[] | null> {
  try {
    const rows = await loadServerData<XiaobaoRiskSnapshot[]>('xiaobao-risk-snapshots');
    return Array.isArray(rows) ? rows : [];
  } catch {}
  return null;
}

async function loadInsights(): Promise<XiaobaoRiskInsightCacheItem[] | null> {
  try {
    const rows = await loadServerData<XiaobaoRiskInsightCacheItem[]>('xiaobao-risk-insights');
    return Array.isArray(rows) ? rows : [];
  } catch {}
  return null;
}

let snapshotSaveQueue: Promise<void> = Promise.resolve();
let insightSaveQueue: Promise<void> = Promise.resolve();
let lastRiskDataFetchAt = 0;

export const useXiaobaoRiskStore = create<XiaobaoRiskState>((set, get) => ({
  snapshots: [],
  insights: [],
  pendingInsightKeys: [],
  insightRequestAttempts: {},
  riskDataLoaded: false,
  error: undefined,

  fetchRiskData: async () => {
    if (get().riskDataLoaded && Date.now() - lastRiskDataFetchAt < SERVER_DATA_CACHE_MS) return;
    set({ riskDataLoaded: false });
    const [snapshots, insights] = await Promise.all([loadSnapshots(), loadInsights()]);
    if (get().riskDataLoaded && Date.now() - lastRiskDataFetchAt < SERVER_DATA_CACHE_MS) return;
    lastRiskDataFetchAt = Date.now();
    set({
      ...(snapshots ? { snapshots } : {}),
      ...(insights ? { insights } : {}),
      riskDataLoaded: snapshots !== null && insights !== null,
      error: snapshots === null || insights === null ? '小宝预警缓存加载失败' : undefined,
    });
  },

  saveSnapshot: async (item) => {
    const optimistic = upsertDailySnapshot(get().snapshots, item);
    set({ snapshots: optimistic, error: undefined });
    const task = snapshotSaveQueue.then(async () => {
      const remote = await loadServerData<XiaobaoRiskSnapshot[]>('xiaobao-risk-snapshots', { force: true });
      const snapshots = mergeDailySnapshotCacheForSave(get().snapshots, Array.isArray(remote) ? remote : [], item);
      set({ snapshots, error: undefined });
      await saveServerData('xiaobao-risk-snapshots', snapshots);
    });
    snapshotSaveQueue = task.catch(() => undefined);
    try {
      await task;
    } catch (error) {
      set({ error: '小宝预警快照保存失败' });
      throw error;
    }
  },

  saveInsight: async (item) => {
    const optimistic = upsertInsight(get().insights, item);
    set({ insights: optimistic, error: undefined });
    const task = insightSaveQueue.then(async () => {
      const remote = await loadServerData<XiaobaoRiskInsightCacheItem[]>('xiaobao-risk-insights', { force: true });
      const insights = mergeInsightCacheForSave(get().insights, Array.isArray(remote) ? remote : [], item);
      set({ insights, error: undefined });
      await saveServerData('xiaobao-risk-insights', insights);
    });
    insightSaveQueue = task.catch(() => undefined);
    try {
      await task;
    } catch (error) {
      set({ error: '小宝预警解读保存失败' });
      throw error;
    }
  },

  beginInsightUpdate: (key) => {
    if (!key) return;
    if (get().pendingInsightKeys.includes(key)) return;
    set({
      pendingInsightKeys: [...get().pendingInsightKeys, key],
      insightRequestAttempts: {
        ...get().insightRequestAttempts,
        [key]: new Date().toISOString(),
      },
    });
  },

  finishInsightUpdate: (key) => {
    if (!key) return;
    set({ pendingInsightKeys: get().pendingInsightKeys.filter((item) => item !== key) });
  },
}));
