'use client';
import { create } from 'zustand';
import type { Bug, BugStatus, BugLog } from '@/lib/bug';
import { generateBugNo } from '@/lib/bug';
import { applyBugTransition } from '@/lib/bug-workflow';
import { loadServerData, saveServerData, SERVER_DATA_CACHE_MS } from '@/lib/server-data';
import {
  makeBugCreatedActivity,
  makeBugStatusActivity,
  makeBugTransferredActivity,
} from '@/lib/work-activity-factory';
import { useWorkActivityStore } from './useWorkActivityStore';

function saveStored(items: Bug[]) {
  saveServerData('bugs', items).catch(() => {});
}

let lastBugsFetchAt = 0;

async function loadStored(): Promise<Bug[] | null> {
  try {
    return await loadServerData<Bug[]>('bugs');
  } catch {}
  return null;
}

function makeLog(action: BugLog['action'], operator: string, from?: string, to?: string, remark?: string): BugLog {
  return { id: `log-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`, action, fromValue: from, toValue: to, operator, remark, createdAt: new Date().toISOString() };
}

interface BugState {
  bugs: Bug[];
  loaded: boolean;
  fetchBugs: (options?: { force?: boolean }) => Promise<void>;
  createBug: (data: Omit<Bug, 'id' | 'bugNo' | 'createdAt' | 'updatedAt' | 'status' | 'logs'>, operator: string) => Bug;
  updateBug: (id: string, data: Partial<Bug>) => void;
  deleteBug: (id: string) => void;
  changeStatus: (id: string, to: BugStatus, operator: string, extra?: { resolution?: string }) => { ok: boolean; message?: string };
  transferBug: (id: string, newAssigneeId: string, operator: string, remark?: string) => { ok: boolean; message?: string };
  getByTestCase: (caseId: string) => Bug[];
  getByVersion: (versionId: string) => Bug[];
  getByAssignee: (assigneeId: string) => Bug[];
}

export const useBugStore = create<BugState>((set, get) => ({
  bugs: [],
  loaded: false,

  fetchBugs: async (options) => {
    if (!options?.force && get().loaded && Date.now() - lastBugsFetchAt < SERVER_DATA_CACHE_MS) return;
    const cached = await loadStored();
    if (!options?.force && get().loaded && Date.now() - lastBugsFetchAt < SERVER_DATA_CACHE_MS) return;
    lastBugsFetchAt = Date.now();
    set({ bugs: cached ?? [], loaded: true });
  },

  createBug: (data, operator) => {
    const list = get().bugs;
    const now = new Date().toISOString();
    const log = makeLog('create', operator);
    const bug: Bug = {
      ...data,
      id: `bug-${Date.now()}`,
      bugNo: generateBugNo(list),
      status: 'open',
      logs: [log],
      createdAt: now,
      updatedAt: now,
    };
    const updated = [...list, bug];
    set({ bugs: updated, loaded: true });
    saveStored(updated);
    useWorkActivityStore.getState().addActivity(makeBugCreatedActivity(bug, operator));
    return bug;
  },

  updateBug: (id, data) => {
    const updated = get().bugs.map((b) =>
      b.id === id ? { ...b, ...data, updatedAt: new Date().toISOString() } : b,
    );
    set({ bugs: updated, loaded: true });
    saveStored(updated);
  },

  deleteBug: (id) => {
    const updated = get().bugs.filter((b) => b.id !== id);
    set({ bugs: updated, loaded: true });
    saveStored(updated);
  },

  changeStatus: (id, to, operator, extra) => {
    const bug = get().bugs.find((b) => b.id === id);
    if (!bug) return { ok: false, message: 'Bug不存在' };
    const result = applyBugTransition(bug, to, operator, {
      now: new Date(),
      resolution: extra?.resolution,
    });
    if (!result.ok || !result.patch) return { ok: false, message: result.message };
    get().updateBug(id, result.patch);
    const activity = makeBugStatusActivity(bug, bug.status, to, operator);
    if (activity) useWorkActivityStore.getState().addActivity(activity);
    return { ok: true };
  },

  transferBug: (id, newAssigneeId, operator, remark) => {
    const bug = get().bugs.find((b) => b.id === id);
    if (!bug) return { ok: false, message: 'Bug不存在' };
    if (bug.assigneeId === newAssigneeId) return { ok: false, message: '已是当前负责人' };
    const log = makeLog('transfer', operator, bug.assigneeId, newAssigneeId, remark);
    get().updateBug(id, { assigneeId: newAssigneeId, logs: [...(bug.logs || []), log] });
    useWorkActivityStore.getState().addActivity(makeBugTransferredActivity(bug, operator, newAssigneeId));
    return { ok: true };
  },

  getByTestCase: (caseId) => {
    return get().bugs.filter((b) => b.testCaseId === caseId);
  },

  getByVersion: (versionId) => {
    return get().bugs.filter((b) => b.versionId === versionId);
  },

  getByAssignee: (assigneeId) => {
    return get().bugs.filter((b) => b.assigneeId === assigneeId);
  },
}));
