import { WEB_SERVICE_PREFIX } from '@/constants/service';
import { request } from '../request';
import {
  type ServiceRequestResult,
  mapServiceResult,
  normalizeNullableStringId,
  normalizeStringId,
  safeJsonRequestConfig
} from './shared';
import { normalizeProductMember, normalizeProductSettings } from './product-shared';

const PRODUCT_PREFIX = `${WEB_SERVICE_PREFIX}/project/product`;

type ProductResponse = Omit<Api.Product.Product, 'id' | 'managerUserId' | 'currentUserRoles'> & {
  id: string | number;
  managerUserId?: string | number | null;
  /** 灰度/兼容期后端可能缺省，适配层兜底为 [] */
  currentUserRoles?: Api.Common.CurrentUserRole[] | null;
};

type ProductOptionResponse = Omit<Api.Product.ProductOption, 'id'> & {
  id: string | number;
};

type ProductPageResponse = Api.Product.PageResult<ProductResponse>;

type ProductActivityTimelineItemResponse = Omit<
  Api.Product.ProductActivityTimelineItem,
  'id' | 'operatorUserId' | 'targetUserId' | 'occurredAt'
> & {
  id: string | number;
  operatorUserId?: string | number | null;
  targetUserId?: string | number | null;
  occurredAt: number | string;
};

type ProductActivityTimelinePageResponse = Omit<
  Api.Product.PageResult<ProductActivityTimelineItemResponse>,
  'total'
> & {
  total: number | string;
};

function normalizeProduct(product: ProductResponse): Api.Product.Product {
  return {
    ...product,
    id: normalizeStringId(product.id),
    managerUserId: normalizeNullableStringId(product.managerUserId) ?? '',
    currentUserRoles: product.currentUserRoles ?? []
  };
}

function normalizeProductOption(option: ProductOptionResponse): Api.Product.ProductOption {
  return {
    ...option,
    id: normalizeStringId(option.id)
  };
}

function normalizeOccurredAt(occurredAt: number | string) {
  const value = Number(occurredAt);

  return Number.isFinite(value) ? value : 0;
}

function normalizePageTotal(total: number | string) {
  const value = Number(total);

  return Number.isFinite(value) ? Math.max(0, value) : 0;
}

function normalizeProductActivityTimelineItem(
  item: ProductActivityTimelineItemResponse
): Api.Product.ProductActivityTimelineItem {
  return {
    ...item,
    id: normalizeStringId(item.id),
    operatorUserId: normalizeNullableStringId(item.operatorUserId),
    targetUserId: normalizeNullableStringId(item.targetUserId),
    occurredAt: normalizeOccurredAt(item.occurredAt)
  };
}

function createProductActivityTimelinePageQuery(params: Api.Product.ProductActivityTimelinePageParams) {
  const query = new URLSearchParams();

  query.append('pageNo', String(params.pageNo));
  query.append('pageSize', String(params.pageSize));

  if (params.activityType) {
    query.append('activityType', params.activityType);
  }

  params.actionTypes?.forEach(actionType => {
    if (actionType) {
      query.append('actionTypes', actionType);
    }
  });

  if (params.startTime && params.endTime) {
    query.append('startTime', params.startTime);
    query.append('endTime', params.endTime);
  }

  return query.toString();
}

/** 获取产品分页 */
export async function fetchGetProductPage(params?: Api.Product.ProductSearchParams) {
  const result = await request<ProductPageResponse>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/page`,
    method: 'get',
    params
  });

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

/** 获取可绑定产品下拉选项 */
export async function fetchGetProductOptions() {
  const result = await request<ProductOptionResponse[]>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/options`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<ProductOptionResponse[]>, data =>
    (data ?? []).map(normalizeProductOption)
  );
}

type ProductOverviewSummaryResponse = Omit<Api.Product.ProductOverviewSummary, 'total' | 'items'> & {
  /** 后端 overview-summary 升级（total/items）灰度期间可能缺省，适配层兜底 */
  total?: number | null;
  items?: Api.Product.OverviewStatusItem[] | null;
};

/** 归一化产品概览统计：total/items 兜底，保证业务层拿到完整结构 */
function normalizeProductOverviewSummary(data: ProductOverviewSummaryResponse): Api.Product.ProductOverviewSummary {
  return {
    ...data,
    statusCounts: data.statusCounts ?? {},
    total: data.total ?? 0,
    items: data.items ?? []
  };
}

/** 获取产品入口页概览统计 */
export async function fetchGetProductOverviewSummary() {
  const result = await request<ProductOverviewSummaryResponse>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/overview-summary`,
    method: 'get'
  });

  return mapServiceResult(
    result as ServiceRequestResult<ProductOverviewSummaryResponse>,
    normalizeProductOverviewSummary
  );
}

/** 获取产品详情 */
export async function fetchGetProduct(id: string) {
  const result = await request<ProductResponse>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/get`,
    method: 'get',
    params: { id }
  });

  return mapServiceResult(result as ServiceRequestResult<ProductResponse>, normalizeProduct);
}

/** 新增产品 */
export async function fetchCreateProduct(data: Api.Product.SaveProductParams) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/create`,
    method: 'post',
    data
  });

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

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

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

/** 更新产品 */
export function fetchUpdateProduct(data: Api.Product.UpdateProductParams) {
  return request<boolean>({
    url: `${PRODUCT_PREFIX}/update`,
    method: 'put',
    data
  });
}

/** 改变产品状态 */
export function fetchChangeProductStatus(data: Api.Product.ChangeProductStatusParams) {
  return request<boolean>({
    url: `${PRODUCT_PREFIX}/change-status`,
    method: 'post',
    data
  });
}

/** 删除产品 */
export function fetchDeleteProduct(data: Api.Product.DeleteProductParams) {
  return request<boolean>({
    url: `${PRODUCT_PREFIX}/delete`,
    method: 'post',
    data
  });
}

// ========== 产品需求 API ==========
const REQUIREMENT_PREFIX = `${WEB_SERVICE_PREFIX}/project/product/requirement`;

type RequirementResponse = Omit<
  Api.Product.Requirement,
  | 'id'
  | 'parentId'
  | 'moduleId'
  | 'proposerId'
  | 'currentHandlerUserId'
  | 'implementProjectId'
  | 'sourceBizCode'
  | 'attachments'
> & {
  id: string | number;
  parentId: string | number;
  moduleId: string | number;
  proposerId: string | number;
  currentHandlerUserId?: string | number | null;
  implementProjectId?: string | number | null;
  implementProjectName?: string | null;
  sourceBizCode?: string | null;
  attachments?: AttachmentItemResponse[] | null;
  children?: RequirementResponse[];
};

type RequirementPageResponse = Api.Product.PageResult<RequirementResponse>;
type RequirementReviewResponse = Omit<
  Api.Product.RequirementReview,
  'id' | 'requirementId' | 'operatorId' | 'attendees' | 'attachments'
> & {
  id: string | number;
  requirementId: string | number;
  operatorId: string | number;
  attendees?: Array<{
    userId: string | number;
    nickname: string;
  }>;
  attachments?: AttachmentItemResponse[] | null;
};
type ProductRequirementDashboardSummaryResponse = {
  total?: number | string | null;
  todo?: number | string | null;
  pendingClaim?: number | string | null;
  pendingReview?: number | string | null;
  pendingDispatch?: number | string | null;
  completed?: number | string | null;
  completionRate?: number | string | null;
  highPriorityTodo?: number | string | null;
};
type ProductRequirementDashboardRecentChangeResponse = Omit<
  Api.Product.ProductRequirementDashboardRecentChange,
  'id' | 'requirementId' | 'operatorUserId'
> & {
  id: string | number;
  requirementId?: string | number | null;
  operatorUserId?: string | number | null;
};
type ProductRequirementDashboardResponse = {
  summary?: ProductRequirementDashboardSummaryResponse | null;
  recentChanges?: ProductRequirementDashboardRecentChangeResponse[] | null;
};

type AttachmentItemResponse = Omit<Api.Project.AttachmentItem, 'fileId'> & {
  fileId?: string | number;
  id?: string | number;
};

function normalizeAttachments(list?: AttachmentItemResponse[] | null): Api.Project.AttachmentItem[] | null {
  if (!list) {
    return null;
  }

  return list.map(item => {
    const rawId = item.fileId ?? item.id;

    return {
      ...item,
      fileId: rawId === null || rawId === undefined ? '' : String(rawId)
    };
  });
}

function normalizeRequirement(requirement: RequirementResponse): Api.Product.Requirement {
  return {
    ...requirement,
    id: normalizeStringId(requirement.id),
    parentId: normalizeStringId(requirement.parentId),
    moduleId: normalizeStringId(requirement.moduleId),
    proposerId: normalizeStringId(requirement.proposerId),
    currentHandlerUserId: normalizeNullableStringId(requirement.currentHandlerUserId),
    implementProjectId: normalizeNullableStringId(requirement.implementProjectId),
    implementProjectName: requirement.implementProjectName ?? null,
    sourceBizCode: requirement.sourceBizCode ?? null,
    attachments: normalizeAttachments(requirement.attachments),
    children: requirement.children?.map(normalizeRequirement)
  };
}

function normalizeRequirementReview(review: RequirementReviewResponse): Api.Product.RequirementReview {
  return {
    ...review,
    id: normalizeStringId(review.id),
    requirementId: normalizeStringId(review.requirementId),
    operatorId: normalizeStringId(review.operatorId),
    attendees: review.attendees?.map(item => ({
      ...item,
      userId: normalizeStringId(item.userId)
    })),
    attachments: normalizeAttachments(review.attachments)
  };
}

function normalizeDashboardCount(value: number | string | null | undefined) {
  const count = Number(value ?? 0);

  return Number.isFinite(count) ? Math.max(0, count) : 0;
}

function normalizeProductRequirementDashboard(
  data: ProductRequirementDashboardResponse
): Api.Product.ProductRequirementDashboard {
  const summary = data.summary ?? {};

  return {
    summary: {
      total: normalizeDashboardCount(summary.total),
      todo: normalizeDashboardCount(summary.todo),
      pendingClaim: normalizeDashboardCount(summary.pendingClaim),
      pendingReview: normalizeDashboardCount(summary.pendingReview),
      pendingDispatch: normalizeDashboardCount(summary.pendingDispatch),
      completed: normalizeDashboardCount(summary.completed),
      completionRate: Math.min(100, normalizeDashboardCount(summary.completionRate)),
      highPriorityTodo: normalizeDashboardCount(summary.highPriorityTodo)
    },
    recentChanges: (data.recentChanges ?? []).map(item => ({
      ...item,
      id: normalizeStringId(item.id),
      requirementId: normalizeNullableStringId(item.requirementId),
      operatorUserId: normalizeNullableStringId(item.operatorUserId)
    }))
  };
}

/** 获取需求分页列表 */
export async function fetchGetRequirementPage(params?: Api.Product.RequirementSearchParams) {
  const result = await request<RequirementPageResponse>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/page`,
    method: 'get',
    params
  });

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

/** 获取需求树形列表（支持分页，pageSize只算父需求） */
export async function fetchGetRequirementTree(params?: Api.Product.RequirementSearchParams) {
  const result = await request<Api.Product.PageResult<RequirementResponse>>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/tree`,
    method: 'get',
    params
  });

  return mapServiceResult(result as ServiceRequestResult<Api.Product.PageResult<RequirementResponse>>, data => ({
    ...data,
    list: data.list.map(normalizeRequirement)
  }));
}

/** 获取需求详情 */
export async function fetchGetRequirement(id: string, productId: string) {
  const result = await request<RequirementResponse>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/get`,
    method: 'get',
    params: { id, productId }
  });

  return mapServiceResult(result as ServiceRequestResult<RequirementResponse>, normalizeRequirement);
}

/** 创建需求 */
export async function fetchCreateRequirement(data: Api.Product.SaveRequirementParams) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/create`,
    method: 'post',
    data
  });

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

/** 更新需求 */
export function fetchUpdateRequirement(data: Api.Product.UpdateRequirementParams) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/update`,
    method: 'put',
    data
  });
}

/** 变更需求状态 */
export function fetchChangeRequirementStatus(data: Api.Product.ChangeRequirementStatusParams) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/change-status`,
    method: 'post',
    data
  });
}

/** 删除需求 */
export function fetchDeleteRequirement(data: Api.Product.DeleteRequirementParams) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/delete`,
    method: 'post',
    data
  });
}

/** 拆分需求 */
export async function fetchSplitRequirement(data: Api.Product.SplitRequirementParams) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/split`,
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}
/** 获取需求可执行的状态动作列表 */
export async function fetchGetRequirementAllowedTransitions(requirementId: string, productId: string) {
  const result = await request<Api.Product.RequirementLifecycleAction[]>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/allowed-transitions`,
    method: 'get',
    params: { requirementId, productId }
  });

  return mapServiceResult(result as ServiceRequestResult<Api.Product.RequirementLifecycleAction[]>, data => data);
}

/** 批量获取需求可执行的状态动作列表 */
export async function fetchGetRequirementAllowedTransitionsBatch(data: Api.Product.RequirementBatchReqVO) {
  const result = await request<Api.Product.RequirementAllowedTransitionBatchRespVO[]>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/allowed-transitions/batch`,
    method: 'post',
    data
  });

  return mapServiceResult(
    result as ServiceRequestResult<Api.Product.RequirementAllowedTransitionBatchRespVO[]>,
    data1 =>
      data1.map(item => ({
        requirementId: normalizeStringId(item.requirementId),
        transitions: item.transitions
      }))
  );
}

/** 提交产品需求评审 */
export async function fetchSubmitProductRequirementReview(data: Api.Product.RequirementReviewSubmitParams) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/review/submit`,
    method: 'post',
    data
  });

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

/** 获取产品需求评审记录 */
export async function fetchGetProductRequirementReview(productId: string, requirementId: string) {
  const result = await request<RequirementReviewResponse>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/review/get`,
    method: 'get',
    params: { productId, requirementId }
  });

  return mapServiceResult(result as ServiceRequestResult<RequirementReviewResponse>, normalizeRequirementReview);
}

/** 获取产品概览需求池实时看板 */
export async function fetchGetProductRequirementDashboard(productId: string) {
  const result = await request<ProductRequirementDashboardResponse>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/dashboard`,
    method: 'get',
    params: { productId }
  });

  return mapServiceResult(
    result as ServiceRequestResult<ProductRequirementDashboardResponse>,
    normalizeProductRequirementDashboard
  );
}

/** 获取需求所有状态字典 */
export async function fetchGetRequirementStatusDict() {
  const result = await request<Api.Product.RequirementStatusDict[]>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/status/dict`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<Api.Product.RequirementStatusDict[]>, data => data);
}

/** 判断产品需求是否已指派并生成项目需求 */
export async function fetchHasDispatchedProjectRequirement(requirementId: string, productId: string) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/has-dispatched`,
    method: 'get',
    params: { requirementId, productId }
  });
}

/** 批量判断产品需求是否已指派并生成项目需求 */
export async function fetchHasDispatchedProjectRequirementBatch(data: Api.Product.RequirementBatchReqVO) {
  const result = await request<Api.Product.RequirementHasDispatchedBatchRespVO[]>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/has-dispatched/batch`,
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<Api.Product.RequirementHasDispatchedBatchRespVO[]>, data1 =>
    data1.map(item => ({
      requirementId: normalizeStringId(item.requirementId),
      hasDispatched: Boolean(item.hasDispatched)
    }))
  );
}

/** 根据当前产品需求id获取对应地，所流转到项目侧的项目需求id */
export async function fetchGetDispatchedProjectLink(productRequirementId: string) {
  return request<{ projectRequirementId: string; projectId: string }>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/dispatched-project-link`,
    method: 'get',
    params: { productRequirementId }
  });
}

// ========== 模块管理 API ==========
type RequirementModuleResponse = Omit<Api.Product.RequirementModule, 'id' | 'parentId' | 'productId'> & {
  id: string | number;
  parentId: string | number;
  productId: string | number;
  children?: RequirementModuleResponse[];
};

function normalizeRequirementModule(module: RequirementModuleResponse): Api.Product.RequirementModule {
  return {
    ...module,
    id: normalizeStringId(module.id),
    parentId: normalizeStringId(module.parentId),
    productId: normalizeStringId(module.productId),
    children: module.children?.map(normalizeRequirementModule)
  };
}

/** 获取需求模块树 */
export async function fetchGetRequirementModuleTree(productId: string) {
  const result = await request<RequirementModuleResponse[]>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/module/tree`,
    method: 'get',
    params: { productId }
  });

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

/** 创建需求模块 */
export async function fetchCreateRequirementModule(data: Api.Product.SaveRequirementModuleParams) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/module/create`,
    method: 'post',
    data
  });

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

/** 更新需求模块 */
export function fetchUpdateRequirementModule(data: Api.Product.SaveRequirementModuleParams) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/module/update`,
    method: 'put',
    data
  });
}

/** 删除需求模块 */
export function fetchDeleteRequirementModule(data: Api.Product.DeleteRequirementModuleParams) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${REQUIREMENT_PREFIX}/module/delete`,
    method: 'post',
    data
  });
}

export async function fetchGetProductSettings(id: string) {
  const result = await request<Api.Product.ProductSettings>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/${id}/settings`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<Api.Product.ProductSettings>, normalizeProductSettings);
}

export function fetchUpdateProductSettingBaseInfo(id: string, data: Api.Product.UpdateProductSettingBaseInfoParams) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/${id}/settings/base-info`,
    method: 'put',
    data
  });
}

export async function fetchGetProductMembers(id: string) {
  const result = await request<Api.Product.ProductMember[]>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/${id}/members`,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<Api.Product.ProductMember[]>, data =>
    data.map(normalizeProductMember)
  );
}

export async function fetchGetProductActivityTimelinePage(
  id: string,
  params: Api.Product.ProductActivityTimelinePageParams
) {
  const query = createProductActivityTimelinePageQuery(params);
  const url = query ? `${PRODUCT_PREFIX}/${id}/activities/page?${query}` : `${PRODUCT_PREFIX}/${id}/activities/page`;
  const result = await request<ProductActivityTimelinePageResponse>({
    ...safeJsonRequestConfig,
    url,
    method: 'get'
  });

  return mapServiceResult(result as ServiceRequestResult<ProductActivityTimelinePageResponse>, data => ({
    total: normalizePageTotal(data.total),
    list: data.list.map(normalizeProductActivityTimelineItem)
  }));
}

export async function fetchCreateProductMember(id: string, data: Api.Product.CreateProductMemberParams) {
  const result = await request<string | number>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/${id}/members`,
    method: 'post',
    data
  });

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

export async function fetchBatchCreateProductMembers(id: string, data: Api.Product.BatchCreateProductMembersParams) {
  const result = await request<Array<string | number>>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/${id}/members/batch`,
    method: 'post',
    data
  });

  return mapServiceResult(result as ServiceRequestResult<Array<string | number>>, list =>
    Array.isArray(list) ? list.map(normalizeStringId) : []
  );
}

export function fetchUpdateProductMember(id: string, memberId: string, data: Api.Product.UpdateProductMemberParams) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/${id}/members/${memberId}`,
    method: 'put',
    data
  });
}

export function fetchBatchInactiveProductMembers(id: string, data: Api.Product.BatchInactiveProductMembersParams) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/${id}/members/batch/inactive`,
    method: 'post',
    data
  });
}

export function fetchInactiveProductMember(
  id: string,
  memberId: string,
  data: Api.Product.InactiveProductMemberParams
) {
  return request<boolean>({
    ...safeJsonRequestConfig,
    url: `${PRODUCT_PREFIX}/${id}/members/${memberId}/inactive`,
    method: 'post',
    data
  });
}
