import dayjs from 'dayjs';
import { getStatusTagType } from '@/constants/status-tag';

type ExecutionStatusCode = Api.Project.ProjectExecutionStatusCode;
type TaskStatusCode = Api.Project.ProjectTaskStatusCode;
type ExecutionAssigneeActionType = Api.Project.ExecutionAssigneeActionType;

/**
 * 是否在任务界面展示「父任务」相关露出（表格列 / 新建编辑下拉 / 详情只读字段）。
 * 当前业务经执行分层后极少有子任务需求，暂统一隐藏，使任务呈扁平的一级任务列表；
 * 底层父子数据与级联完成逻辑保留不动，将来恢复子任务功能改回 true 即可。
 */
export const SHOW_TASK_PARENT_FIELD = false;

export const executionAssigneeActionNameMap: Record<ExecutionAssigneeActionType, string> = {
  join: '加入',
  inactive: '失效',
  owner_transfer_in: '转入负责人',
  owner_transfer_out: '转出负责人'
};

export const EXECUTION_STATUS_ORDER = [
  'pending',
  'active',
  'paused',
  'completed',
  'cancelled'
] as const satisfies readonly ExecutionStatusCode[];

export const TASK_STATUS_ORDER = [
  'pending',
  'active',
  'paused',
  'completed',
  'cancelled'
] as const satisfies readonly TaskStatusCode[];

export const executionStatusFallbackNameMap: Record<ExecutionStatusCode, string> = {
  pending: '待开始',
  active: '进行中',
  paused: '已暂停',
  completed: '已完成',
  cancelled: '已取消'
};

export const taskStatusFallbackNameMap: Record<TaskStatusCode, string> = {
  pending: '待开始',
  active: '进行中',
  paused: '已暂停',
  completed: '已完成',
  cancelled: '已取消'
};

export function getExecutionStatusTagType(statusCode: ExecutionStatusCode | string) {
  return getStatusTagType('projectExecution', statusCode);
}

export function getTaskStatusTagType(statusCode: TaskStatusCode | string) {
  return getStatusTagType('projectTask', statusCode);
}

export function getExecutionAssigneeActionTagType(actionType: ExecutionAssigneeActionType | string) {
  return getStatusTagType('executionAssignee', actionType);
}

export function getExecutionAssigneeActionName(actionType: ExecutionAssigneeActionType | string) {
  return executionAssigneeActionNameMap[actionType as ExecutionAssigneeActionType] || actionType;
}

export function formatDate(value: string | null | undefined) {
  const parsed = dayjs(value);

  return parsed.isValid() ? parsed.format('YYYY-MM-DD') : '--';
}

export function formatDateTime(value: string | null | undefined) {
  const parsed = dayjs(value);

  return parsed.isValid() ? parsed.format('YYYY-MM-DD HH:mm:ss') : '--';
}

export function formatDateRange(startDate: string | null | undefined, endDate: string | null | undefined) {
  const startText = formatDate(startDate);
  const endText = formatDate(endDate);

  if (startText === '--' && endText === '--') {
    return '--';
  }

  return `${startText} 至 ${endText}`;
}

export function formatWorklogDateRange(startDate: string | null | undefined, endDate: string | null | undefined) {
  if (!startDate || !endDate) {
    return '--';
  }
  if (startDate === endDate) {
    return formatDate(startDate);
  }
  return `${formatDate(startDate)} ~ ${formatDate(endDate)}`;
}

export type WorklogGranularity = 'day' | 'week';

/**
 * 根据 worklog 段判定填报粒度（前端规则：startDate === endDate 视为日，否则视为周），并返回展示文案 + 悬浮提示。
 * - day：单日，display = YYYY-MM-DD，tooltip 为空
 * - week：跨日，display = YYYY年第W周（按 startDate 所在 ISO 周），tooltip = 实际起止
 */
export function formatWorklogPeriod(
  startDate: string | null | undefined,
  endDate: string | null | undefined
): { granularity: WorklogGranularity | null; display: string; tooltip: string | null } {
  if (!startDate || !endDate) {
    return { granularity: null, display: '--', tooltip: null };
  }

  // 后端可能返回带时间段的字符串（如 "2026-05-10T00:00:00"），不能直接 `===`，先归一到 YYYY-MM-DD
  const startKey = formatDate(startDate);
  const endKey = formatDate(endDate);

  if (startKey === endKey) {
    const dayDate = dayjs(startDate);
    const weekSuffix = dayDate.isValid() ? `（第${dayDate.isoWeek()}周）` : '';
    return { granularity: 'day', display: `${startKey}${weekSuffix}`, tooltip: null };
  }

  const start = dayjs(startDate);

  return {
    granularity: 'week',
    display: start.isValid() ? `${start.isoWeekYear()}年第${start.isoWeek()}周` : `${startKey} ~ ${endKey}`,
    tooltip: `${startKey} ~ ${endKey}`
  };
}

const worklogGranularityNameMap: Record<WorklogGranularity, string> = {
  day: '日',
  week: '周'
};

export function getWorklogGranularityName(granularity: WorklogGranularity | null) {
  return granularity ? worklogGranularityNameMap[granularity] : '--';
}

export function getExecutionStatusName(execution: Pick<Api.Project.ProjectExecution, 'statusCode' | 'statusName'>) {
  return execution.statusName?.trim() || executionStatusFallbackNameMap[execution.statusCode] || execution.statusCode;
}

export function getTaskStatusName(task: Pick<Api.Project.ProjectTask, 'statusCode' | 'statusName'>) {
  return task.statusName?.trim() || taskStatusFallbackNameMap[task.statusCode] || task.statusCode;
}

export function getProgressText(progressRate: number | null | undefined) {
  if (typeof progressRate !== 'number' || !Number.isFinite(progressRate)) {
    return '0%';
  }

  return `${Math.min(100, Math.max(0, progressRate))}%`;
}

export function isActiveExecutionAssignee(assignee: Pick<Api.Project.ExecutionAssignee, 'joinedAt' | 'removedAt'>) {
  if (!assignee.removedAt) {
    return true;
  }

  if (!assignee.joinedAt) {
    return false;
  }

  return dayjs(assignee.joinedAt).isAfter(dayjs(assignee.removedAt));
}

export const VIRTUAL_OWNER_ASSIGNEE_ID_PREFIX = 'virtual-owner-';

/**
 * 如果真实协办人列表里没有执行负责人（即负责人未作为协办人入库），
 * 在列表前置一条"虚拟负责人行"，仅用于 UI 上让用户感知"负责人也在团队里"。
 * 该行不会被发到后端，也不会被失效 / 设为负责人等真实操作选中。
 */
// eslint-disable-next-line max-params
export function withVirtualOwnerAssignee(
  assignees: Api.Project.ExecutionAssignee[],
  ownerId: string | null | undefined,
  ownerNickname: string,
  executionId: string
): Api.Project.ExecutionAssignee[] {
  if (!ownerId) {
    return assignees;
  }

  const ownerInList = assignees.some(item => item.userId === ownerId && isActiveExecutionAssignee(item));
  if (ownerInList) {
    return assignees;
  }

  const virtualOwner: Api.Project.ExecutionAssignee = {
    id: `${VIRTUAL_OWNER_ASSIGNEE_ID_PREFIX}${ownerId}`,
    executionId,
    userId: ownerId,
    userNickname: ownerNickname,
    joinedAt: null,
    removedAt: null,
    removedReason: null
  };
  return [virtualOwner, ...assignees];
}

export function shouldRequireTaskProgressBeforeComplete(
  action: Api.Project.LifecycleAction<Api.Project.ProjectTaskActionCode>,
  task: Api.Project.ProjectTask
) {
  return action.actionCode === 'complete' && task.progressRate !== 100;
}

/**
 * 在当前页数据集合内判定是否叶子任务：当前页中没有任何任务把它当父任务。
 * 跨页未覆盖时按"叶子"处理；后端 5.11 / 5.14 兜底拒错。
 */
export function isTaskLeafInList(row: Api.Project.ProjectTask, allRows: Api.Project.ProjectTask[]) {
  return !allRows.some(item => item.parentTaskId === row.id);
}

/**
 * 是否对该任务行展示「填报」入口（与后端工时填报矩阵 §4.8.4 对齐 + 业务事实修正）：
 * - 已登录、当前页叶子、且当前用户是 owner / 活跃协办人为基础门槛
 * - 待开始（pending）：负责人、协办人均可——首次填工时是 auto_start 触发口（无独立"开始"按钮）
 * - 进行中（active）：负责人、协办人均可
 * - 已完成（completed）：负责人、协办人均可（补录 / 修正用于报表补齐；后端不回写 task.progressRate）
 * - 已暂停 / 已取消：双方均拒
 */
export function canReportTaskWorklog(
  row: Api.Project.ProjectTask,
  allRows: Api.Project.ProjectTask[],
  currentUserId: string
) {
  if (!currentUserId) {
    return false;
  }
  if (!isTaskLeafInList(row, allRows)) {
    return false;
  }

  const isOwner = row.ownerId === currentUserId;
  const isActiveAssignee = Boolean(row.assignees?.some(item => item.userId === currentUserId));
  if (!isOwner && !isActiveAssignee) {
    return false;
  }

  return row.statusCode === 'pending' || row.statusCode === 'active' || row.statusCode === 'completed';
}

type TaskAssigneeActionType = Api.Project.TaskAssigneeActionType;

export const taskAssigneeActionNameMap: Record<TaskAssigneeActionType, string> = {
  join: '加入',
  inactive: '失效'
};

export function getTaskAssigneeActionName(actionType: TaskAssigneeActionType | string) {
  return taskAssigneeActionNameMap[actionType as TaskAssigneeActionType] || actionType;
}

export function getTaskAssigneeActionTagType(actionType: TaskAssigneeActionType | string) {
  return getStatusTagType('taskAssigneeMember', actionType);
}

/** 任务工作区的搜索模型：在 ProjectTaskSearchParams 基础上加入跨执行视角专用字段 */
export interface TaskWorkspaceSearchModel {
  keyword?: string;
  statusCode?: string;
  priority?: string;
  ownerId?: string;
  /** 跨执行视角下：限定到某个执行 */
  executionId?: string;
  /** 截止时间快速选项;仅跨执行视角下生效(新接口入参),单执行视角下后端老接口不支持,前端不下传 */
  dueRange?: 'overdue' | 'today' | 'thisWeek';
  updateTime?: string[];
}

/** worklog 提交后通过 emit 链路向上透传的 payload；workspace 据此判定是否触发完成级联 */
export interface WorklogChangedPayload {
  /** 本次操作类型：create / edit / delete */
  mode: 'create' | 'edit' | 'delete';
  /** 任务 id（worklog 所属 task） */
  taskId: string;
  /** 本次填报的进度（0~100）；delete 模式不传 */
  progressRate?: number;
}
