import dayjs from 'dayjs';

const productStatusLabelMap = {
  active: '启用',
  paused: '暂停',
  archived: '归档',
  abandoned: '废弃'
} as const satisfies Record<Api.Product.ProductStatusCode, string>;

const activityTypeLabelMap = {
  product: '产品',
  status: '状态',
  member: '成员'
} as const satisfies Record<Api.Product.ProductActivityType, string>;

export type ProductActivityFilterType = 'all' | Api.Product.ProductActivityType;

export type ProductActivityTone = 'sky' | 'emerald' | 'amber' | 'rose' | 'slate';

export interface ProductActivityTextPart {
  text: string;
  strong?: boolean;
}

interface ActivitySummaryResult {
  text: string;
  parts: ProductActivityTextPart[];
}

export interface ProductActivityDisplayItem extends Api.Product.ProductActivityTimelineItem {
  tagLabel: string;
  timeText: string;
  actionText: string;
  displaySummary: string;
  compactText: string;
  compactTextParts: ProductActivityTextPart[];
  operatorText: string;
  subjectText: string;
  reasonText: string;
  statusTransition: string;
  tone: ProductActivityTone;
}

export const PRODUCT_ACTIVITY_TYPE_OPTIONS: Array<{ label: string; value: ProductActivityFilterType }> = [
  { label: '全部', value: 'all' },
  { label: '产品', value: 'product' },
  { label: '状态', value: 'status' },
  { label: '成员', value: 'member' }
];

export const PRODUCT_ACTIVITY_ACTION_OPTIONS: Array<{
  label: string;
  value: Api.Product.ProductActivityActionType;
  type: Api.Product.ProductActivityType;
}> = [
  { label: '产品创建', value: 'create', type: 'product' },
  { label: '产品经理变更', value: 'change_manager', type: 'product' },
  { label: '暂停', value: 'pause', type: 'status' },
  { label: '恢复', value: 'resume', type: 'status' },
  { label: '归档', value: 'archive', type: 'status' },
  { label: '废弃', value: 'abandon', type: 'status' },
  { label: '成员加入', value: 'add_member', type: 'member' },
  { label: '成员调整', value: 'update_member', type: 'member' },
  { label: '成员移出', value: 'remove_member', type: 'member' }
];

export const PRODUCT_ACTIVITY_TIME_SHORTCUTS = [
  { label: '最近7天', days: 7 },
  { label: '最近30天', days: 30 },
  { label: '最近90天', days: 90 }
] as const;

export const DEFAULT_PRODUCT_ACTIVITY_PAGE_SIZE = 10;

type ActivityDetailRecord = Record<string, unknown>;

function getStatusLabel(status: Api.Product.ProductStatusCode | null | undefined) {
  if (!status) {
    return '--';
  }

  return productStatusLabelMap[status] || '--';
}

function getActivityTone(item: Api.Product.ProductActivityTimelineItem): ProductActivityTone {
  if (item.type === 'status') {
    if (item.actionType === 'resume') {
      return 'emerald';
    }

    if (item.actionType === 'pause') {
      return 'amber';
    }

    if (item.actionType === 'abandon') {
      return 'rose';
    }

    return 'slate';
  }

  if (item.type === 'product') {
    return item.actionType === 'change_manager' ? 'emerald' : 'sky';
  }

  return item.actionType === 'remove_member' ? 'rose' : 'sky';
}

export function formatProductActivityTime(occurredAt: number | null | undefined) {
  if (!Number.isFinite(occurredAt)) {
    return '';
  }

  const parsed = dayjs(Number(occurredAt));

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

export function buildProductActivityRange(days: number): [string, string] {
  const end = dayjs().endOf('day');
  const start = dayjs()
    .subtract(Math.max(days - 1, 0), 'day')
    .startOf('day');

  return [start.format('YYYY-MM-DD HH:mm:ss'), end.format('YYYY-MM-DD HH:mm:ss')];
}

export function getProductActivityActionOptions(activityType: ProductActivityFilterType) {
  if (activityType === 'all') {
    return PRODUCT_ACTIVITY_ACTION_OPTIONS;
  }

  return PRODUCT_ACTIVITY_ACTION_OPTIONS.filter(item => item.type === activityType);
}

export function normalizeProductActivityActionTypes(
  activityType: ProductActivityFilterType,
  actionTypes: readonly Api.Product.ProductActivityActionType[]
) {
  const allowed = new Set(getProductActivityActionOptions(activityType).map(item => item.value));

  return actionTypes.filter(actionType => allowed.has(actionType));
}

function parseActivityDetails(details: string | null | undefined): ActivityDetailRecord | null {
  if (!details?.trim()) {
    return null;
  }

  try {
    const parsed = JSON.parse(details);

    if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
      const normalized = parsed as ActivityDetailRecord;
      const fieldChanges = normalized.fieldChanges;

      if (fieldChanges && typeof fieldChanges === 'object' && !Array.isArray(fieldChanges)) {
        return {
          ...normalized,
          ...(fieldChanges as ActivityDetailRecord)
        };
      }

      return normalized;
    }
  } catch {}

  return null;
}

function getRecordValue(record: ActivityDetailRecord | null, keys: readonly string[]) {
  if (!record) {
    return undefined;
  }

  const matchedKey = keys.find(key => key in record);

  return matchedKey ? record[matchedKey] : undefined;
}

function getFieldChangeText(
  record: ActivityDetailRecord | null,
  keys: readonly string[],
  preferredSide: 'before' | 'after'
) {
  const rawValue = getRecordValue(record, keys);

  if (rawValue && typeof rawValue === 'object' && !Array.isArray(rawValue)) {
    const fieldChange = rawValue as { before?: unknown; after?: unknown };
    const preferredValue = fieldChange[preferredSide];

    if (preferredValue !== null && preferredValue !== undefined && String(preferredValue).trim()) {
      return String(preferredValue).trim();
    }

    const fallbackSide = preferredSide === 'after' ? fieldChange.before : fieldChange.after;

    if (fallbackSide !== null && fallbackSide !== undefined && String(fallbackSide).trim()) {
      return String(fallbackSide).trim();
    }
  }

  if (rawValue !== null && rawValue !== undefined && String(rawValue).trim()) {
    return String(rawValue).trim();
  }

  return '';
}

function getActivityTargetUserName(
  item: Api.Product.ProductActivityTimelineItem,
  detailsRecord: ActivityDetailRecord | null
) {
  const targetUserName = item.targetUserName?.trim() || '';

  if (targetUserName) {
    return targetUserName;
  }

  const preferredSide = item.actionType === 'remove_member' ? 'before' : 'after';

  return getFieldChangeText(
    detailsRecord,
    [
      'memberUserName',
      'memberUserNickname',
      'memberName',
      'userNickname',
      'userName',
      'targetUserName',
      'targetUserNickname'
    ],
    preferredSide
  );
}

function getActivityTargetRoleName(
  item: Api.Product.ProductActivityTimelineItem,
  detailsRecord: ActivityDetailRecord | null
) {
  const preferredSide = item.actionType === 'remove_member' ? 'before' : 'after';

  return getFieldChangeText(detailsRecord, ['roleName', 'memberRoleName', 'targetRoleName'], preferredSide);
}

function getRoleTransitionText(detailsRecord: ActivityDetailRecord | null) {
  const beforeRoleName = getFieldChangeText(detailsRecord, ['roleName', 'memberRoleName', 'targetRoleName'], 'before');
  const afterRoleName = getFieldChangeText(detailsRecord, ['roleName', 'memberRoleName', 'targetRoleName'], 'after');

  if (beforeRoleName && afterRoleName && beforeRoleName !== afterRoleName) {
    return `${beforeRoleName} -> ${afterRoleName}`;
  }

  return afterRoleName || beforeRoleName;
}

function isGenericActivitySummary(summaryText: string, actionText: string) {
  if (!summaryText) {
    return true;
  }

  return summaryText === actionText || summaryText === actionText.replace('执行了', '执行了');
}

function isMemberActivityAction(actionType: Api.Product.ProductActivityActionType) {
  return actionType === 'add_member' || actionType === 'remove_member' || actionType === 'update_member';
}

function buildMemberChangeSummary(
  item: Api.Product.ProductActivityTimelineItem,
  detailsRecord: ActivityDetailRecord | null,
  operatorText: string
): ActivitySummaryResult | null {
  const memberName = getActivityTargetUserName(item, detailsRecord);
  const roleName = getActivityTargetRoleName(item, detailsRecord);

  if (!memberName) {
    return null;
  }

  const prefix =
    operatorText === '--' ? `执行了【${item.actionName}】：` : `${operatorText}执行了【${item.actionName}】：`;
  const roleSuffix = roleName ? `（${roleName}）` : '';
  const text = `${prefix}${memberName}${roleSuffix}`;
  const parts: ProductActivityTextPart[] = [{ text: prefix }, { text: memberName, strong: true }];

  if (roleSuffix) {
    parts.push({ text: roleSuffix });
  }

  return { text, parts };
}

function buildMemberUpdateSummary(
  item: Api.Product.ProductActivityTimelineItem,
  detailsRecord: ActivityDetailRecord | null,
  operatorText: string
): ActivitySummaryResult {
  const memberName = getActivityTargetUserName(item, detailsRecord);
  const roleTransitionText = getRoleTransitionText(detailsRecord);
  const memberText = memberName || '成员';
  const roleText = roleTransitionText ? `，角色：${roleTransitionText}` : '';
  const prefix =
    operatorText === '--' ? `执行了【${item.actionName}】：` : `${operatorText}执行了【${item.actionName}】：`;
  const text = `${prefix}${memberText}${roleText}`;
  const parts: ProductActivityTextPart[] = [{ text: prefix }, { text: memberText, strong: Boolean(memberName) }];

  if (roleText) {
    parts.push({ text: roleText });
  }

  return { text, parts };
}

function buildManagerChangeSummary(detailsRecord: ActivityDetailRecord | null, operatorText: string) {
  const beforeManagerName = getFieldChangeText(
    detailsRecord,
    ['beforeManagerUserName', 'beforeManagerUserNickname', 'managerUserName', 'managerUserNickname', 'managerName'],
    'before'
  );
  const afterManagerName = getFieldChangeText(
    detailsRecord,
    ['afterManagerUserName', 'afterManagerUserNickname', 'managerUserName', 'managerUserNickname', 'managerName'],
    'after'
  );

  if (!beforeManagerName && !afterManagerName) {
    return '';
  }

  const transitionText =
    beforeManagerName && afterManagerName
      ? `${beforeManagerName} -> ${afterManagerName}`
      : afterManagerName || beforeManagerName;

  return operatorText === '--' ? `变更产品经理：${transitionText}` : `${operatorText}变更产品经理：${transitionText}`;
}

function plainSummary(text: string): ActivitySummaryResult {
  return { text, parts: [{ text }] };
}

function resolveDetailedSummary(
  item: Api.Product.ProductActivityTimelineItem,
  detailsRecord: ActivityDetailRecord | null,
  texts: { operatorText: string; actionText: string }
): ActivitySummaryResult {
  const { operatorText, actionText } = texts;
  const summaryText = item.summary?.trim() || '';

  if (item.actionType === 'add_member' || item.actionType === 'remove_member') {
    return buildMemberChangeSummary(item, detailsRecord, operatorText) || plainSummary(summaryText || actionText);
  }

  if (item.actionType === 'update_member') {
    return buildMemberUpdateSummary(item, detailsRecord, operatorText);
  }

  if (!isGenericActivitySummary(summaryText, actionText)) {
    return plainSummary(summaryText);
  }

  if (item.actionType === 'change_manager') {
    const managerSummary = buildManagerChangeSummary(detailsRecord, operatorText);

    return plainSummary(managerSummary || summaryText || actionText);
  }

  return plainSummary(summaryText || actionText);
}

export function buildProductActivityDisplayItem(
  item: Api.Product.ProductActivityTimelineItem
): ProductActivityDisplayItem {
  const operatorText = item.operatorName?.trim() || '--';
  const actionText =
    operatorText === '--' ? `执行了【${item.actionName}】` : `${operatorText}执行了【${item.actionName}】`;
  const detailsRecord = parseActivityDetails(item.details);
  const subjectText = isMemberActivityAction(item.actionType) ? getActivityTargetUserName(item, detailsRecord) : '';
  const summary =
    item.type === 'status'
      ? plainSummary(actionText)
      : resolveDetailedSummary(item, detailsRecord, { operatorText, actionText });

  return {
    ...item,
    tagLabel: activityTypeLabelMap[item.type],
    timeText: formatProductActivityTime(item.occurredAt) || '--',
    actionText,
    displaySummary: summary.text,
    compactText: summary.text,
    compactTextParts: summary.parts.filter(part => part.text),
    operatorText,
    subjectText,
    reasonText: item.reason?.trim() || '',
    statusTransition:
      item.type === 'status' && item.fromStatus && item.toStatus
        ? `${getStatusLabel(item.fromStatus)} -> ${getStatusLabel(item.toStatus)}`
        : '',
    tone: getActivityTone(item)
  };
}

export function buildProductActivityDisplayItems(
  items: readonly Api.Product.ProductActivityTimelineItem[] | null | undefined
) {
  return [...(items || [])].map(buildProductActivityDisplayItem);
}
