import type { FinanceCostEntryState } from '../../types';

/**
 * 文件职责：成本录入分类与明细本地编辑动作。
 */
import type {
  FinanceCostCategoryCode,
  FinanceCostEntryDetailDto,
} from '#/api/finance/cost';

import { roundAmount, sumAllCategoryTotal, sumCategoryItems } from './helpers';

interface EntryActionOptions {
  entry: FinanceCostEntryState;
}

/** 创建录入区编辑动作。 */
export function createEntryActions(options: EntryActionOptions) {
  function toggleCategoryExpanded(category: FinanceCostCategoryCode) {
    const target = options.entry.categories.find(
      (item) => item.category === category,
    );
    if (!target) return;
    target.expanded = !target.expanded;
  }

  function setCategoryTotal(category: FinanceCostCategoryCode, value: number) {
    const target = options.entry.categories.find(
      (item) => item.category === category,
    );
    if (!target) return;
    target.totalAmount = Math.max(0, roundAmount(value));
    syncEntrySummary();
  }

  function upsertDetailItem(
    category: FinanceCostCategoryCode,
    detail: FinanceCostEntryDetailDto,
    mode: 'create' | 'edit',
  ) {
    const target = options.entry.categories.find(
      (item) => item.category === category,
    );
    if (!target) return;

    const nextItem: FinanceCostEntryDetailDto = {
      ...detail,
      itemId: detail.itemId || createTempItemId(),
      amount: resolveDetailAmount(category, detail),
      quantity:
        detail.quantity === undefined
          ? undefined
          : roundAmount(detail.quantity),
      unitPrice:
        detail.unitPrice === undefined
          ? undefined
          : roundAmount(detail.unitPrice),
      sortOrder: detail.sortOrder > 0 ? detail.sortOrder : 1,
    };

    const index = target.items.findIndex(
      (item) => item.itemId === detail.itemId,
    );
    if (mode === 'edit' && index !== -1) {
      target.items.splice(index, 1, nextItem);
    } else {
      target.items.push(nextItem);
    }

    target.items.sort((left, right) => left.sortOrder - right.sortOrder);
    target.totalAmount = sumCategoryItems(target);
    syncEntrySummary();
  }

  function removeDetailItem(
    category: FinanceCostCategoryCode,
    itemId: string | undefined,
  ) {
    const target = options.entry.categories.find(
      (item) => item.category === category,
    );
    if (!target || !itemId) return;

    target.items = target.items.filter((item) => item.itemId !== itemId);
    target.totalAmount = sumCategoryItems(target);
    syncEntrySummary();
  }

  function syncEntrySummary() {
    const totalCost = sumAllCategoryTotal(options.entry.categories);
    options.entry.totalCost = totalCost;
    options.entry.costRate =
      options.entry.monthRevenue > 0
        ? roundAmount((totalCost / options.entry.monthRevenue) * 100)
        : 0;
  }

  return {
    removeDetailItem,
    setCategoryTotal,
    syncEntrySummary,
    toggleCategoryExpanded,
    upsertDetailItem,
  };
}

function resolveDetailAmount(
  category: FinanceCostCategoryCode,
  detail: FinanceCostEntryDetailDto,
) {
  if (category !== 'labor') {
    return Math.max(0, roundAmount(detail.amount));
  }

  const quantity = roundAmount(detail.quantity ?? 0);
  const unitPrice = roundAmount(detail.unitPrice ?? 0);
  return Math.max(0, roundAmount(quantity * unitPrice));
}

function createTempItemId() {
  return `tmp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}
