import { create } from 'zustand';
import { importStatement } from '../domain/pipeline/statements';
import { sharedPipeline } from '../domain/pipeline/pipelineSingleton';
import type { PipelineResult } from '../domain/pipeline/billPipeline';
import type { ProcessedDraft } from '../domain/pipeline/billPipeline';
import type { Category } from '../domain/taxonomy/categories';
import type { ImportedEvent, Rule, Transaction } from '../domain/core/types';
import type { LedgerIndex } from '../domain/core/types';
import type { DedupConfig } from '../domain/transaction/dedup';
import type { TransferConfig } from '../domain/transaction/transferRecognizer';
import type { StatementAdapter } from '../domain/pipeline/statements';

import { logger } from '../utils/logger';

/**
 * 账单导入状态管理（plan.md「0.1 状态管理」+「2.8 账单处理责任链」）。
 *
 * 职责：
 * - 导入 CSV 账单 → 生成 ImportedEvent
 * - 通过 BillPipeline 走责任链（转账识别 → 去重 → 分类）
 * - 维护待确认的草稿（用户确认后写入 main.bean）
 *
 * 单例 pipeline 保证并发安全（跨多次导入）。
 */

export interface ImportState {
  /** 本次导入的原始事件（导入后、处理前）。 */
  events: ImportedEvent[];
  /** 处理后的待确认草稿。 */
  pendingDrafts: ProcessedDraft[];
  /** 最近一次处理结果统计。 */
  lastResult: PipelineResult | null;
  /** 待处理的规则（供 pipeline 用）。 */
  rules: Rule[];
  /** 待处理的分类库。 */
  categories: Category[];
  isLoading: boolean;
  error: string | null;

  // actions
  /** 设置规则/分类（账本加载后调用）。 */
  setContext: (ctx: { rules?: Rule[]; categories?: Category[] }) => void;
  /** 导入 CSV 账单（生成事件，不立即处理）。 */
  importCsv: (content: string, adapter: StatementAdapter) => ImportedEvent[];
  /** 走 BillPipeline 处理当前事件（转账识别→去重→分类→生成草稿）。 */
  process: (ledger: LedgerIndex, history: Transaction[], dedupConfig?: DedupConfig, transferConfig?: TransferConfig) => Promise<PipelineResult>;
  /** 确认单笔草稿（从 pendingDrafts 移除，由调用方写入 main.bean）。 */
  confirmDraft: (index: number) => ProcessedDraft | null;
  /** 批量确认草稿（从 pendingDrafts 移除指定索引列表）。 */
  confirmDrafts: (indices: number[]) => void;
  /** 拒绝单笔草稿。 */
  rejectDraft: (index: number) => void;
  /** 清空本次导入。 */
  clear: () => void;
}

/** 使用共享 pipeline 单例，保证跨 store 的并发安全。 */
const pipeline = sharedPipeline;

export const useImportStore = create<ImportState>((set, get) => ({
  events: [],
  pendingDrafts: [],
  lastResult: null,
  rules: [],
  categories: [],
  isLoading: false,
  error: null,

  setContext: (ctx) => set((state) => ({
    rules: ctx.rules ?? state.rules,
    categories: ctx.categories ?? state.categories,
  })),

  importCsv: (content, adapter) => {
    try {
      const events = importStatement(content, adapter);
      logger.info('import', `导入 CSV 账单成功, 解析得到 ${events.length} 笔原始事件`);
      set({ events, error: null });
      return events;
    } catch (e) {
      logger.error('import', '解析 CSV 账单代码或格式失败', e);
      set({ error: e instanceof Error ? e.message : String(e) });
      throw e;
    }
  },

  process: async (ledger, history, dedupConfig, transferConfig) => {
    const { events, rules, categories } = get();
    set({ isLoading: true, error: null });
    try {
      const result = await pipeline.process(events, {
        ledger, rules, categories, history, dedupConfig, transferConfig,
      });
      set({
        pendingDrafts: result.drafts,
        lastResult: result,
        isLoading: false,
      });
      return result;
    } catch (e) {
      set({ isLoading: false, error: e instanceof Error ? e.message : String(e) });
      throw e;
    }
  },

  confirmDraft: (index) => {
    const { pendingDrafts } = get();
    const draft = pendingDrafts[index];
    if (!draft) return null;
    // 用 draft 引用而非索引过滤，避免竞态
    const next = pendingDrafts.filter((d) => d !== draft);
    logger.info('import', `[手动确认草稿] 确认导入草稿 [日期: ${draft.draft.date}, 商户: "${draft.draft.payee ?? '未知'}", 叙述: "${draft.draft.narration}"]`);
    set({ pendingDrafts: next });
    return draft;
  },

  confirmDrafts: (indices) => {
    const { pendingDrafts } = get();
    // 使用引用过滤而非索引过滤，避免并发覆盖
    const toRemove = new Set(indices.map(i => pendingDrafts[i]));
    logger.info('import', `[批量确认草稿] 批量确认 ${toRemove.size} 笔草稿入账`);
    set({ pendingDrafts: pendingDrafts.filter(d => !toRemove.has(d)) });
  },

  rejectDraft: (index) => {
    const { pendingDrafts } = get();
    const draft = pendingDrafts[index];
    if (draft) {
      logger.info('import', `[手动忽略草稿] 丢弃草稿 [日期: ${draft.draft.date}, 商户: "${draft.draft.payee ?? '未知'}", 叙述: "${draft.draft.narration}"]`);
    }
    set({ pendingDrafts: pendingDrafts.filter((_, i) => i !== index) });
  },

  clear: () => {
    logger.info('import', '[清空导入缓存] 已清空当前导入队列与草稿列表');
    set({ events: [], pendingDrafts: [], lastResult: null, error: null });
  },
}));
