/**
 * API 层 — v2.6 对接层
 * 保留 v1.0 全部接口签名，内部适配 v2.6 后端 API
 * v2.6 后端没有的接口返回空/mock 数据，保证组件不报错
 */

const API_BASE = import.meta.env.VITE_API_URL || '';

// ── 项目上下文（由 store 设置） ──

let _currentProjectId: string | null = null;

export function setApiProjectId(pid: string | null) {
  _currentProjectId = pid;
}

export function _getProjectId(): string | null {
  return _currentProjectId;
}

// Alias without underscore (OBS-37)
export const getProjectId = _getProjectId;

function projectId(): string {
  if (!_currentProjectId) throw new Error('No project selected');
  return _currentProjectId;
}

// ── 通用请求 ──

async function fetchJ<T>(url: string): Promise<T> {
  const res = await fetch(url, { cache: 'no-store' });
  if (!res.ok) throw new Error(String(res.status));
  return res.json();
}

async function postJ<T>(url: string, data: unknown): Promise<T> {
  const res = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  });
  return res.json();
}

// ── v2.6 Task → v1.0 Task 适配 ──

function adaptTask(raw: any): Task {
  const t: Task = {
    id: raw.id,
    title: raw.title || raw.requirement || '(无标题)',
    state: raw.status || 'created',
    status: raw.status || 'created',
    org: raw.assignee || '',
    now: raw.description || raw.requirement || '-',
    eta: raw.priority || '-',
    block: '无',
    ac: raw.assignee || '',
    output: '',
    heartbeat: { status: 'idle', label: '⚪' },
    flow_log: [],
    todos: [],
    review_round: 0,
    archived: false,
    updated_at: raw.updated_at || '',
    nodes: [],
    plan_status: '',
    sourceMeta: {},
    parent_task: raw.parent_task || null,
    stage: raw.stage || null,
    stages_json: raw.stages_json || '[]',
  };
  return t;
}

// ── API 接口（保持 v1.0 签名） ──

export const api = {
  // ── 核心数据 ──

  /** 聚合状态：项目列表 + 当前项目任务 + daemon 状态 */
  liveStatus: async (): Promise<LiveStatus> => {
    const [projectsMap, daemonData] = await Promise.all([
      fetchJ<{ projects: Record<string, any> }>(`${API_BASE}/api/projects`).catch(() => ({ projects: {} })),
      fetchJ<any>(`${API_BASE}/api/daemon/status`).catch(() => ({})),
    ]);

    const pids = Object.keys(projectsMap);
    const pid = _currentProjectId || pids[0] || '';
    let tasks: Task[] = [];

    if (pid) {
      try {
        const data = await fetchJ<{ tasks: any[] }>(`${API_BASE}/api/projects/${pid}/tasks`);
        tasks = (data.tasks || []).map(adaptTask);
      } catch { /* empty */ }
    }

    // 如果没有选中项目，尝试收集所有项目的任务
    if (!_currentProjectId && pids.length > 1) {
      const allTasks: Task[] = [];
      for (const p of pids) {
        try {
          const data = await fetchJ<{ tasks: any[] }>(`${API_BASE}/api/projects/${p}/tasks`);
          for (const t of (data.tasks || []).map(adaptTask)) {
            t.sourceMeta = { ...t.sourceMeta, project_id: p, project_name: (projectsMap.projects as Record<string, any>)[p]?.name || p };
            allTasks.push(t);
          }
        } catch { /* skip */ }
      }
      tasks = allTasks;
    }

    return {
      tasks,
      syncStatus: {
        ok: true,
        daemon: daemonData,
        projects: projectsMap,
        currentProject: pid,
      },
    };
  },

  /** 获取项目列表 */
  projects: async (): Promise<{ projects: Record<string, any> }> => {
    return fetchJ(`${API_BASE}/api/projects`);
  },

  /** 创建项目 */
  createProject: (data: { id?: string; name: string; description?: string | null }) =>
    postJ<ActionResult>(`${API_BASE}/api/projects`, data),

  // ── Agent 配置（v2.6 暂无，返回空） ──

  agentConfig: async (): Promise<AgentConfig> => ({
    agents: [],
    knownModels: [],
  }),

  modelChangeLog: async (): Promise<ChangeLogEntry[]> => [],

  officialsStats: async (): Promise<OfficialsData> => ({
    officials: [],
    totals: { tasks_done: 0, cost_cny: 0 },
    top_official: '',
  }),

  agentsStatus: async (): Promise<AgentsStatusData> => ({
    ok: true,
    gateway: { alive: true, probe: true, status: 'running' },
    agents: [],
    checkedAt: new Date().toISOString(),
  }),

  morningBrief: async (): Promise<MorningBrief> => ({
    categories: {},
  }),

  morningConfig: async (): Promise<SubConfig> => ({
    categories: [],
    keywords: [],
    custom_feeds: [],
    feishu_webhook: '',
  }),

  // ── 任务实时动态（v2.6 用 events 兜底） ──

  taskActivity: async (id: string): Promise<TaskActivityData> => {
    try {
      const pid = _currentProjectId || Object.keys((await api.projects()).projects)[0];
      if (!pid) return { ok: false };
      const data = await fetchJ<{ events: any[] }>(`${API_BASE}/api/projects/${pid}/tasks/${id}?include=events`);
      return { ok: true, activity: [], timeline: [] };
    } catch {
      return { ok: false };
    }
  },

  schedulerState: async (id: string): Promise<SchedulerStateData> => ({
    ok: true, scheduler: {},
  }),

  // ── 技能内容（v2.6 暂无） ──

  skillContent: async (agentId: string, skillName: string): Promise<SkillContentResult> => ({
    ok: false, error: 'Not implemented in v2.6',
  }),

  // ── 操作类 ──

  setModel: async (_agentId: string, _model: string): Promise<ActionResult> => ({ ok: false, error: 'Not implemented' }),
  setDispatchChannel: async (_channel: string): Promise<ActionResult> => ({ ok: false, error: 'Not implemented' }),
  agentWake: async (_agentId: string): Promise<ActionResult> => ({ ok: false, error: 'Not implemented' }),

  taskAction: async (taskId: string, action: string, reason: string): Promise<ActionResult> => {
    try {
      const pid = _currentProjectId || Object.keys((await api.projects()).projects)[0];
      if (!pid) return { ok: false, error: 'No project' };
      const statusMap: Record<string, string> = {
        stop: 'paused', cancel: 'cancelled', resume: 'executing',
      };
      const newStatus = statusMap[action];
      if (!newStatus) return { ok: false, error: 'Unknown action' };
      return postJ(`${API_BASE}/api/projects/${pid}/tasks/${taskId}/status`, { status: newStatus });
    } catch (e: any) {
      return { ok: false, error: e.message };
    }
  },

  taskStatusUpdate: async (taskId: string, newStatus: string): Promise<ActionResult> => {
    try {
      const pid = _currentProjectId || Object.keys((await api.projects()).projects)[0];
      if (!pid) return { ok: false, error: 'No project' };
      return postJ(`${API_BASE}/api/projects/${pid}/tasks/${taskId}/status`, { status: newStatus });
    } catch (e: any) {
      return { ok: false, error: e.message };
    }
  },

  reviewAction: async (taskId: string, action: string, comment: string): Promise<ActionResult> => {
    try {
      const pid = _currentProjectId || Object.keys((await api.projects()).projects)[0];
      if (!pid) return { ok: false, error: 'No project' };
      return postJ(`${API_BASE}/api/projects/${pid}/tasks/${taskId}/reviews`, { verdict: action, comment });
    } catch (e: any) {
      return { ok: false, error: e.message };
    }
  },

  advanceState: async (taskId: string, comment: string): Promise<ActionResult> => ({ ok: false, error: 'Not implemented' }),

  archiveTask: async (taskId: string, archived: boolean): Promise<ActionResult> => ({ ok: true }),

  archiveAllDone: async (): Promise<ActionResult & { count?: number }> => ({ ok: true, count: 0 }),

  createTask: async (data: CreateTaskPayload): Promise<ActionResult & { taskId?: string }> => {
    try {
      const pid = data.project_type || _currentProjectId || '_general';
      const prio = typeof data.priority === 'string' ? parseInt(data.priority, 10) || 5 : 5;
      const payload: any = {
        description: data.requirement || data.title || '',
        task_type: 'general',
        priority: prio,
        assigned_by: 'user',
      };
      if (data.title && data.title.trim()) payload.title = data.title.trim();
      // ID 由后端生成，不传 id 字段
      return postJ(`${API_BASE}/api/projects/${pid}/tasks`, payload);
    } catch (e: any) {
      return { ok: false, error: e.message };
    }
  },

  schedulerScan: async (thresholdSec = 180) => ({ ok: true } as any),
  schedulerRetry: async (taskId: string, reason: string) => ({ ok: false, error: 'Not implemented' } as ActionResult),
  schedulerEscalate: async (taskId: string, reason: string) => ({ ok: false, error: 'Not implemented' } as ActionResult),
  schedulerRollback: async (taskId: string, reason: string) => ({ ok: false, error: 'Not implemented' } as ActionResult),
  refreshMorning: async () => ({ ok: false, error: 'Not implemented' } as ActionResult),
  saveMorningConfig: async (config: SubConfig) => ({ ok: false, error: 'Not implemented' } as ActionResult),
  addSkill: async (..._args: any[]) => ({ ok: false, error: 'Not implemented' } as ActionResult),

  // ── 远程 Skills（v2.6 暂无） ──
  addRemoteSkill: async (..._args: any[]) => ({ ok: false, error: 'Not implemented' } as any),
  remoteSkillsList: async () => ({ ok: true, remoteSkills: [], count: 0 } as any),
  updateRemoteSkill: async (..._args: any[]) => ({ ok: false } as ActionResult),
  removeRemoteSkill: async (..._args: any[]) => ({ ok: false } as ActionResult),

  // ── M3: 成果物（v2.6 暂无后端，返回空） ──
  artifacts: async (taskId: string): Promise<ArtifactsResult> => ({
    ok: true, deliverable: null, nodes: [],
  }),

  // ── v2.7: Task 进度 + 子 Task ──

  taskProgress: async (taskId: string): Promise<TaskProgress | null> => {
    try {
      const pid = _currentProjectId || Object.keys((await api.projects()).projects)[0];
      if (!pid) return null;
      return fetchJ<TaskProgress>(`${API_BASE}/api/projects/${pid}/tasks/${taskId}/progress`);
    } catch { return null; }
  },

  listSubtasks: async (parentId: string): Promise<Task[]> => {
    try {
      const pid = _currentProjectId || Object.keys((await api.projects()).projects)[0];
      if (!pid) return [];
      const data = await fetchJ<{ tasks: any[] }>(`${API_BASE}/api/projects/${pid}/tasks?parent_task=${parentId}`);
      return (data.tasks || []).map(adaptTask);
    } catch { return []; }
  },
  artifactPreview: async (taskId: string, path: string): Promise<ArtifactPreviewResult> => ({
    ok: false, previewable: false, name: '', type: '', render_as: '', size: 0, content: null,
  }),
  artifactDownloadUrl: (taskId: string, path: string) => '',

  // ── M3: 人工干预（v2.6 暂无后端） ──
  humanInput: async (taskId: string): Promise<HumanInputResult> => ({
    ok: true, active: false, checkpoints: [],
  }),
  humanInputRespond: async (taskId: string, data: HumanInputRespondPayload) => ({ ok: false, error: 'Not implemented' } as ActionResult),

  // ── 朝堂议政（v2.6 暂无后端） ──
  courtDiscussStart: async (..._args: any[]) => ({ ok: false, error: 'Not implemented' } as CourtDiscussResult),
  courtDiscussAdvance: async (..._args: any[]) => ({ ok: false, error: 'Not implemented' } as CourtDiscussResult),
  courtDiscussConclude: async (..._args: any[]) => ({ ok: false, error: 'Not implemented' } as any),
  courtDiscussDestroy: async (..._args: any[]) => ({ ok: false } as ActionResult),
  courtDiscussFate: async () => ({ ok: true, event: '' }) as any,
};

// ── Types（保持 v1.0 完整类型定义） ──

export interface ActionResult { ok: boolean; message?: string; error?: string; }
export interface FlowEntry { at: string; from: string; to: string; remark: string; }
export interface TodoItem { id: string | number; title: string; status: 'not-started' | 'in-progress' | 'completed'; detail?: string; }
export interface Heartbeat { status: 'active' | 'warn' | 'stalled' | 'unknown' | 'idle'; label: string; }

export interface StageInfo { id: string; label: string; order: number; total: number; done: number; active: number; }

export interface TaskProgress {
  task_id: string; title: string;
  total_subtasks: number; done_subtasks: number;
  active_stage: string | null;
  stages: StageInfo[];
}

export interface Task {
  id: string; title: string; state: string; org: string; now: string;
  eta: string; block: string; ac: string; output: string;
  heartbeat: Heartbeat; flow_log: FlowEntry[]; todos: TodoItem[];
  review_round: number; archived: boolean; archivedAt?: string;
  updatedAt?: string; updated_at?: string;
  status?: string; plan_status?: string; nodes?: TaskNode[];
  latest_event?: TaskEvent; sourceMeta?: Record<string, unknown>;
  activity?: ActivityEntry[]; _prev_state?: string;
  parent_task?: string | null;
  stage?: string | null;
  stages_json?: string;
  progress?: TaskProgress;
}

export interface TaskNode {
  node_id: string; name: string; agent_id: string; status: string;
  depends_on?: string[]; output_summary?: string; output?: string;
  guard_status?: string; guard_checks?: GuardCheck[]; rollback_count?: number;
}

export interface GuardCheck { name: string; passed: boolean; message: string; severity: 'error' | 'warn' | 'info'; }
export interface TaskEvent { event_type: string; reason: string; timestamp: string; }
export interface SyncStatus { ok: boolean; [key: string]: unknown; }

export interface LiveStatus {
  tasks: Task[];
  syncStatus: SyncStatus & { daemon?: any; projects?: Record<string, any>; currentProject?: string };
}

export interface AgentInfo { id: string; label: string; emoji: string; role: string; model: string; skills: SkillInfo[]; }
export interface SkillInfo { name: string; description: string; path: string; }
export interface KnownModel { id: string; label: string; provider: string; }
export interface AgentConfig { agents: AgentInfo[]; knownModels?: KnownModel[]; dispatchChannel?: string; }
export interface ChangeLogEntry { at: string; agentId: string; oldModel: string; newModel: string; rolledBack?: boolean; }

export interface OfficialInfo {
  id: string; label: string; emoji: string; role: string; rank: string;
  model: string; model_short: string; tokens_in: number; tokens_out: number;
  cache_read: number; cache_write: number; cost_cny: number; cost_usd: number;
  sessions: number; messages: number; tasks_done: number; tasks_active: number;
  tasks_failed?: number; memorySize?: number; memoryUpdatedAt?: string;
  flow_participations: number; merit_score: number; merit_rank: number;
  last_active: string; heartbeat: Heartbeat;
  participated_edicts: { id: string; title: string; state: string; status?: string }[];
}

export interface OfficialsData { officials: OfficialInfo[]; totals: { tasks_done: number; cost_cny: number }; top_official: string; }
export interface AgentStatusInfo { id: string; label: string; emoji: string; role: string; status: string; statusLabel: string; lastActive?: string; }
export interface GatewayStatus { alive: boolean; probe: boolean; status: string; }
export interface AgentsStatusData { ok: boolean; gateway: GatewayStatus; agents: AgentStatusInfo[]; checkedAt: string; }

export interface MorningNewsItem { title: string; summary?: string; desc?: string; link: string; source: string; image?: string; pub_date?: string; }
export interface MorningBrief { date?: string; generated_at?: string; categories: Record<string, MorningNewsItem[]>; }
export interface SubCategoryConfig { name: string; enabled: boolean; }
export interface CustomFeed { name: string; url: string; category: string; }
export interface SubConfig { categories: SubCategoryConfig[]; keywords: string[]; custom_feeds: CustomFeed[]; feishu_webhook: string; }

export interface ActivityEntry {
  kind: string; at?: number | string; text?: string; thinking?: string;
  agent?: string; from?: string; to?: string; remark?: string;
  tools?: { name: string; input_preview?: string }[]; tool?: string;
  output?: string; exitCode?: number | null;
  items?: TodoItem[];
  diff?: { changed?: { id: string; from: string; to: string }[]; added?: { id: string; title: string }[]; removed?: { id: string; title: string }[] };
}

export interface PhaseDuration { phase: string; durationSec: number; durationText: string; ongoing?: boolean; }
export interface TodosSummary { total: number; completed: number; inProgress: number; notStarted: number; percent: number; }
export interface ResourceSummary { totalTokens?: number; totalCost?: number; totalElapsedSec?: number; }
export interface TimelineEntry { time: string; phase: string; node_id: string; node_name: string; agent: string; action: string; verdict: string; detail: string; }

export interface TaskActivityData {
  ok: boolean; message?: string; error?: string;
  activity?: ActivityEntry[]; timeline?: TimelineEntry[];
  relatedAgents?: string[]; agentLabel?: string; lastActive?: string;
  phaseDurations?: PhaseDuration[]; totalDuration?: string;
  todosSummary?: TodosSummary; resourceSummary?: ResourceSummary;
}

export interface SchedulerInfo { retryCount?: number; escalationLevel?: number; lastDispatchStatus?: string; stallThresholdSec?: number; enabled?: boolean; lastProgressAt?: string; lastDispatchAt?: string; lastDispatchAgent?: string; autoRollback?: boolean; }
export interface SchedulerStateData { ok: boolean; error?: string; scheduler?: SchedulerInfo; stalledSec?: number; }
export interface SkillContentResult { ok: boolean; name?: string; agent?: string; content?: string; path?: string; error?: string; }
export interface ScanAction { taskId: string; action: string; to?: string; toState?: string; stalledSec?: number; }
export interface CreateTaskPayload { title: string; org?: string; targetDept?: string; priority?: string; templateId?: string; params?: Record<string, string>; requirement?: string; project_root?: string; project_type?: string; }

export interface RemoteSkillItem { skillName: string; agentId: string; sourceUrl: string; description: string; localPath: string; addedAt: string; lastUpdated: string; status: string; }
export interface RemoteSkillsListResult { ok: boolean; remoteSkills?: RemoteSkillItem[]; count?: number; listedAt?: string; error?: string; }

export interface CourtDiscussResult { ok: boolean; session_id?: string; topic?: string; round?: number; new_messages?: Array<{ official_id: string; name: string; content: string; emotion?: string; action?: string }>; scene_note?: string; total_messages?: number; error?: string; }

export interface ArtifactEntry { name: string; path: string; size: number; type: string; render_as: string; previewable: boolean; }
export interface ArtifactNode { node_id: string; name: string; agent_id: string; status: string; artifacts: ArtifactEntry[]; }
export interface ArtifactsResult { ok: boolean; deliverable: ArtifactEntry | null; nodes: ArtifactNode[]; }
export interface ArtifactPreviewResult { ok: boolean; previewable: boolean; name: string; type: string; render_as: string; size: number; content: string | null; message?: string; }

export interface CheckpointInfo { node_id: string; node_name: string; agent_id: string; checkpoint: HumanInputCheckpoint; triggered_at: string; }
export interface HumanInputCheckpoint {
  type: 'verify' | 'decision' | 'action'; title: string; description?: string; urgency?: string;
  options?: Array<{ id: string; label: string; description?: string; pros?: string[]; cons?: string[]; recommended?: boolean }>;
  verificationSteps?: string[]; autoCheckResults?: Array<{ label: string; passed: boolean }>;
  actionSteps?: Array<{ id: string; description: string; command?: string }>;
  verificationCommand?: string;
  artifacts?: Array<{ name: string; path: string }>;
}
export interface HumanInputResult { ok: boolean; active: boolean; checkpoints: CheckpointInfo[]; }
export interface HumanInputRespondPayload { node_id?: string; action?: string; reason?: string; selected_option?: string; completed_steps?: string[]; verification_note?: string; free_text?: string; }
