/**
 * 文件职责：商品列表页面纯函数工具。
 * 1. 处理表单克隆、DTO 映射、字段归一化。
 * 2. 提供状态/库存展示与日期格式化工具。
 */
import type {
  ProductDetailDto,
  ProductListItemDto,
  ProductStatus,
  SaveProductDto,
} from '#/api/product';
import type {
  ProductEditorFormState,
  ProductFilterState,
  ProductQuickEditFormState,
  ProductSoldoutFormState,
} from '#/views/product/list/types';

import dayjs from 'dayjs';

import {
  DEFAULT_EDITOR_FORM,
  DEFAULT_FILTER_STATE,
  DEFAULT_QUICK_EDIT_FORM,
  DEFAULT_SOLDOUT_FORM,
  PRODUCT_STATUS_META_MAP,
} from './constants';

/** 克隆筛选状态，避免引用污染。 */
export function cloneFilterState(
  source: ProductFilterState = DEFAULT_FILTER_STATE,
): ProductFilterState {
  return {
    categoryId: source.categoryId,
    keyword: source.keyword,
    status: source.status,
    kind: source.kind,
    page: source.page,
    pageSize: source.pageSize,
  };
}

/** 克隆编辑表单。 */
export function cloneEditorForm(
  source: ProductEditorFormState = DEFAULT_EDITOR_FORM,
): ProductEditorFormState {
  return {
    id: source.id,
    name: source.name,
    subtitle: source.subtitle,
    description: source.description,
    comboGroups: source.comboGroups.map((group) => ({
      name: group.name,
      minSelect: group.minSelect,
      maxSelect: group.maxSelect,
      sortOrder: group.sortOrder,
      items: group.items.map((item) => ({
        productId: item.productId,
        productName: item.productName,
        quantity: item.quantity,
        sortOrder: item.sortOrder,
      })),
    })),
    imageUrls: [...source.imageUrls],
    categoryId: source.categoryId,
    kind: source.kind,
    price: source.price,
    originalPrice: source.originalPrice,
    stock: source.stock,
    tagsText: source.tagsText,
    status: source.status,
    shelfMode: source.shelfMode,
    timedOnShelfAt: source.timedOnShelfAt,
  };
}

/** 克隆快速编辑表单。 */
export function cloneQuickEditForm(
  source: ProductQuickEditFormState = DEFAULT_QUICK_EDIT_FORM,
): ProductQuickEditFormState {
  return {
    id: source.id,
    price: source.price,
    originalPrice: source.originalPrice,
    stock: source.stock,
    isOnSale: source.isOnSale,
  };
}

/** 克隆沽清表单。 */
export function cloneSoldoutForm(
  source: ProductSoldoutFormState = DEFAULT_SOLDOUT_FORM,
): ProductSoldoutFormState {
  return {
    mode: source.mode,
    remainStock: source.remainStock,
    reason: source.reason,
    recoverAt: source.recoverAt,
    syncToPlatform: source.syncToPlatform,
    notifyManager: source.notifyManager,
  };
}

/** 货币格式化。 */
export function formatCurrency(value: null | number) {
  const amount = Number(value ?? 0);
  if (!Number.isFinite(amount)) return '¥0.00';
  return `¥${amount.toFixed(2)}`;
}

/** 状态元信息解析。 */
export function resolveStatusMeta(status: ProductStatus) {
  return PRODUCT_STATUS_META_MAP[status] ?? PRODUCT_STATUS_META_MAP.off_shelf;
}

/** 按库存返回展示文本。 */
export function formatStockText(stock: number) {
  if (stock <= 0) return '0 缺货';
  if (stock <= 10) return `${stock} 偏低`;
  return `${stock} 充足`;
}

/** 按库存返回样式类。 */
export function resolveStockClass(stock: number) {
  if (stock <= 0) return 'stock-out';
  if (stock <= 10) return 'stock-low';
  return 'stock-ok';
}

/** 标签数组转输入框文本。 */
export function tagsToText(tags: string[]) {
  return tags.join(', ');
}

/** 输入框文本转标签数组。 */
export function textToTags(source: string) {
  return [
    ...new Set(
      source
        .split(',')
        .map((item) => item.trim())
        .filter(Boolean)
        .slice(0, 8),
    ),
  ];
}

/** 统一格式化为 yyyy-MM-dd HH:mm:ss。 */
export function formatDateTime(value: Date | dayjs.Dayjs | string) {
  const parsed = dayjs(value);
  if (!parsed.isValid()) return '';
  return parsed.format('YYYY-MM-DD HH:mm:ss');
}

/** 列表项映射到编辑表单（兜底）。 */
export function mapListItemToEditorForm(
  item: ProductListItemDto,
): ProductEditorFormState {
  const imageUrls = item.imageUrl ? [item.imageUrl] : [];
  return {
    id: item.id,
    name: item.name,
    subtitle: item.subtitle,
    description: item.subtitle,
    comboGroups: [],
    imageUrls,
    categoryId: item.categoryId,
    kind: item.kind,
    price: item.price,
    originalPrice: item.originalPrice,
    stock: item.stock,
    tagsText: tagsToText(item.tags),
    status: item.status,
    shelfMode: 'draft',
    timedOnShelfAt: '',
  };
}

/** 详情映射到编辑表单。 */
export function mapDetailToEditorForm(
  detail: ProductDetailDto,
): ProductEditorFormState {
  const imageUrls = [...(detail.imageUrls ?? []), detail.imageUrl]
    .map((item) => String(item || '').trim())
    .filter(Boolean)
    .filter((item, index, source) => source.indexOf(item) === index)
    .slice(0, 5);

  return {
    id: detail.id,
    name: detail.name,
    subtitle: detail.subtitle,
    description: detail.description,
    comboGroups: (detail.comboGroups ?? []).map((group) => ({
      name: group.name,
      minSelect: group.minSelect,
      maxSelect: group.maxSelect,
      sortOrder: group.sortOrder,
      items: group.items.map((item) => ({
        productId: item.productId,
        productName: item.productName,
        quantity: item.quantity,
        sortOrder: item.sortOrder,
      })),
    })),
    imageUrls,
    categoryId: detail.categoryId,
    kind: detail.kind,
    price: detail.price,
    originalPrice: detail.originalPrice,
    stock: detail.stock,
    tagsText: tagsToText(detail.tags),
    status: detail.status,
    shelfMode: detail.status === 'on_sale' ? 'now' : 'draft',
    timedOnShelfAt: '',
  };
}

/** 列表项映射到快速编辑表单。 */
export function mapListItemToQuickEditForm(
  item: ProductListItemDto,
): ProductQuickEditFormState {
  return {
    id: item.id,
    price: item.price,
    originalPrice: item.originalPrice,
    stock: item.stock,
    isOnSale: item.status === 'on_sale',
  };
}

/** 列表项映射到沽清表单。 */
export function mapListItemToSoldoutForm(
  item: ProductListItemDto,
): ProductSoldoutFormState {
  return {
    mode: item.soldoutMode ?? 'today',
    remainStock: Math.max(0, item.stock),
    reason: item.soldoutMode ? '库存紧张' : '',
    recoverAt: '',
    syncToPlatform: true,
    notifyManager: false,
  };
}

/** 编辑表单映射为保存请求参数。 */
export function toSavePayload(
  form: ProductEditorFormState,
  storeId: string,
): SaveProductDto {
  const price = Number(form.price || 0);
  const originalPrice = Number(form.originalPrice ?? 0);
  let normalizedStatus: ProductStatus = form.status;
  if (form.shelfMode === 'now') {
    normalizedStatus = 'on_sale';
  } else if (form.shelfMode === 'scheduled') {
    normalizedStatus = 'off_shelf';
  }

  return {
    id: form.id || undefined,
    storeId,
    categoryId: form.categoryId,
    name: form.name.trim(),
    subtitle: form.subtitle.trim(),
    description: form.description.trim(),
    kind: form.kind,
    price: Number.isFinite(price) ? Number(price.toFixed(2)) : 0,
    originalPrice:
      originalPrice > 0 && Number.isFinite(originalPrice)
        ? Number(originalPrice.toFixed(2))
        : null,
    stock: Math.max(0, Math.floor(Number(form.stock || 0))),
    tags: textToTags(form.tagsText),
    comboGroups:
      form.kind === 'combo'
        ? form.comboGroups.map((group, groupIndex) => ({
            name: group.name.trim(),
            minSelect: Math.max(1, Math.floor(Number(group.minSelect || 1))),
            maxSelect: Math.max(1, Math.floor(Number(group.maxSelect || 1))),
            sortOrder: Math.max(
              1,
              Math.floor(Number(group.sortOrder || groupIndex + 1)),
            ),
            items: group.items.map((item, itemIndex) => ({
              productId: item.productId,
              quantity: Math.max(1, Math.floor(Number(item.quantity || 1))),
              sortOrder: Math.max(
                1,
                Math.floor(Number(item.sortOrder || itemIndex + 1)),
              ),
            })),
          }))
        : [],
    imageUrls: form.imageUrls
      .map((item) => item.trim())
      .filter(Boolean)
      .filter((item, index, source) => source.indexOf(item) === index)
      .slice(0, 5),
    status: normalizedStatus,
    shelfMode: form.shelfMode,
    timedOnShelfAt:
      form.shelfMode === 'scheduled' && form.timedOnShelfAt
        ? formatDateTime(form.timedOnShelfAt)
        : undefined,
  };
}
