import type {
  MarketingCouponChannel,
  MarketingCouponDetailDto,
  MarketingCouponType,
  SaveMarketingCouponDto,
} from '#/api/marketing';
import type {
  CouponCardViewModel,
  CouponEditorForm,
} from '#/views/marketing/coupon/types';

/**
 * 文件职责：优惠券页面纯函数。
 * 1. 负责列表文案、视觉样式映射。
 * 2. 负责表单与 API DTO 的互转。
 */
import dayjs from 'dayjs';

import {
  COUPON_CHANNEL_TEXT_MAP,
  COUPON_TYPE_FILTER_OPTIONS,
  createDefaultCouponEditorForm,
} from './constants';

/** 领取进度百分比。 */
export function resolveClaimedProgressPercent(
  claimedQuantity: number,
  totalQuantity: number,
) {
  if (totalQuantity <= 0) return 0;
  const percent = Math.round((claimedQuantity * 100) / totalQuantity);
  return Math.max(0, Math.min(100, percent));
}

/** 千分位格式化。 */
export function formatInteger(value: number) {
  return Intl.NumberFormat('zh-CN', {
    maximumFractionDigits: 0,
  }).format(value);
}

/** 优惠券左侧色板样式类。 */
export function resolveCouponTypeClass(couponType: MarketingCouponType) {
  if (couponType === 'amount_off') {
    return 'mcp-left-red';
  }
  if (couponType === 'discount') {
    return 'mcp-left-blue';
  }
  return 'mcp-left-green';
}

/** 进度条颜色类。 */
export function resolveProgressClass(couponType: MarketingCouponType) {
  if (couponType === 'amount_off') {
    return 'mcp-progress-red';
  }
  if (couponType === 'discount') {
    return 'mcp-progress-blue';
  }
  return 'mcp-progress-green';
}

/** 列表类型文案。 */
export function resolveCouponTypeLabel(couponType: MarketingCouponType) {
  return (
    COUPON_TYPE_FILTER_OPTIONS.find((item) => item.value === couponType)
      ?.label ?? '优惠券'
  );
}

/** 列表券面主文案。 */
export function resolveCouponFaceValueText(item: CouponCardViewModel) {
  if (item.couponType === 'amount_off') {
    return `¥${trimDecimal(item.value)}`;
  }
  if (item.couponType === 'discount') {
    return `${trimDecimal(item.value)}折`;
  }
  return '免配送';
}

/** 列表券面副文案。 */
export function resolveCouponFaceConditionText(item: CouponCardViewModel) {
  if (item.couponType === 'amount_off' || item.couponType === 'discount') {
    if (item.minimumSpend && item.minimumSpend > 0) {
      return `满${trimDecimal(item.minimumSpend)}可用`;
    }
    return item.couponType === 'discount' ? '全场通用' : '无门槛';
  }
  return '无门槛';
}

/** 列表有效期文案。 */
export function resolveCouponValidityText(item: CouponCardViewModel) {
  if (item.validFrom && item.validTo) {
    return `${item.validFrom.replaceAll('-', '.')} - ${item.validTo.replaceAll('-', '.')}`;
  }
  if (item.relativeValidDays && item.relativeValidDays > 0) {
    return `领取后 ${item.relativeValidDays} 天内有效`;
  }
  return '--';
}

/** 列表规则文案。 */
export function resolveCouponRuleText(item: CouponCardViewModel) {
  const limitText =
    item.perUserLimit && item.perUserLimit > 0
      ? `每人限领${item.perUserLimit}张`
      : '不限领';

  const channelText = resolveChannelsText(item.channels);
  return `${limitText} | ${channelText}`;
}

/** 门店范围标签文本。 */
export function resolveCouponStoreTagText(
  item: CouponCardViewModel,
  storeNameMap: Record<string, string>,
) {
  if (item.storeScopeMode === 'all') {
    return '全部门店';
  }

  const storeNames = item.storeIds
    .map((storeId) => storeNameMap[storeId])
    .filter((name) => typeof name === 'string' && name.length > 0);

  if (storeNames.length <= 0) {
    return '指定门店';
  }

  if (storeNames.length === 1) {
    return storeNames[0];
  }

  return `${storeNames[0]}等${storeNames.length}家`;
}

/** 渠道文本。 */
export function resolveChannelsText(channels: MarketingCouponChannel[]) {
  const normalized = channels.toSorted();
  const allChannels: MarketingCouponChannel[] = [
    'delivery',
    'pickup',
    'dine_in',
  ];
  const isAll = allChannels.every((channel) => normalized.includes(channel));
  if (isAll) {
    return '全渠道可用';
  }

  const channelLabels = normalized.map(
    (channel) => COUPON_CHANNEL_TEXT_MAP[channel],
  );
  if (channelLabels.length === 1) {
    return `仅${channelLabels[0]}可用`;
  }
  return `${channelLabels.join('/')}可用`;
}

/** 详情映射为编辑表单。 */
export function mapDetailToEditorForm(
  detail: MarketingCouponDetailDto,
): CouponEditorForm {
  const form = createDefaultCouponEditorForm();
  form.id = detail.id;
  form.name = detail.name;
  form.couponType = detail.couponType;
  form.value = detail.couponType === 'free_delivery' ? null : detail.value;
  form.minimumSpend = detail.minimumSpend;
  form.totalQuantity = detail.totalQuantity;
  form.perUserLimit = detail.perUserLimit;
  form.validityType = detail.validityType;
  form.validDateRange =
    detail.validityType === 'fixed' && detail.validFrom && detail.validTo
      ? [dayjs(detail.validFrom), dayjs(detail.validTo)]
      : null;
  form.relativeValidDays = detail.relativeValidDays;
  form.channels = [...detail.channels];
  form.storeScopeMode = detail.storeScopeMode;
  form.storeIds = [...detail.storeIds];
  form.status = detail.status;
  return form;
}

/** 编辑表单构建保存请求。 */
export function buildSaveCouponPayload(
  form: CouponEditorForm,
  storeId: string,
): SaveMarketingCouponDto {
  const validFrom =
    form.validityType === 'fixed' && form.validDateRange
      ? form.validDateRange[0].format('YYYY-MM-DD')
      : null;
  const validTo =
    form.validityType === 'fixed' && form.validDateRange
      ? form.validDateRange[1].format('YYYY-MM-DD')
      : null;

  const value =
    form.couponType === 'free_delivery' ? 0 : Number(form.value ?? 0);
  const minimumSpend =
    form.couponType === 'free_delivery'
      ? null
      : normalizeNullableNumber(form.minimumSpend);

  return {
    id: form.id || undefined,
    storeId,
    name: form.name.trim(),
    couponType: form.couponType,
    value,
    minimumSpend,
    totalQuantity: Math.floor(Number(form.totalQuantity || 0)),
    perUserLimit: normalizeNullableNumber(form.perUserLimit),
    validityType: form.validityType,
    validFrom,
    validTo,
    relativeValidDays:
      form.validityType === 'days'
        ? Math.floor(Number(form.relativeValidDays || 0))
        : null,
    channels: [...form.channels],
    storeScopeMode: form.storeScopeMode,
    storeIds: form.storeScopeMode === 'stores' ? [...form.storeIds] : undefined,
    status: form.status,
  };
}

function normalizeNullableNumber(value: null | number) {
  if (value === null || Number.isNaN(value)) {
    return null;
  }
  return Number(value);
}

function trimDecimal(value: number) {
  const fixed = value.toFixed(2);
  return fixed.replace(/\.?0+$/, '');
}
