import type { AgentDecomposeResponse, AgentDecomposeTarget } from '@ftb/shared';

export interface AiDecomposeCompletedPayload {
  result: AgentDecomposeResponse;
  dedupeSummary: { removedDevTaskCount: number; removedTestCaseCount: number };
}

export type AiDecomposeButtonMode = 'generate' | 'generating' | 'view_result' | 'retry';

export type AiDecomposeSessionState =
  | { status: 'idle' }
  | { status: 'generating'; startedAt: number; promise: Promise<AiDecomposeCompletedPayload> }
  | { status: 'completed'; completedAt: number; payload: AiDecomposeCompletedPayload }
  | { status: 'error'; failedAt: number; error: string };

type Listener = () => void;

export interface AiDecomposeSessionStore {
  get: (planId: string, target: AgentDecomposeTarget) => AiDecomposeSessionState;
  start: (
    planId: string,
    target: AgentDecomposeTarget,
    run: () => Promise<AiDecomposeCompletedPayload>,
  ) => Promise<AiDecomposeCompletedPayload>;
  markReviewed: (planId: string, target: AgentDecomposeTarget) => void;
  subscribe: (listener: Listener) => () => void;
}

function getSessionKey(planId: string, target: AgentDecomposeTarget): string {
  return `${planId}::${target}`;
}

function normalizeError(error: unknown): string {
  return error instanceof Error ? error.message : String(error || 'AI 生成失败');
}

export function createAiDecomposeSessionStore(): AiDecomposeSessionStore {
  const sessions = new Map<string, AiDecomposeSessionState>();
  const listeners = new Set<Listener>();

  const notify = () => {
    for (const listener of listeners) listener();
  };

  return {
    get(planId, target) {
      return sessions.get(getSessionKey(planId, target)) ?? { status: 'idle' };
    },

    start(planId, target, run) {
      const key = getSessionKey(planId, target);
      const existing = sessions.get(key);
      if (existing?.status === 'generating') return existing.promise;

      const promise = run().then(
        (payload) => {
          sessions.set(key, { status: 'completed', completedAt: Date.now(), payload });
          notify();
          return payload;
        },
        (error) => {
          sessions.set(key, { status: 'error', failedAt: Date.now(), error: normalizeError(error) });
          notify();
          throw error;
        },
      );

      sessions.set(key, { status: 'generating', startedAt: Date.now(), promise });
      notify();
      return promise;
    },

    markReviewed(planId, target) {
      sessions.delete(getSessionKey(planId, target));
      notify();
    },

    subscribe(listener) {
      listeners.add(listener);
      return () => listeners.delete(listener);
    },
  };
}

export function getAiDecomposeButtonMode(session: AiDecomposeSessionState): AiDecomposeButtonMode {
  if (session.status === 'generating') return 'generating';
  if (session.status === 'completed') return 'view_result';
  if (session.status === 'error') return 'retry';
  return 'generate';
}

export const aiDecomposeSessionStore = createAiDecomposeSessionStore();
