import type { ComputedRef } from 'vue';
import { ElMessageBox } from 'element-plus';
import { fetchGetProjectTask, fetchGetProjectTaskPage, fetchGetProjectTaskWorklogPage } from '@/service/api/project';

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

export interface CascadeTriggerPayload {
  task: ProjectTask;
  submittedProgress: number;
}

export interface UseTaskCompletionCascadeOptions {
  projectId: ComputedRef<string>;
  /** 由调用方提供：打开 StatusActionDialog 的钩子；composable 不持有 dialog 实例 */
  openStatusActionDialog: (task: ProjectTask, action: TaskAction, fromCascade: boolean) => void;
  /** 从 task 的 availableActions 里找出"完成"动作；找不到返回 null */
  resolveCompleteAction: (task: ProjectTask) => TaskAction | null;
}

interface AssigneeProgress {
  userId: string;
  nickname: string;
  /** null = 该协办人从未填过 worklog */
  latestProgress: number | null;
}

const TASK_COMPLETED_STATUS_CODE: Api.Project.ProjectTaskStatusCode = 'completed';
const NO_WARNING_CONFIRM_MESSAGE = '任务进度已达 100%，是否完成当前任务？';
const PARENT_CONFIRM_MESSAGE = '所有子任务已完成，是否完成父任务？';

function buildAssigneeWarningMessage(under100: AssigneeProgress[]): string {
  const names = under100.map(item => item.nickname).join('、');
  return `存在协办人进度未达 100%（${names}），是否仍要完成当前任务？`;
}

export function useTaskCompletionCascade(options: UseTaskCompletionCascadeOptions) {
  /**
   * worklog 提交后命中 owner + progress=100 + 非删除时由 workspace 调用。
   * 内部：拉协办人进度 → 构造 confirm 文案 → 用户确认 → 打开完成弹层
   */
  async function triggerAfterWorklog(payload: CascadeTriggerPayload): Promise<void> {
    const { task } = payload;
    const completeAction = options.resolveCompleteAction(task);
    if (!completeAction) {
      // window.$message?.warning('当前任务暂无可用完成动作');
      return;
    }

    const under100 = await loadAssigneesUnder100(task);
    const message = under100.length > 0 ? buildAssigneeWarningMessage(under100) : NO_WARNING_CONFIRM_MESSAGE;
    const messageBoxType = under100.length > 0 ? 'warning' : 'info';

    try {
      await ElMessageBox.confirm(message, '完成确认', {
        confirmButtonText: '完成任务',
        cancelButtonText: '仅保留工时',
        type: messageBoxType
      });
    } catch {
      return;
    }

    options.openStatusActionDialog(task, completeAction, true);
  }

  /**
   * 由 workspace 在 handleStatusSubmit 完成成功 + pendingCascade=true 时调用。
   * 内部：判断当前任务有无父任务 → 拉同级子任务 → 全 completed → 拉父任务详情 → owner 一致 → 弹完成提示。
   */
  async function onTaskCompleted(completedTask: ProjectTask): Promise<void> {
    if (!completedTask.parentTaskId) {
      return;
    }

    const siblings = await loadSiblings(completedTask.parentTaskId, completedTask.executionId);
    if (siblings === null) {
      window.$message?.warning('父任务级联检查失败');
      return;
    }
    const allCompleted = siblings.every(item => item.statusCode === TASK_COMPLETED_STATUS_CODE);
    if (!allCompleted) {
      return;
    }

    const parent = await fetchTaskDetail(completedTask.parentTaskId, completedTask.executionId);
    if (!parent) {
      window.$message?.warning('父任务级联检查失败');
      return;
    }

    if (parent.ownerId !== completedTask.ownerId) {
      // owner 不一致：本期不做主动通知，留待通知功能上线后由父任务负责人决策
      return;
    }

    const completeAction = options.resolveCompleteAction(parent);
    if (!completeAction) {
      window.$message?.warning('父任务暂无可用完成动作');
      return;
    }

    try {
      await ElMessageBox.confirm(PARENT_CONFIRM_MESSAGE, '完成父任务确认', {
        confirmButtonText: '完成父任务',
        cancelButtonText: '暂不完成',
        type: 'info'
      });
    } catch {
      return;
    }

    options.openStatusActionDialog(parent, completeAction, false);
  }

  /** 拉协办人进度并筛出 < 100% 的项；接口失败时返回空数组（降级到普通文案） */
  async function loadAssigneesUnder100(task: ProjectTask): Promise<AssigneeProgress[]> {
    const assignees = task.assignees ?? [];
    if (assignees.length === 0) {
      return [];
    }

    try {
      // 跨执行视角下 workspace 没有执行上下文，级联链路一律取任务自身的 executionId
      const result = await fetchGetProjectTaskWorklogPage(options.projectId.value, task.executionId, task.id, {
        pageNo: 1,
        pageSize: -1
      });
      if (result.error || !result.data) {
        return [];
      }

      // worklog 接口默认按 endDate DESC 排序，相同 userId 第一次出现的即为该用户最新一条
      const latestByUser = new Map<string, number>();
      for (const log of result.data.list) {
        if (!latestByUser.has(log.userId)) {
          latestByUser.set(log.userId, log.progressRate);
        }
      }

      const under100: AssigneeProgress[] = [];
      for (const assignee of assignees) {
        const progress = latestByUser.get(assignee.userId);
        if (progress === undefined) {
          under100.push({ userId: assignee.userId, nickname: assignee.nickname, latestProgress: null });
        } else if (progress < 100) {
          under100.push({ userId: assignee.userId, nickname: assignee.nickname, latestProgress: progress });
        }
      }
      return under100;
    } catch {
      return [];
    }
  }

  /** 拉父级下所有子任务；接口失败返回 null（与"空列表"区分，由调用方降级处理）。父子任务同执行，executionId 取被完成任务自身的值 */
  async function loadSiblings(parentTaskId: string, executionId: string): Promise<ProjectTask[] | null> {
    try {
      const result = await fetchGetProjectTaskPage(options.projectId.value, executionId, {
        pageNo: 1,
        pageSize: -1,
        parentTaskId
      });
      if (result.error || !result.data) {
        return null;
      }
      return result.data.list;
    } catch {
      return null;
    }
  }

  /** 拉父任务详情；失败返回 null */
  async function fetchTaskDetail(taskId: string, executionId: string): Promise<ProjectTask | null> {
    try {
      const result = await fetchGetProjectTask(options.projectId.value, executionId, taskId);
      if (result.error || !result.data) {
        return null;
      }
      return result.data;
    } catch {
      return null;
    }
  }

  return {
    triggerAfterWorklog,
    onTaskCompleted
  };
}
