import { WEB_SERVICE_PREFIX } from '@/constants/service';
import { request } from '../request';
import {
  type ServiceRequestResult,
  mapServiceResult,
  normalizeNullableStringId,
  normalizeStringId,
  safeJsonRequestConfig
} from './shared';
import {
  type ExecutionAssigneeLogResponse,
  type ExecutionAssigneeResponse,
  type ProjectExecutionResponse,
  type ProjectLocalDateValue,
  type ProjectMemberResponse,
  type ProjectTaskResponse,
  type TaskAssigneeFromApiResponse,
  type TaskAssigneeLogResponse,
  type TaskWorklogResponse,
  getProjectLifecycleActions,
  normalizeExecutionAssignee,
  normalizeExecutionAssigneeLog,
  normalizeProjectExecution,
  normalizeProjectLocalDate,
  normalizeProjectMember,
  normalizeProjectTask,
  normalizeTaskAssignee,
  normalizeTaskAssigneeLog,
  normalizeTaskWorklog
} from './project-shared';

const PROJECT_PREFIX = `${WEB_SERVICE_PREFIX}/project/project`;

type ProjectResponse = Omit<
  Api.Project.Project,
  'id' | 'managerUserId' | 'productId' | 'plannedStartDate' | 'plannedEndDate' | 'actualStartDate' | 'actualEndDate'
> & {
  id: string | number;
  managerUserId?: string | number | null;
  productId?: string | number | null;
  plannedStartDate?: ProjectLocalDateValue;
  plannedEndDate?: ProjectLocalDateValue;
  actualStartDate?: ProjectLocalDateValue;
  actualEndDate?: ProjectLocalDateValue;
};

type ProjectPageResponse = Api.Project.PageResult<ProjectResponse>;
type ProjectExecutionPageResponse = Api.Project.PageResult<ProjectExecutionResponse>;
type ProjectTaskPageResponse = Api.Project.PageResult<ProjectTaskResponse>;
type StatusBoardResponse = Api.Project.StatusBoard;

type ProjectContextResponse = Omit<Api.Project.ProjectContext, 'currentProject' | 'navs'> & {
  currentProject: Omit<Api.Project.ProjectContext['currentProject'], 'id'> & { id: string | number };
  navs: Array<Omit<Api.Project.ProjectContext['navs'][number], 'id'> & { id: string | number }>;
};

function getExecutionPrefix(projectId: string) {
  return `${PROJECT_PREFIX}/${projectId}/executions`;
}

function getTaskPrefix(projectId: string, executionId: string) {
  return `${getExecutionPrefix(projectId)}/${executionId}/tasks`;
}

/** 归一化项目数据 */
function normalizeProject(project: ProjectResponse): Api.Project.Project {
  return {
    ...project,
    id: normalizeStringId(project.id),
    managerUserId: normalizeNullableStringId(project.managerUserId) ?? '',
    productId: normalizeNullableStringId(project.productId),
    plannedStartDate: normalizeProjectLocalDate(project.plannedStartDate),
    plannedEndDate: normalizeProjectLocalDate(project.plannedEndDate),
    actualStartDate: normalizeProjectLocalDate(project.actualStartDate),
    actualEndDate: normalizeProjectLocalDate(project.actualEndDate)
  };
}

/** 将项目详情组装为设置页数据 */
function createProjectSettings(project: Api.Project.Project): Api.Project.ProjectSettings {
  return {
    baseInfo: {
      id: project.id,
      projectCode: project.projectCode,
      projectName: project.projectName,
      directionCode: project.directionCode,
      projectType: project.projectType,
      productId: project.productId,
      productName: project.productName ?? null,
      managerUserId: project.managerUserId,
      managerUserNickname: project.managerUserNickname ?? null,
      statusCode: project.statusCode,
      plannedStartDate: project.plannedStartDate,
      plannedEndDate: project.plannedEndDate,
      actualStartDate: project.actualStartDate,
      actualEndDate: project.actualEndDate,
      projectDesc: project.projectDesc,
      lastStatusReason: project.lastStatusReason
    },
    lifecycle: {
      statusCode: project.statusCode,
      lastStatusReason: project.lastStatusReason,
      availableActions: getProjectLifecycleActions(project.statusCode)
    }
  };
}

/** 获取项目分页 */
export async function fetchGetProjectPage(params?: Api.Project.ProjectSearchParams) {
  const result = await request<ProjectPageResponse>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/page`,
    method: 'get',
    params
  });

  return mapServiceResult(result as ServiceRequestResult<ProjectPageResponse>, data => ({
    ...data,
    list: data.list.map(normalizeProject)
  }));
}

/** 获取项目入口页概览统计 */
export function fetchGetProjectOverviewSummary() {
  return request<Api.Project.ProjectOverviewSummary>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/overview-summary`,
    method: 'get'
  });
}

/** 获取项目详情 */
export async function fetchGetProject(id: string) {
  const result = await request<ProjectResponse>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/get`,
    method: 'get',
    params: { id }
  });

  return mapServiceResult(result as ServiceRequestResult<ProjectResponse>, normalizeProject);
}

/** 根据产品ID获取产品下的所有项目 */
export async function fetchGetProjectListByProductId(productId: string) {
  const result = await request<ProjectResponse[]>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/list-by-product`,
    method: 'get',
    params: { productId }
  });

  return mapServiceResult(result as ServiceRequestResult<ProjectResponse[]>, data => data.map(normalizeProject));
}

/** 创建项目 */
export async function fetchCreateProject(data: Api.Project.SaveProjectParams) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/create`,
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}

/** 创建项目（含初始团队，原子接口） */
export async function fetchCreateProjectWithTeam(data: Api.Project.CreateProjectWithTeamParams) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/create-with-team`,
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}

/** 更新项目 */
export function fetchUpdateProject(data: Api.Project.UpdateProjectParams) {
  return request<boolean>({
    url: `${PROJECT_PREFIX}/update`,
    method: 'put',
    data
  });
}

/** 变更项目状态 */
export function fetchChangeProjectStatus(data: Api.Project.ChangeProjectStatusParams) {
  return request<boolean>({
    url: `${PROJECT_PREFIX}/change-status`,
    method: 'post',
    data
  });
}

/** 删除项目 */
export function fetchDeleteProject(data: Api.Project.DeleteProjectParams) {
  return request<boolean>({
    url: `${PROJECT_PREFIX}/delete`,
    method: 'post',
    data
  });
}

/** 获取项目上下文 */
export async function fetchGetProjectContext(id: string) {
  const result = await request<ProjectContextResponse>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/${id}/context`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<ProjectContextResponse>, data => ({
    ...data,
    currentProject: {
      ...data.currentProject,
      id: normalizeStringId(data.currentProject.id)
    },
    navs: data.navs.map(nav => ({
      ...nav,
      id: normalizeStringId(nav.id)
    }))
  }));
}

/** 获取项目成员列表 */
export async function fetchGetProjectMembers(id: string) {
  const result = await request<ProjectMemberResponse[]>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/${id}/members`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<ProjectMemberResponse[]>, data =>
    data.map(normalizeProjectMember)
  );
}

/** 创建项目成员 */
export async function fetchCreateProjectMember(id: string, data: Api.Project.CreateProjectMemberParams) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/${id}/members`,
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}

/** 更新项目成员 */
export function fetchUpdateProjectMember(id: string, memberId: string, data: Api.Project.UpdateProjectMemberParams) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/${id}/members/${memberId}`,
    method: 'put',
    data
  });
}

/** 移出项目成员 */
export function fetchInactiveProjectMember(
  id: string,
  memberId: string,
  data: Api.Project.InactiveProjectMemberParams
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${PROJECT_PREFIX}/${id}/members/${memberId}/inactive`,
    method: 'post',
    data
  });
}

/** 获取项目设置 */
export async function fetchGetProjectSettings(id: string) {
  const result = await fetchGetProject(id);

  if (result.error || !result.data) {
    return result as ServiceRequestResult<Api.Project.ProjectSettings>;
  }

  return {
    ...result,
    data: createProjectSettings(result.data)
  };
}

/** 更新项目设置基础信息 */
export async function fetchUpdateProjectSettingBaseInfo(
  id: string,
  data: Api.Project.UpdateProjectSettingBaseInfoParams
) {
  const detailResult = await fetchGetProject(id);

  if (detailResult.error || !detailResult.data) {
    return detailResult as ServiceRequestResult<boolean>;
  }

  return fetchUpdateProject({
    id,
    projectCode: detailResult.data.projectCode,
    projectName: data.projectName,
    directionCode: data.directionCode,
    projectType: data.projectType,
    productId: detailResult.data.productId,
    managerUserId: detailResult.data.managerUserId,
    plannedStartDate: data.plannedStartDate,
    plannedEndDate: data.plannedEndDate,
    actualStartDate: detailResult.data.actualStartDate,
    actualEndDate: detailResult.data.actualEndDate,
    projectDesc: data.projectDesc
  });
}

/** 获取项目执行分页 */
export async function fetchGetProjectExecutionPage(
  projectId: string,
  params?: Api.Project.ProjectExecutionSearchParams
) {
  const result = await request<ProjectExecutionPageResponse>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/page`,
    method: 'get',
    params
  });

  return mapServiceResult(result as ServiceRequestResult<ProjectExecutionPageResponse>, data => ({
    ...data,
    list: data.list.map(normalizeProjectExecution)
  }));
}

/** 获取项目执行状态看板 */
export function fetchGetProjectExecutionStatusBoard(
  projectId: string,
  params?: Api.Project.ProjectExecutionStatusBoardParams
) {
  return request<StatusBoardResponse>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/status-board`,
    method: 'get',
    params
  });
}

/** 获取项目执行详情 */
export async function fetchGetProjectExecution(projectId: string, executionId: string) {
  const result = await request<ProjectExecutionResponse>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/${executionId}`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<ProjectExecutionResponse>, normalizeProjectExecution);
}

/** 创建项目执行 */
export async function fetchCreateProjectExecution(projectId: string, data: Api.Project.CreateProjectExecutionParams) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: getExecutionPrefix(projectId),
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}

/** 更新项目执行 */
export function fetchUpdateProjectExecution(
  projectId: string,
  executionId: string,
  data: Api.Project.UpdateProjectExecutionParams
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/${executionId}`,
    method: 'put',
    data
  });
}

/** 变更项目执行负责人 */
export function fetchChangeProjectExecutionOwner(
  projectId: string,
  executionId: string,
  data: Api.Project.ChangeExecutionOwnerParams
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/${executionId}/change-owner`,
    method: 'post',
    data
  });
}

/** 删除项目执行 */
export function fetchDeleteProjectExecution(
  projectId: string,
  executionId: string,
  data: Api.Project.DeleteProjectExecutionParams
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/${executionId}`,
    method: 'delete',
    data
  });
}

/** 变更项目执行状态 */
export function fetchChangeProjectExecutionStatus(
  projectId: string,
  executionId: string,
  data: Api.Project.ChangeExecutionStatusParams
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/${executionId}/change-status`,
    method: 'post',
    data
  });
}

/** 获取项目执行协办人 */
export async function fetchGetProjectExecutionAssignees(projectId: string, executionId: string) {
  const result = await request<ExecutionAssigneeResponse[]>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/${executionId}/assignees`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<ExecutionAssigneeResponse[]>, data =>
    data.map(normalizeExecutionAssignee)
  );
}

/** 创建项目执行协办人 */
export async function fetchCreateProjectExecutionAssignee(
  projectId: string,
  executionId: string,
  data: Api.Project.CreateExecutionAssigneeParams
) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/${executionId}/assignees`,
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}

/** 移除项目执行协办人 */
export function fetchInactiveProjectExecutionAssignee(
  projectId: string,
  executionId: string,
  payload: { assigneeId: string; data: Api.Project.InactiveExecutionAssigneeParams }
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/${executionId}/assignees/${payload.assigneeId}/inactive`,
    method: 'post',
    data: payload.data
  });
}

/** 获取项目执行协办人变更历史分页 */
export async function fetchGetProjectExecutionAssigneeLogPage(
  projectId: string,
  executionId: string,
  params?: Api.Project.ExecutionAssigneeLogSearchParams
) {
  const result = await request<Api.Project.PageResult<ExecutionAssigneeLogResponse>>({
    ...safeJsonRequestConfig,
    url: `${getExecutionPrefix(projectId)}/${executionId}/assignee-logs`,
    method: 'get',
    params
  });

  return mapServiceResult(
    result as ServiceRequestResult<Api.Project.PageResult<ExecutionAssigneeLogResponse>>,
    data => ({
      ...data,
      list: data.list.map(normalizeExecutionAssigneeLog)
    })
  );
}

/** 获取项目任务分页 */
export async function fetchGetProjectTaskPage(
  projectId: string,
  executionId: string,
  params?: Api.Project.ProjectTaskSearchParams
) {
  const result = await request<ProjectTaskPageResponse>({
    ...safeJsonRequestConfig,
    url: `${getTaskPrefix(projectId, executionId)}/page`,
    method: 'get',
    params
  });

  return mapServiceResult(result as ServiceRequestResult<ProjectTaskPageResponse>, data => ({
    ...data,
    list: data.list.map(normalizeProjectTask)
  }));
}

/** 获取项目任务状态看板 */
export function fetchGetProjectTaskStatusBoard(
  projectId: string,
  executionId: string,
  params?: Api.Project.ProjectTaskStatusBoardParams
) {
  return request<StatusBoardResponse>({
    ...safeJsonRequestConfig,
    url: `${getTaskPrefix(projectId, executionId)}/status-board`,
    method: 'get',
    params
  });
}

/** 获取项目任务详情 */
export async function fetchGetProjectTask(projectId: string, executionId: string, taskId: string) {
  const result = await request<ProjectTaskResponse>({
    ...safeJsonRequestConfig,
    url: `${getTaskPrefix(projectId, executionId)}/${taskId}`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<ProjectTaskResponse>, normalizeProjectTask);
}

/** 创建项目任务 */
export async function fetchCreateProjectTask(
  projectId: string,
  executionId: string,
  data: Api.Project.SaveProjectTaskParams
) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: getTaskPrefix(projectId, executionId),
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}

/** 更新项目任务 */
export function fetchUpdateProjectTask(
  projectId: string,
  executionId: string,
  payload: { taskId: string; data: Api.Project.SaveProjectTaskParams }
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getTaskPrefix(projectId, executionId)}/${payload.taskId}`,
    method: 'put',
    data: payload.data
  });
}

/** 删除项目任务 */
// eslint-disable-next-line max-params
export function fetchDeleteProjectTask(
  projectId: string,
  executionId: string,
  taskId: string,
  data: Api.Project.DeleteProjectTaskParams
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getTaskPrefix(projectId, executionId)}/${taskId}`,
    method: 'delete',
    data
  });
}

/** 变更项目任务状态 */
export function fetchChangeProjectTaskStatus(
  projectId: string,
  executionId: string,
  payload: { taskId: string; data: Api.Project.ChangeTaskStatusParams }
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getTaskPrefix(projectId, executionId)}/${payload.taskId}/change-status`,
    method: 'post',
    data: payload.data
  });
}

type TaskWorklogPageResponse = Api.Project.PageResult<TaskWorklogResponse>;

function getWorklogPrefix(projectId: string, executionId: string, taskId: string) {
  return `${getTaskPrefix(projectId, executionId)}/${taskId}/worklogs`;
}

/** 获取任务工时分页 */
// eslint-disable-next-line max-params
export async function fetchGetProjectTaskWorklogPage(
  projectId: string,
  executionId: string,
  taskId: string,
  params?: Api.Project.TaskWorklogSearchParams
) {
  const result = await request<TaskWorklogPageResponse>({
    ...safeJsonRequestConfig,
    url: getWorklogPrefix(projectId, executionId, taskId),
    method: 'get',
    params
  });

  return mapServiceResult(result as ServiceRequestResult<TaskWorklogPageResponse>, data => ({
    ...data,
    list: data.list.map(normalizeTaskWorklog)
  }));
}

/** 新增任务工时 */
// eslint-disable-next-line max-params
export async function fetchCreateProjectTaskWorklog(
  projectId: string,
  executionId: string,
  taskId: string,
  data: Api.Project.SaveTaskWorklogParams
) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: getWorklogPrefix(projectId, executionId, taskId),
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}

/** 修改任务工时 */
// eslint-disable-next-line max-params
export function fetchUpdateProjectTaskWorklog(
  projectId: string,
  executionId: string,
  taskId: string,
  payload: { worklogId: string; data: Api.Project.SaveTaskWorklogParams }
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getWorklogPrefix(projectId, executionId, taskId)}/${payload.worklogId}`,
    method: 'put',
    data: payload.data
  });
}

/** 删除任务工时 */
// eslint-disable-next-line max-params
export function fetchDeleteProjectTaskWorklog(
  projectId: string,
  executionId: string,
  taskId: string,
  worklogId: string
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getWorklogPrefix(projectId, executionId, taskId)}/${worklogId}`,
    method: 'delete'
  });
}

/** 5.6 获取任务协办人列表（仅当前活跃） */
export async function fetchGetProjectTaskAssignees(projectId: string, executionId: string, taskId: string) {
  const result = await request<TaskAssigneeFromApiResponse[]>({
    ...safeJsonRequestConfig,
    url: `${getTaskPrefix(projectId, executionId)}/${taskId}/assignees`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<TaskAssigneeFromApiResponse[]>, data =>
    data.map(normalizeTaskAssignee)
  );
}

/** 5.7 加入任务协办人 */
// eslint-disable-next-line max-params
export async function fetchCreateProjectTaskAssignee(
  projectId: string,
  executionId: string,
  taskId: string,
  data: Api.Project.CreateTaskAssigneeParams
) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${getTaskPrefix(projectId, executionId)}/${taskId}/assignees`,
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}

/** 5.8 退出任务协办人 */
// eslint-disable-next-line max-params
export function fetchInactiveProjectTaskAssignee(
  projectId: string,
  executionId: string,
  taskId: string,
  assigneeId: string,
  data: Api.Project.InactiveTaskAssigneeParams
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${getTaskPrefix(projectId, executionId)}/${taskId}/assignees/${assigneeId}/inactive`,
    method: 'post',
    data
  });
}

/** 5.9 任务协办人变更历史分页 */
// eslint-disable-next-line max-params
export async function fetchGetProjectTaskAssigneeLogPage(
  projectId: string,
  executionId: string,
  taskId: string,
  params?: Api.Project.TaskAssigneeLogSearchParams
) {
  const result = await request<Api.Project.PageResult<TaskAssigneeLogResponse>>({
    ...safeJsonRequestConfig,
    url: `${getTaskPrefix(projectId, executionId)}/${taskId}/assignee-logs`,
    method: 'get',
    params
  });

  return mapServiceResult(result as ServiceRequestResult<Api.Project.PageResult<TaskAssigneeLogResponse>>, data => ({
    ...data,
    list: data.list.map(normalizeTaskAssigneeLog)
  }));
}
