<template>
  <section class="page-grid">
    <section class="panel finance-board-panel finance-precision-panel">
      <header class="finance-board-header page-hero-card finance-report-hero">
        <div class="finance-board-title page-hero-copy">
          <p class="eyebrow">06 财务分析</p>
          <span
            class="title-with-help"
            title="按时间范围回算订单、生产、库存、报工、返工报废和费用数据，统一落在冲压产品材料成本核算表。"
          >
            <h3>{{ displayTitle }}</h3>
          </span>
        </div>

        <div class="finance-board-toolbar page-hero-actions filter-ribbon finance-filter-ribbon">
          <label class="form-field finance-compact-field">
            <span>开始日期</span>
            <input v-model="filters.date_from" type="date" />
          </label>
          <label class="form-field finance-compact-field">
            <span>结束日期</span>
            <input v-model="filters.date_to" type="date" />
          </label>
          <button class="ghost-button" type="button" @click="expenseDrawerOpen = true">费用登记</button>
          <button class="primary-button" type="button" :disabled="loadingBoard" @click="loadBoard">
            {{ loadingBoard ? "刷新中..." : "刷新核算表" }}
          </button>
        </div>
      </header>

      <div v-if="feedbackMessage" class="feedback-banner">{{ feedbackMessage }}</div>
      <div v-if="errorMessage" class="feedback-banner error-banner">{{ errorMessage }}</div>

      <div class="finance-inline-stats">
        <article
          v-for="stat in topStats"
          :key="stat.label"
          class="finance-inline-stat"
          :class="stat.tone ? `finance-inline-stat-${stat.tone}` : ''"
        >
          <span>{{ stat.label }}</span>
          <strong>{{ stat.value }}</strong>
        </article>
      </div>

      <div class="finance-board-tags">
        <span class="table-chip">工单 {{ board.summary.row_count }} 条</span>
        <span class="table-chip">数据区间 {{ formatDate(board.date_from) }} ~ {{ formatDate(board.date_to) }}</span>
        <span class="table-chip">更新时间 {{ formatDateTime(board.generated_at) }}</span>
      </div>

      <TableControls
        v-model:search="boardControls.search.value"
        v-model:sort-key="boardControls.sortKey.value"
        v-model:sort-direction="boardControls.sortDirection.value"
        :sort-options="boardControls.sortOptions"
        placeholder="搜索工单、产品、客户、供料、送货单、材质"
      />

      <div class="finance-sheet-wrap">
        <table class="finance-sheet-table">
          <thead>
            <tr class="finance-sheet-title-row">
              <th :colspan="sheetColumns.length">{{ displayTitle }}</th>
            </tr>
            <tr class="finance-sheet-group-row">
              <th
                v-for="group in sheetGroups"
                :key="group.label"
                :colspan="group.colspan"
                :class="{ 'finance-sheet-group-single': group.colspan === 1 }"
              >
                {{ group.label }}
              </th>
            </tr>
            <tr class="finance-sheet-column-row">
              <th
                v-for="column in sheetColumns"
                :key="column.key"
                :class="headerClasses(column)"
                :style="{ minWidth: column.width, width: column.width }"
              >
                {{ column.label }}
              </th>
            </tr>
          </thead>
          <tbody>
            <tr v-if="!filteredBoardRows.length">
              <td :colspan="sheetColumns.length" class="finance-empty-cell">
                当前时间范围内暂无可核算的生产工单数据。
              </td>
            </tr>
            <tr
              v-for="row in paginatedBoardRows"
              :key="`${row.work_order_id}-${row.row_no}`"
              :class="rowClasses(row)"
            >
              <td
                v-for="column in sheetColumns"
                :key="column.key"
                :class="cellClasses(column, row)"
                :style="{ minWidth: column.width, width: column.width }"
              >
                <template v-if="column.key === 'product_code'">
                  <div class="finance-code-cell">
                    <strong>{{ row.product_code || "-" }}</strong>
                    <small>{{ row.work_order_no }}</small>
                  </div>
                </template>
                <template v-else-if="column.key === 'supply_mode'">
                  <span class="finance-mode-chip" :class="modeClass(row.supply_mode)">
                    {{ row.supply_mode || "-" }}
                  </span>
                </template>
                <template v-else-if="column.key === 'delivery_note_no'">
                  <div class="finance-note-cell">
                    <span>{{ row.delivery_note_no || "-" }}</span>
                  </div>
                </template>
                <template v-else>
                  {{ formatColumnValue(column, row) }}
                </template>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
      <PaginationBar v-model:page="boardPage" v-model:page-size="boardPageSize" :total="boardTotal" />

      <div class="finance-footer-stack">
        <table class="finance-rollup-table">
          <tbody>
            <tr>
              <th>{{ summaryLabels.sales }}</th>
              <td>{{ formatMoney(board.summary.sales_total) }}</td>
              <th>成本比例</th>
              <td>{{ formatPercent(board.summary.cost_ratio) }}</td>
              <th>{{ summaryLabels.grossMaterial }}</th>
              <td>{{ formatMoney(board.summary.gross_material_total) }}</td>
              <th>{{ summaryLabels.scrapRevenue }}</th>
              <td>{{ formatMoney(board.summary.scrap_revenue_total) }}</td>
              <th>{{ summaryLabels.materialCost }}</th>
              <td>{{ formatMoney(board.summary.material_cost_total) }}</td>
              <th>{{ summaryLabels.materialLoss }}</th>
              <td>{{ formatMoney(board.summary.material_loss_total) }}</td>
            </tr>
          </tbody>
        </table>

        <table class="finance-expense-table">
          <tbody>
            <tr v-for="expense in board.expense_rows" :key="expense.key">
              <th>{{ expense.label }}</th>
              <td>{{ formatMoney(expense.amount) }}</td>
            </tr>
            <tr class="finance-expense-profit-row">
              <th>{{ summaryLabels.profit }}</th>
              <td :class="{ 'negative-value': Number(board.summary.profit_amount || 0) < 0 }">
                {{ formatMoney(board.summary.profit_amount) }}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </section>

    <Teleport to="body">
      <div v-if="expenseDrawerOpen" class="workflow-drawer-mask finance-expense-mask" @click.self="closeExpenseDrawer">
        <aside class="workflow-drawer finance-expense-drawer">
          <header class="workflow-drawer-head">
            <div>
              <p class="eyebrow">费用登记</p>
              <span class="title-with-help" title="费用日期会直接参与上方时间范围刷新。">
                <h3>把选定期间的人工、租金、水电、折旧等费用记入核算大屏</h3>
              </span>
            </div>
            <div class="workflow-drawer-head-actions">
              <span class="table-chip">{{ expensePreviewLabel }}</span>
              <button class="ghost-button" type="button" @click="closeExpenseDrawer">关闭</button>
            </div>
          </header>

          <div class="finance-expense-grid">
            <section class="workflow-section-card">
              <form class="stack-form" @submit.prevent="submitExpense">
                <div class="double-field">
                  <label class="form-field">
                    <span>费用日期</span>
                    <input v-model="expenseForm.accounting_date" type="date" required />
                  </label>
                  <label class="form-field">
                    <span>费用类型</span>
                    <select v-model="expenseForm.overhead_type" required @change="applyOverheadDefaults">
                      <option v-for="option in overheadOptions" :key="option.value" :value="option.value">
                        {{ option.label }}
                      </option>
                    </select>
                  </label>
                </div>

                <div class="double-field">
                  <label class="form-field">
                    <span>金额</span>
                    <input v-model.number="expenseForm.amount" type="number" min="0" step="0.01" required />
                  </label>
                  <label class="form-field">
                    <span>分摊依据</span>
                    <select v-model="expenseForm.allocation_basis">
                      <option value="WORK_HOURS">工时</option>
                      <option value="MACHINE_HOURS">机时</option>
                      <option value="QTY">产量</option>
                      <option value="OCCUPIED_AREA">占地面积</option>
                    </select>
                  </label>
                </div>

                <label class="form-field">
                  <span>备注</span>
                  <input v-model.trim="expenseForm.description" type="text" placeholder="例如：4月上旬厂房租金、水电、包装耗材" />
                </label>

                <div class="workflow-inline-actions">
                  <button class="primary-button" type="submit" :disabled="submittingExpense">
                    {{ submittingExpense ? "保存中..." : "登记费用" }}
                  </button>
                  <span class="panel-tag">{{ currentOverheadLabel }}</span>
                </div>
              </form>
            </section>

            <aside class="workflow-summary-card">
              <div class="panel-header">
                <div>
                  <p class="eyebrow">最近费用</p>
                  <h3>当前费用月份</h3>
                </div>
                <span class="table-chip">{{ expensePeriodCode }}</span>
              </div>

              <div class="table-wrap">
                <TableControls
                  v-model:search="expenseControls.search.value"
                  v-model:sort-key="expenseControls.sortKey.value"
                  v-model:sort-direction="expenseControls.sortDirection.value"
                  :sort-options="expenseControls.sortOptions"
                  placeholder="搜索费用日期、类型、分摊依据、金额、备注"
                />
                <table class="data-table compact-table">
                  <thead>
                    <tr>
                      <th>日期</th>
                      <th>类型</th>
                      <th>分摊依据</th>
                      <th>金额</th>
                      <th>备注</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr v-for="item in paginatedRecentExpenseRows" :key="item.overhead_entry_id">
                      <td>{{ formatDate(extractExpenseDate(item) || item.created_at) }}</td>
                      <td>{{ formatOverheadLabel(item.overhead_type) }}</td>
                      <td>{{ formatAllocationBasisLabel(item.allocation_basis) }}</td>
                      <td>¥{{ formatMoney(item.amount) }}</td>
                      <td>{{ stripExpenseMetadata(item.description) || "-" }}</td>
                    </tr>
                    <tr v-if="!filteredRecentExpenseRows.length">
                      <td colspan="5" class="empty-row">当前费用月份还没有录入记录</td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <PaginationBar
                v-model:page="recentExpensePage"
                v-model:page-size="recentExpensePageSize"
                :total="recentExpenseTotal"
              />
            </aside>
          </div>
        </aside>
      </div>
    </Teleport>
  </section>
</template>

<script setup>
import { computed, onMounted, reactive, ref } from "vue"

import PaginationBar from "../components/PaginationBar.vue"
import TableControls from "../components/TableControls.vue"
import { useBodyScrollLock } from "../composables/useBodyScrollLock"
import { postResource, requestJson } from "../services/api"
import { dictionaryFallback, normalizeDictionaryKey } from "../utils/dictionaries"
import { formatAmount, formatDate, formatDateTime, formatQty } from "../utils/formatters"
import { usePagination } from "../utils/pagination"
import { useTableControls } from "../utils/tableControls"

const overheadOptions = [
  { value: "OPERATOR_WAGE", label: "操作工人工资" },
  { value: "MANAGER_WAGE", label: "管理人员工资" },
  { value: "FINANCE_CHARGE", label: "财务费用" },
  { value: "MOULD_MAINTENANCE", label: "模具维护成本" },
  { value: "OUTSOURCE_PROCESS", label: "外协加工费" },
  { value: "PRODUCTION_PACKAGING", label: "生产包装" },
  { value: "EQUIPMENT_DEPRECIATION", label: "设备折旧费" },
  { value: "UTILITY", label: "水电能耗" },
  { value: "OFFICE_SUPPLIES", label: "办公用品" },
  { value: "FACTORY_RENT", label: "厂房租金" },
  { value: "TEMPORARY_WAGE", label: "临时工工资" },
  { value: "STAFF_WELFARE", label: "职工福利" },
  { value: "SOCIAL_INSURANCE", label: "社保费" },
  { value: "CASH_MISC", label: "白条费用" },
  { value: "OTHER", label: "其它" }
]

const overheadLabelMap = Object.fromEntries(overheadOptions.map((item) => [item.value, item.label]))
const allocationBasisLabelMap = {
  WORK_HOURS: "工时",
  MACHINE_HOURS: "机时",
  QTY: "产量",
  OCCUPIED_AREA: "占地面积"
}

const sheetGroups = [
  { label: "订单信息", colspan: 8 },
  { label: "当月生产数量+发货与成品库存以及价值", colspan: 6 },
  { label: "当月材料购买使用情况与库存", colspan: 5 },
  { label: "毛料成本", colspan: 6 },
  { label: "废料收益", colspan: 4 },
  { label: "合计成本", colspan: 4 },
  { label: "人工成本", colspan: 2 },
  { label: "委外成本", colspan: 2 },
  { label: "产品成本核算", colspan: 3 },
  { label: "返工成本", colspan: 3 },
  { label: "报废成本", colspan: 3 },
  { label: "返工报废本批平均值", colspan: 1 }
]

const sheetColumns = [
  { key: "row_no", label: "序号", type: "index", sticky: 1, width: "84px" },
  { key: "biz_date", label: "日期", type: "date", sticky: 2, width: "116px" },
  { key: "product_code", label: "产品代码", type: "code", sticky: 3, width: "160px" },
  { key: "customer_name", label: "客户", type: "text", sticky: 4, width: "160px" },
  { key: "product_name", label: "产品名称", type: "text", sticky: 5, width: "180px" },
  { key: "supply_mode", label: "供料", type: "mode", width: "120px" },
  { key: "delivery_note_no", label: "送货单号", type: "text", width: "180px" },
  { key: "order_qty", label: "订单数量", type: "qty", width: "120px" },
  { key: "actual_production_qty", label: "实际生产数量", type: "qty", width: "130px" },
  { key: "shipped_qty", label: "出货数量", type: "qty", width: "120px" },
  { key: "inventory_qty", label: "库存数量PCS", type: "qty", width: "130px" },
  { key: "inventory_value", label: "库存价值", type: "money", width: "130px" },
  { key: "untaxed_unit_price", label: "未税单价", type: "money", width: "120px" },
  { key: "untaxed_total_amount", label: "未税产品总价", type: "money", width: "150px" },
  { key: "purchase_material_weight_kg", label: "购买材料重量KG", type: "qty", width: "150px" },
  { key: "used_material_weight_kg", label: "使用重量KG", type: "qty", width: "130px" },
  { key: "material_inventory_weight_kg", label: "库存重量KG", type: "qty", width: "130px" },
  { key: "material_inventory_producible_qty", label: "库存可生产数量", type: "qty", width: "150px" },
  { key: "material_inventory_value", label: "库存原料价值", type: "money", width: "140px" },
  { key: "material_grade", label: "材质", type: "text", width: "150px" },
  { key: "material_unit_price_kg", label: "材料单价kg", type: "money", width: "130px" },
  { key: "gross_weight_g", label: "单件毛料重量g", type: "qty", width: "140px" },
  { key: "gross_material_cost_per_piece", label: "单毛料成本", type: "money", width: "130px" },
  { key: "gross_material_total_cost", label: "合计毛料成本", type: "money", width: "140px" },
  { key: "net_weight_g", label: "产品净重g", type: "qty", width: "130px" },
  { key: "scrap_weight_g", label: "废料重量", type: "qty", width: "120px" },
  { key: "scrap_unit_price_kg", label: "废料单价", type: "money", width: "120px" },
  { key: "scrap_revenue_per_piece", label: "单件废料收益", type: "money", width: "140px" },
  { key: "scrap_total_revenue", label: "合计废料收益", type: "money", width: "140px" },
  { key: "material_cost_per_piece", label: "单件材料成本", type: "money", width: "140px" },
  { key: "material_total_cost", label: "合计材料成本", type: "money", width: "140px" },
  { key: "loss_rate", label: "损耗率", type: "percent", width: "110px" },
  { key: "loss_total_cost", label: "损耗率合计成本", type: "money", width: "150px" },
  { key: "labor_cost_per_piece", label: "单件人工成本", type: "money", width: "140px" },
  { key: "labor_total_cost", label: "人工合计成本", type: "money", width: "140px" },
  { key: "outsource_cost_per_piece", label: "单件成本", type: "money", width: "120px" },
  { key: "outsource_total_cost", label: "总成本", type: "money", width: "120px" },
  { key: "product_cost_per_piece", label: "单价产品成本", type: "money", width: "140px" },
  { key: "product_cost_with_adjustment_per_piece", label: "包含返工报废成本", type: "money", width: "160px" },
  { key: "product_total_cost", label: "合计成本", type: "money", width: "130px" },
  { key: "rework_qty", label: "返工数量", type: "qty", width: "120px" },
  { key: "rework_cost_per_piece", label: "返工成本", type: "money", width: "120px" },
  { key: "rework_total_cost", label: "返工总成本", type: "money", width: "140px" },
  { key: "scrap_qty", label: "报废数量", type: "qty", width: "120px" },
  { key: "scrap_residual_value_per_piece", label: "报废品残值", type: "money", width: "130px" },
  { key: "scrap_total_cost", label: "报废成本", type: "money", width: "120px" },
  { key: "batch_adjustment_avg_cost", label: "返工报废本批平均值", type: "money", width: "170px" }
]

const EXPENSE_DATE_PREFIX = /^\[EXPENSE_DATE:(\d{4}-\d{2}-\d{2})\]\s*/

function padNumber(value) {
  return String(value).padStart(2, "0")
}

function getToday() {
  const now = new Date()
  return `${now.getFullYear()}-${padNumber(now.getMonth() + 1)}-${padNumber(now.getDate())}`
}

function getMonthRange(value) {
  const [year, month] = String(value || getToday())
    .slice(0, 10)
    .split("-")
    .map((item) => Number(item))
  const lastDay = new Date(year, month, 0).getDate()
  return {
    year,
    month,
    start: `${year}-${padNumber(month)}-01`,
    end: `${year}-${padNumber(month)}-${padNumber(lastDay)}`
  }
}

function buildEmptyBoard(dateFrom, dateTo) {
  return {
    title: "冲压产品材料成本核算表",
    date_from: dateFrom,
    date_to: dateTo,
    generated_at: new Date().toISOString(),
    rows: [],
    expense_rows: overheadOptions.map((item) => ({
      key: item.value.toLowerCase(),
      label: `${item.label}：`,
      amount: 0
    })),
    summary: {
      row_count: 0,
      sales_total: 0,
      gross_material_total: 0,
      scrap_revenue_total: 0,
      material_cost_total: 0,
      material_loss_total: 0,
      labor_total: 0,
      outsource_total: 0,
      rework_total: 0,
      scrap_total: 0,
      overhead_total: 0,
      direct_cost_total: 0,
      profit_amount: 0,
      cost_ratio: 0
    }
  }
}

function formatMoney(value) {
  return formatAmount(value)
}

function formatPercent(value) {
  return `${(Number(value || 0) * 100).toFixed(2)}%`
}

function formatOverheadLabel(value) {
  return overheadLabelMap[normalizeDictionaryKey(value)] || dictionaryFallback(value, "-", "未识别费用类型")
}

function formatAllocationBasisLabel(value) {
  return allocationBasisLabelMap[normalizeDictionaryKey(value)] || dictionaryFallback(value, "-", "未识别分摊依据")
}

function extractExpenseDate(entry) {
  const match = String(entry?.description || "").match(EXPENSE_DATE_PREFIX)
  return match?.[1] || null
}

function stripExpenseMetadata(description) {
  return String(description || "").replace(EXPENSE_DATE_PREFIX, "").trim()
}

function buildExpenseDescription(accountingDate, description) {
  const note = stripExpenseMetadata(description)
  return note ? `[EXPENSE_DATE:${accountingDate}] ${note}` : `[EXPENSE_DATE:${accountingDate}]`
}

const today = getToday()
const defaultMonth = getMonthRange(today)

const loadingBoard = ref(false)
const submittingExpense = ref(false)
const expenseDrawerOpen = ref(false)
const feedbackMessage = ref("")
const errorMessage = ref("")
const board = ref(buildEmptyBoard(defaultMonth.start, defaultMonth.end))
const periods = ref([])
const overheads = ref([])

const filters = reactive({
  date_from: defaultMonth.start,
  date_to: defaultMonth.end
})

const expenseForm = reactive({
  accounting_date: today,
  overhead_type: "UTILITY",
  amount: 0,
  allocation_basis: "WORK_HOURS",
  description: ""
})

useBodyScrollLock(computed(() => expenseDrawerOpen.value))

const isSingleMonthRange = computed(() => String(filters.date_from || "").slice(0, 7) === String(filters.date_to || "").slice(0, 7))

const periodWord = computed(() => (isSingleMonthRange.value ? "本月" : "本期"))

const displayTitle = computed(() => {
  if (!filters.date_from || !filters.date_to) {
    return "冲压产品材料成本核算表"
  }
  if (isSingleMonthRange.value) {
    const [year, month] = filters.date_from.split("-")
    return `${year}年${Number(month)}月冲压产品材料成本核算表`
  }
  return `冲压产品材料成本核算表（${filters.date_from} ~ ${filters.date_to}）`
})

const summaryLabels = computed(() => ({
  sales: `${periodWord.value}销售额：`,
  grossMaterial: `${periodWord.value}合计毛料成本：`,
  scrapRevenue: `${periodWord.value}合计废料收益：`,
  materialCost: `${periodWord.value}材料成本合计：`,
  materialLoss: `${periodWord.value}材料折损价值：`,
  profit: `${periodWord.value}利润：`
}))

const topStats = computed(() => [
  { label: `${periodWord.value}销售额`, value: `¥${formatMoney(board.value.summary.sales_total)}`, tone: "steel" },
  { label: "材料成本", value: `¥${formatMoney(board.value.summary.material_cost_total)}` },
  { label: "人工成本", value: `¥${formatMoney(board.value.summary.labor_total)}` },
  { label: "委外成本", value: `¥${formatMoney(board.value.summary.outsource_total)}`, tone: "copper" },
  { label: "直接成本", value: `¥${formatMoney(board.value.summary.direct_cost_total)}` },
  {
    label: `${periodWord.value}利润`,
    value: `¥${formatMoney(board.value.summary.profit_amount)}`,
    tone: Number(board.value.summary.profit_amount || 0) < 0 ? "danger" : "success"
  }
])

const boardRows = computed(() => board.value.rows || [])
const boardControls = useTableControls(boardRows, {
  searchFields: [
    "work_order_no",
    "product_code",
    "product_name",
    "customer_name",
    "supply_mode",
    "delivery_note_no",
    "material_grade"
  ],
  sortOptions: [
    { key: "biz_date", label: "日期" },
    { key: "product_code", label: "产品代码" },
    { key: "customer_name", label: "客户" },
    { key: "order_qty", label: "订单数量" },
    { key: "actual_production_qty", label: "实际生产数量" },
    { key: "shipped_qty", label: "出货数量" },
    { key: "inventory_qty", label: "库存数量" },
    { key: "material_cost_per_piece", label: "单件材料成本" },
    { key: "product_cost_with_adjustment_per_piece", label: "含返工报废成本" },
    { key: "product_total_cost", label: "合计成本" }
  ],
  defaultSortKey: "biz_date",
  defaultSortDirection: "desc"
})
const filteredBoardRows = boardControls.rows
const {
  page: boardPage,
  pageSize: boardPageSize,
  total: boardTotal,
  rows: paginatedBoardRows
} = usePagination(filteredBoardRows)

const expensePeriodRange = computed(() => getMonthRange(expenseForm.accounting_date || today))

const expensePeriodCode = computed(
  () => `${expensePeriodRange.value.year}${padNumber(expensePeriodRange.value.month)}`
)

const expensePreviewLabel = computed(
  () => `${expensePeriodRange.value.year}年${expensePeriodRange.value.month}月费用`
)

const currentOverheadLabel = computed(() => formatOverheadLabel(expenseForm.overhead_type))

function applyOverheadDefaults() {
  if (expenseForm.overhead_type === "FACTORY_RENT" && expenseForm.allocation_basis !== "OCCUPIED_AREA") {
    expenseForm.allocation_basis = "OCCUPIED_AREA"
  }
}

const recentExpenseRows = computed(() =>
  overheads.value
    .filter(
      (item) =>
        Number(item.year_no || 0) === expensePeriodRange.value.year &&
        Number(item.month_no || 0) === expensePeriodRange.value.month
    )
)
const expenseControls = useTableControls(recentExpenseRows, {
  searchFields: [
    (row) => extractExpenseDate(row) || row.created_at,
    (row) => formatOverheadLabel(row.overhead_type),
    (row) => formatAllocationBasisLabel(row.allocation_basis),
    "amount",
    (row) => stripExpenseMetadata(row.description)
  ],
  sortOptions: [
    { key: "created_at", label: "创建时间" },
    { key: "overhead_type", label: "费用类型" },
    { key: "allocation_basis", label: "分摊依据" },
    { key: "amount", label: "金额" },
    { key: "description", label: "备注" }
  ],
  defaultSortKey: "created_at",
  defaultSortDirection: "desc"
})
const filteredRecentExpenseRows = expenseControls.rows

const {
  page: recentExpensePage,
  pageSize: recentExpensePageSize,
  total: recentExpenseTotal,
  rows: paginatedRecentExpenseRows
} = usePagination(filteredRecentExpenseRows)

function headerClasses(column) {
  return {
    "finance-sticky-cell": Boolean(column.sticky),
    [`finance-sticky-${column.sticky}`]: Boolean(column.sticky)
  }
}

function cellClasses(column, row) {
  return {
    "finance-sticky-cell": Boolean(column.sticky),
    [`finance-sticky-${column.sticky}`]: Boolean(column.sticky),
    "finance-number-cell": ["qty", "money", "percent", "index"].includes(column.type),
    "negative-value":
      ["money"].includes(column.type) &&
      Number(row?.[column.key] || 0) < 0
  }
}

function rowClasses(row) {
  return {
    "finance-sheet-row-loss":
      Number(row.product_cost_with_adjustment_per_piece || 0) > Number(row.untaxed_unit_price || 0),
    "finance-sheet-row-warning": Number(row.loss_rate || 0) >= 0.05
  }
}

function modeClass(value) {
  if (value === "自家料") {
    return "finance-mode-self"
  }
  if (value === "客供料") {
    return "finance-mode-customer"
  }
  if (value === "外协发加工") {
    return "finance-mode-outsource"
  }
  return ""
}

function formatColumnValue(column, row) {
  const value = row?.[column.key]
  if (column.type === "date") {
    return formatDate(value)
  }
  if (column.type === "index") {
    return value ?? "-"
  }
  if (column.type === "qty") {
    return formatQty(value)
  }
  if (column.type === "money") {
    return formatMoney(value)
  }
  if (column.type === "percent") {
    return formatPercent(value)
  }
  return value || "-"
}

async function loadReferenceData() {
  const [periodRows, overheadRows] = await Promise.all([
    requestJson("/finance/periods", { method: "GET" }).catch(() => []),
    requestJson("/finance/overheads", { method: "GET" }).catch(() => [])
  ])

  periods.value = periodRows
  overheads.value = overheadRows
}

async function loadBoard() {
  feedbackMessage.value = ""
  errorMessage.value = ""

  if (filters.date_from && filters.date_to && filters.date_from > filters.date_to) {
    errorMessage.value = "开始日期不能晚于结束日期"
    return
  }

  loadingBoard.value = true

  try {
    const result = await requestJson(
      `/finance/product-material-cost-board?date_from=${filters.date_from}&date_to=${filters.date_to}`,
      { method: "GET" }
    )
    board.value = result
  } catch (error) {
    board.value = buildEmptyBoard(filters.date_from, filters.date_to)
    errorMessage.value = error.message || "产品材料成本核算表加载失败"
  } finally {
    loadingBoard.value = false
  }
}

async function ensureAccountingPeriod(accountingDate) {
  const { year, month, start, end } = getMonthRange(accountingDate)
  const existingPeriod = periods.value.find(
    (item) => Number(item.year_no || 0) === year && Number(item.month_no || 0) === month
  )

  if (existingPeriod) {
    return existingPeriod.period_id
  }

  const createdPeriod = await postResource("/finance/periods", {
    year_no: year,
    month_no: month,
    start_date: start,
    end_date: end,
    close_status: "OPEN"
  })

  periods.value = [createdPeriod, ...periods.value]
  return createdPeriod.period_id
}

async function submitExpense() {
  feedbackMessage.value = ""
  errorMessage.value = ""

  if (Number(expenseForm.amount || 0) <= 0) {
    errorMessage.value = "费用金额必须大于 0"
    return
  }

  submittingExpense.value = true

  try {
    const periodId = await ensureAccountingPeriod(expenseForm.accounting_date)
    await postResource("/finance/overheads", {
      period_id: Number(periodId),
      overhead_type: expenseForm.overhead_type,
      amount: Number(expenseForm.amount || 0),
      allocation_basis: expenseForm.allocation_basis,
      description: buildExpenseDescription(expenseForm.accounting_date, expenseForm.description)
    })

    feedbackMessage.value = `${formatOverheadLabel(expenseForm.overhead_type)}已登记到 ${expensePreviewLabel.value}`
    expenseForm.amount = 0
    expenseForm.description = ""

    await Promise.all([loadReferenceData(), loadBoard()])
  } catch (error) {
    errorMessage.value = error.message || "费用登记失败"
  } finally {
    submittingExpense.value = false
  }
}

function closeExpenseDrawer() {
  expenseDrawerOpen.value = false
}

onMounted(async () => {
  await Promise.all([loadReferenceData(), loadBoard()])
})
</script>
