import dayjs from 'dayjs';
import { getProjectStatusLabel } from '../../shared/project-master-data';

export interface ProjectHomepageMetric {
  label: string;
  value: string;
  hint: string;
}

export interface ProjectHomepageFact {
  label: string;
  value: string;
  fullWidth?: boolean;
}

export interface ProjectHomepageBanner {
  identity: {
    name: string;
    code: string;
    directionCode: string;
    projectType: string;
    statusCode: Api.Project.ProjectStatusCode | null;
    statusLabel: string;
    description: string;
    facts: ProjectHomepageFact[];
  };
  metrics: ProjectHomepageMetric[];
}

export interface ProjectHomepageBannerSource {
  project: Api.Project.Project | null;
  settings: Api.Project.ProjectSettings | null;
  members: readonly Api.Project.ProjectMember[];
  latestActivityTime?: string | null;
}

export interface ProjectHomepageTimelineItem {
  key: string;
  tag: '对象' | '状态' | '团队' | '计划';
  title: string;
  content: string;
  time: string;
  tone: 'sky' | 'emerald' | 'amber' | 'rose' | 'slate';
}

export interface ProjectScheduleOverview {
  metrics: ProjectHomepageMetric[];
  dates: Array<{
    label: string;
    value: string;
  }>;
}

export interface ProjectTeamOverview {
  metrics: ProjectHomepageMetric[];
  roles: Array<{
    label: string;
    value: string;
  }>;
}

export interface ProjectHomepageExtensionModule {
  key: 'milestone' | 'risk' | 'document';
  title: string;
  description: string;
  items: string[];
}

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

  return parsed.isValid() ? parsed.valueOf() : 0;
}

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

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

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

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

function getStatusLabel(status: Api.Project.ProjectStatusCode | null | undefined) {
  return status ? getProjectStatusLabel(status) || '--' : '--';
}

function getActiveMembers(members: readonly Api.Project.ProjectMember[]) {
  return members.filter(item => item.status === 0);
}

function getManagerLabel(
  project: Api.Project.Project | null,
  settings: Api.Project.ProjectSettings | null,
  members: readonly Api.Project.ProjectMember[]
) {
  return (
    settings?.baseInfo.managerUserNickname ||
    project?.managerUserNickname ||
    getActiveMembers(members).find(item => item.managerFlag)?.userNickname ||
    '--'
  );
}

function getRoleSummary(members: readonly Api.Project.ProjectMember[]) {
  const activeMembers = getActiveMembers(members);

  if (!activeMembers.length) {
    return '--';
  }

  const roleCounter = new Map<string, number>();

  activeMembers.forEach(member => {
    const roleName = member.roleName || '未命名角色';

    roleCounter.set(roleName, (roleCounter.get(roleName) || 0) + 1);
  });

  return Array.from(roleCounter.entries())
    .sort((left, right) => {
      const leftWeight = left[0].includes('经理') || left[0].includes('负责人') ? 0 : 1;
      const rightWeight = right[0].includes('经理') || right[0].includes('负责人') ? 0 : 1;

      if (leftWeight !== rightWeight) {
        return leftWeight - rightWeight;
      }

      return left[0].localeCompare(right[0], 'zh-CN');
    })
    .map(([roleName, count]) => `${roleName} ${count} 人`)
    .join(' / ');
}

function getPlanRangeLabel(project: Api.Project.Project | null) {
  const start = formatDate(project?.plannedStartDate);
  const end = formatDate(project?.plannedEndDate);

  if (start === '--' && end === '--') {
    return '--';
  }

  return `${start} 至 ${end}`;
}

function getProgressValue(project: Api.Project.Project | null) {
  const progress = project?.progressRate ?? 0;

  if (!Number.isFinite(progress)) {
    return 0;
  }

  return Math.min(100, Math.max(0, progress));
}

function resolveLatestTimelineTime(
  project: Api.Project.Project | null,
  settings: Api.Project.ProjectSettings | null,
  members: readonly Api.Project.ProjectMember[]
) {
  const timeValues = [
    project?.createTime,
    project?.updateTime,
    settings?.lifecycle.lastStatusReason ? project?.updateTime : null,
    project?.actualStartDate,
    project?.actualEndDate,
    ...members.flatMap(member => [member.joinedTime, member.leftTime || null])
  ];

  const latestValue = timeValues.reduce((latest, current) => Math.max(latest, getTimeValue(current)), 0);

  return latestValue ? dayjs(latestValue).format('YYYY-MM-DD HH:mm') : '--';
}

// 待重构：拆 helper 以降低复杂度，暂以 disable 注释临时放行
// eslint-disable-next-line complexity
function buildProjectHomepageBannerIdentity(source: ProjectHomepageBannerSource) {
  const { project, settings, members } = source;
  const baseInfo = settings?.baseInfo;
  const statusCode = settings?.lifecycle.statusCode || project?.statusCode || null;

  return {
    name: project?.projectName || baseInfo?.projectName || '--',
    code: project?.projectCode || baseInfo?.projectCode || '--',
    directionCode: project?.directionCode || baseInfo?.directionCode || '',
    projectType: project?.projectType || baseInfo?.projectType || '',
    statusCode,
    statusLabel: getStatusLabel(statusCode),
    description: project?.projectDesc?.trim() || baseInfo?.projectDesc?.trim() || '',
    facts: [
      { label: '所属产品', value: project?.productName || baseInfo?.productName || project?.productId || '--' },
      { label: '项目经理', value: getManagerLabel(project, settings, members) },
      { label: '角色摘要', value: getRoleSummary(members), fullWidth: true }
    ]
  } satisfies ProjectHomepageBanner['identity'];
}

function buildProjectHomepageBannerMetrics(source: ProjectHomepageBannerSource) {
  const activeMembers = getActiveMembers(source.members);
  const latestTimelineTime =
    source.latestActivityTime?.trim() || resolveLatestTimelineTime(source.project, source.settings, source.members);

  return [
    {
      label: '团队人数',
      value: String(activeMembers.length),
      hint: '当前处于有效状态的项目成员数'
    },
    {
      label: '项目进度',
      value: `${getProgressValue(source.project)}%`,
      hint: '项目详情中维护的当前进度百分比'
    },
    {
      label: '计划周期',
      value: getPlanRangeLabel(source.project),
      hint: '项目计划开始和计划结束日期'
    },
    {
      label: '最近动态时间',
      value: latestTimelineTime,
      hint: '对象、状态、计划或团队最近一次可确认变动时间'
    }
  ] satisfies ProjectHomepageMetric[];
}

export function buildProjectHomepageBanner(source: ProjectHomepageBannerSource): ProjectHomepageBanner {
  return {
    identity: buildProjectHomepageBannerIdentity(source),
    metrics: buildProjectHomepageBannerMetrics(source)
  };
}

export function buildProjectHomepageTimeline(
  project: Api.Project.Project | null,
  settings: Api.Project.ProjectSettings | null,
  members: readonly Api.Project.ProjectMember[]
) {
  const items: Array<Omit<ProjectHomepageTimelineItem, 'time'> & { time: string | null | undefined }> = [];

  if (project?.createTime) {
    items.push({
      key: `project-create-${project.id}`,
      tag: '对象',
      title: '创建项目',
      content: `项目 ${project.projectName || project.projectCode} 已创建并进入项目管理域。`,
      time: project.createTime,
      tone: 'sky'
    });
  }

  const statusReason =
    settings?.lifecycle.lastStatusReason || settings?.baseInfo.lastStatusReason || project?.lastStatusReason;

  if (project?.updateTime && project?.statusCode && statusReason) {
    const toneMap: Record<Api.Project.ProjectStatusCode, ProjectHomepageTimelineItem['tone']> = {
      pending: 'slate',
      active: 'emerald',
      paused: 'amber',
      completed: 'emerald',
      cancelled: 'rose',
      archived: 'slate'
    };

    items.push({
      key: `project-status-${project.id}-${project.updateTime}`,
      tag: '状态',
      title: `状态调整为${getStatusLabel(project.statusCode)}`,
      content: statusReason,
      time: project.updateTime,
      tone: toneMap[project.statusCode]
    });
  }

  if (project?.actualStartDate) {
    items.push({
      key: `project-actual-start-${project.id}`,
      tag: '计划',
      title: '实际开始',
      content: '项目已记录实际开始日期，进入真实推进阶段。',
      time: project.actualStartDate,
      tone: 'emerald'
    });
  }

  if (project?.actualEndDate) {
    items.push({
      key: `project-actual-end-${project.id}`,
      tag: '计划',
      title: '实际结束',
      content: '项目已记录实际结束日期，可结合状态进入完成或归档处理。',
      time: project.actualEndDate,
      tone: 'slate'
    });
  }

  members.forEach(member => {
    if (member.joinedTime) {
      items.push({
        key: `member-join-${member.id}`,
        tag: '团队',
        title: '成员加入',
        content: `${member.userNickname} 以 ${member.roleName || '未命名角色'} 身份加入当前项目。`,
        time: member.joinedTime,
        tone: member.managerFlag ? 'emerald' : 'sky'
      });
    }

    if (member.status === 1 && member.leftTime) {
      items.push({
        key: `member-leave-${member.id}`,
        tag: '团队',
        title: '成员移出',
        content: `${member.userNickname} 已退出当前项目团队。`,
        time: member.leftTime,
        tone: 'rose'
      });
    }
  });

  return items
    .filter(item => getTimeValue(item.time) > 0)
    .sort((left, right) => getTimeValue(right.time) - getTimeValue(left.time))
    .slice(0, 8)
    .map(item => ({
      ...item,
      time: formatDateTime(item.time)
    })) satisfies ProjectHomepageTimelineItem[];
}

export function buildProjectScheduleOverview(project: Api.Project.Project | null): ProjectScheduleOverview {
  const progressValue = getProgressValue(project);
  const hasActualRange = Boolean(project?.actualStartDate || project?.actualEndDate);

  return {
    metrics: [
      {
        label: '当前进度',
        value: `${progressValue}%`,
        hint: '由项目详情维护的进度字段直接呈现'
      },
      {
        label: '日期完整度',
        value: hasActualRange ? '已记录实际日期' : '以计划日期为主',
        hint: '用于判断当前项目计划与执行日期是否闭环'
      }
    ],
    dates: [
      { label: '计划开始', value: formatDate(project?.plannedStartDate) },
      { label: '计划结束', value: formatDate(project?.plannedEndDate) },
      { label: '实际开始', value: formatDate(project?.actualStartDate) },
      { label: '实际结束', value: formatDate(project?.actualEndDate) }
    ]
  };
}

export function buildProjectTeamOverview(members: readonly Api.Project.ProjectMember[]): ProjectTeamOverview {
  const activeMembers = getActiveMembers(members);
  const inactiveMembers = members.filter(item => item.status === 1);
  const manager = activeMembers.find(item => item.managerFlag);
  const roleCounter = new Map<string, number>();

  activeMembers.forEach(member => {
    const roleName = member.roleName || '未命名角色';

    roleCounter.set(roleName, (roleCounter.get(roleName) || 0) + 1);
  });

  return {
    metrics: [
      {
        label: '有效成员',
        value: String(activeMembers.length),
        hint: '当前仍在项目团队中的成员数'
      },
      {
        label: '已退出成员',
        value: String(inactiveMembers.length),
        hint: '历史加入后已移出的项目成员数'
      },
      {
        label: '项目经理',
        value: manager?.userNickname || '--',
        hint: '当前团队中标记为项目负责人的成员'
      },
      {
        label: '角色类型',
        value: String(roleCounter.size),
        hint: '有效成员覆盖的角色种类数'
      }
    ],
    roles: Array.from(roleCounter.entries()).map(([label, value]) => ({ label, value: String(value) }))
  };
}

export function getProjectHomepageExtensionModules(modules: readonly ProjectHomepageExtensionModule[]) {
  return [...modules];
}
