import { taskStatusFallbackNameMap } from '../shared';

type ProjectTask = Api.Project.ProjectTask;
type TaskActionCode = Api.Project.ProjectTaskActionCode;
type TaskStatusCode = Api.Project.ProjectTaskStatusCode;
type TaskAction = Api.Project.LifecycleAction<TaskActionCode>;

/**
 * 任务 actionCode → 目标 statusCode 映射。
 * 看板拖拽用此映射把"拖到哪一列"反查出"应该走哪个动作",再去 task.availableActions 里找匹配项。
 * auto_start 是后端在填工时自动触发,前端不暴露(useTaskActions 也做了同样过滤)。
 */
export const TASK_ACTION_TO_STATUS_CODE: Record<TaskActionCode, TaskStatusCode> = {
  auto_start: 'active',
  pause: 'paused',
  resume: 'active',
  complete: 'completed',
  cancel: 'cancelled'
};

export type DragResolution = { ok: true; action: TaskAction } | { ok: false; reason: string | null };

/**
 * 判定"把 task 拖到 targetStatusCode 列"是否合法,合法时返回应触发的 action。
 *
 * - 同列(statusCode 相等):静默拒绝(看板不支持同列手动排序)
 * - 不在 task.availableActions 内的目标列:拒绝,带文案
 * - complete 动作下进度 < 100:拒绝,带文案(复刻按钮的兜底)
 * - auto_start:不走拖拽通道
 */
export function resolveTaskDragAction(task: ProjectTask, targetStatusCode: string): DragResolution {
  if (task.statusCode === targetStatusCode) {
    return { ok: false, reason: null };
  }

  const candidate = task.availableActions.find(
    action => action.actionCode !== 'auto_start' && TASK_ACTION_TO_STATUS_CODE[action.actionCode] === targetStatusCode
  );

  if (!candidate) {
    const targetName = taskStatusFallbackNameMap[targetStatusCode as TaskStatusCode] || targetStatusCode;
    return { ok: false, reason: `当前任务不能直接变更为「${targetName}」` };
  }

  if (candidate.actionCode === 'complete' && task.progressRate < 100) {
    return { ok: false, reason: '完成任务前请先将进度调整为 100%' };
  }

  return { ok: true, action: candidate };
}

/**
 * 卡片"是否允许拖起"。
 *
 * - 执行已 completed/cancelled (跨执行视角下灰显卡片):禁拖
 * - availableActions 为空(后端按当前用户上下文已过滤):禁拖
 *   → 自然覆盖"不是负责人 / 无权限 / 终态任务 / paused 等无出度"全部场景,口径与按钮完全一致
 * - 仅剩 auto_start 时也禁拖(无可暴露动作)
 */
export function isTaskDraggable(task: ProjectTask, options: { executionLocked?: boolean } = {}): boolean {
  if (options.executionLocked) return false;
  if (!task.availableActions.length) return false;
  return task.availableActions.some(action => action.actionCode !== 'auto_start');
}
