import type { Dayjs } from 'dayjs';

import type {
  MarketingPunchCardDetailDto,
  MarketingPunchCardUsageRecordDto,
  SaveMarketingPunchCardDto,
} from '#/api/marketing';
import type {
  PunchCardEditorForm,
  PunchCardUsageRecordViewModel,
} from '#/views/marketing/punch-card/types';

import dayjs from 'dayjs';

import {
  createDefaultPunchCardEditorForm,
  createDefaultPunchCardScopeForm,
  PUNCH_CARD_RECORD_STATUS_TEXT_MAP,
} from './constants';

/**
 * 文件职责：次卡页面工具方法。
 */

/** 金额格式化。 */
export function formatCurrency(value: null | number | undefined) {
  const amount = Number(value ?? 0);
  if (Number.isNaN(amount)) {
    return '¥0';
  }

  if (Math.abs(amount) >= 1000) {
    return `¥${amount.toLocaleString('zh-CN', {
      minimumFractionDigits: 0,
      maximumFractionDigits: 2,
    })}`;
  }

  return `¥${amount.toFixed(amount % 1 === 0 ? 0 : 2)}`;
}

/** 记录状态转文案。 */
export function resolveUsageStatusText(status: string) {
  return PUNCH_CARD_RECORD_STATUS_TEXT_MAP[status] ?? '正常使用';
}

/** 记录状态转样式类。 */
export function resolveUsageStatusClass(status: string) {
  if (status === 'normal') {
    return 'is-green';
  }
  if (status === 'almost_used_up') {
    return 'is-orange';
  }
  return 'is-gray';
}

/** DTO 转列表视图模型。 */
export function toUsageRecordViewModel(
  source: MarketingPunchCardUsageRecordDto,
): PunchCardUsageRecordViewModel {
  return {
    ...source,
    displayStatusText: resolveUsageStatusText(source.displayStatus),
  };
}

/** 详情转编辑表单。 */
export function mapDetailToEditorForm(
  detail: MarketingPunchCardDetailDto,
): PunchCardEditorForm {
  const dateRange = toValidDateRange(detail.validFrom, detail.validTo);

  const form = createDefaultPunchCardEditorForm();
  form.id = detail.id;
  form.name = detail.name;
  form.coverImageUrl = detail.coverImageUrl ?? '';
  form.salePrice = detail.salePrice;
  form.originalPrice = detail.originalPrice;
  form.totalTimes = detail.totalTimes;
  form.validityType = detail.validityType;
  form.validityDays = detail.validityDays;
  form.validDateRange = dateRange;
  form.scope = {
    scopeType: detail.scope.scopeType,
    categoryIds: [...detail.scope.categoryIds],
    tagIds: [...detail.scope.tagIds],
    productIds: [...detail.scope.productIds],
  };
  form.usageMode = detail.usageMode;
  form.usageCapAmount = detail.usageCapAmount;
  form.dailyLimit = detail.dailyLimit;
  form.perOrderLimit = detail.perOrderLimit;
  form.perUserPurchaseLimit = detail.perUserPurchaseLimit;
  form.allowTransfer = detail.allowTransfer;
  form.expireStrategy = detail.expireStrategy;
  form.description = detail.description ?? '';
  form.notifyChannels =
    detail.notifyChannels.length > 0 ? [...detail.notifyChannels] : ['in_app'];
  form.status = detail.status;

  return form;
}

/** 编辑表单转保存 DTO。 */
export function mapEditorFormToSaveDto(
  form: PunchCardEditorForm,
  storeId: string,
): SaveMarketingPunchCardDto {
  const validFrom =
    form.validityType === 'range' && form.validDateRange
      ? form.validDateRange[0].format('YYYY-MM-DD')
      : null;
  const validTo =
    form.validityType === 'range' && form.validDateRange
      ? form.validDateRange[1].format('YYYY-MM-DD')
      : null;

  return {
    id: form.id || undefined,
    storeId,
    name: form.name.trim(),
    coverImageUrl: form.coverImageUrl.trim() || undefined,
    salePrice: Number(form.salePrice ?? 0),
    originalPrice:
      form.originalPrice === null || form.originalPrice === undefined
        ? null
        : Number(form.originalPrice),
    totalTimes: Number(form.totalTimes ?? 0),
    validityType: form.validityType,
    validityDays:
      form.validityType === 'days'
        ? Number(form.validityDays ?? 0) || null
        : null,
    validFrom,
    validTo,
    scopeType: form.scope.scopeType,
    scopeCategoryIds: [...form.scope.categoryIds],
    scopeTagIds: [...form.scope.tagIds],
    scopeProductIds: [...form.scope.productIds],
    usageMode: form.usageMode,
    usageCapAmount:
      form.usageMode === 'cap'
        ? Number(form.usageCapAmount ?? 0) || null
        : null,
    dailyLimit:
      form.dailyLimit === null || form.dailyLimit === undefined
        ? null
        : Number(form.dailyLimit) || null,
    perOrderLimit:
      form.perOrderLimit === null || form.perOrderLimit === undefined
        ? null
        : Number(form.perOrderLimit) || null,
    perUserPurchaseLimit:
      form.perUserPurchaseLimit === null ||
      form.perUserPurchaseLimit === undefined
        ? null
        : Number(form.perUserPurchaseLimit) || null,
    allowTransfer: form.allowTransfer,
    expireStrategy: form.expireStrategy,
    description: form.description.trim() || undefined,
    notifyChannels: [...form.notifyChannels],
  };
}

/** 创建空编辑表单。 */
export function resetEditorForm(form: PunchCardEditorForm) {
  const value = createDefaultPunchCardEditorForm();
  form.id = value.id;
  form.name = value.name;
  form.coverImageUrl = value.coverImageUrl;
  form.salePrice = value.salePrice;
  form.originalPrice = value.originalPrice;
  form.totalTimes = value.totalTimes;
  form.validityType = value.validityType;
  form.validityDays = value.validityDays;
  form.validDateRange = value.validDateRange;
  form.scope = createDefaultPunchCardScopeForm(value.scope.scopeType);
  form.usageMode = value.usageMode;
  form.usageCapAmount = value.usageCapAmount;
  form.dailyLimit = value.dailyLimit;
  form.perOrderLimit = value.perOrderLimit;
  form.perUserPurchaseLimit = value.perUserPurchaseLimit;
  form.allowTransfer = value.allowTransfer;
  form.expireStrategy = value.expireStrategy;
  form.description = value.description;
  form.notifyChannels = [...value.notifyChannels];
  form.status = value.status;
}

/** 深拷贝范围。 */
export function cloneScope(scope: PunchCardEditorForm['scope']) {
  return {
    scopeType: scope.scopeType,
    categoryIds: [...scope.categoryIds],
    tagIds: [...scope.tagIds],
    productIds: [...scope.productIds],
  };
}

/** base64 下载。 */
export function downloadBase64File(
  fileName: string,
  fileContentBase64: string,
) {
  const blob = decodeBase64ToBlob(fileContentBase64);
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement('a');
  anchor.href = url;
  anchor.download = fileName;
  document.body.append(anchor);
  anchor.click();
  anchor.remove();
  URL.revokeObjectURL(url);
}

function toValidDateRange(
  validFrom: null | string,
  validTo: null | string,
): [Dayjs, Dayjs] | null {
  if (!validFrom || !validTo) {
    return null;
  }

  const from = dayjs(validFrom);
  const to = dayjs(validTo);
  if (!from.isValid() || !to.isValid()) {
    return null;
  }

  return [from, to];
}

function decodeBase64ToBlob(base64: string) {
  const binary = atob(base64);
  const length = binary.length;
  const bytes = new Uint8Array(length);
  for (let index = 0; index < length; index++) {
    bytes[index] = binary.codePointAt(index) ?? 0;
  }
  return new Blob([bytes], { type: 'text/csv;charset=utf-8;' });
}
