<template>
  <section class="page-grid">
    <section class="panel">
      <div class="panel-header">
        <div>
          <p class="eyebrow">退货与处置</p>
          <h3>退货闭环看板</h3>
        </div>
        <div class="workflow-inline-actions">
          <span class="panel-tag">售后闭环</span>
          <button class="primary-button" type="button" @click="openReturnDrawer">新增退货</button>
        </div>
      </div>

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

      <TableControls
        v-model:search="returnControls.search.value"
        v-model:sort-key="returnControls.sortKey.value"
        v-model:sort-direction="returnControls.sortDirection.value"
        :sort-options="returnControls.sortOptions"
        placeholder="搜索退货单号、客户、产品、订单、发货单、原因、状态"
      />

      <div class="table-wrap">
        <table class="data-table compact-table">
          <thead>
            <tr>
              <th>退货单号</th>
              <th>客户</th>
              <th>产品</th>
              <th>订单号</th>
              <th>发货单号</th>
              <th>退货日期</th>
              <th>原因</th>
              <th>状态</th>
              <th>退货数量</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="row in paginatedReturnOrders" :key="row.return_order_id" :class="{ 'row-selected': selectedReturnOrderId === row.return_order_id }">
              <td>{{ row.return_no }}</td>
              <td>{{ row.customer_name }}</td>
              <td>{{ row.product_names || "-" }}</td>
              <td>{{ row.order_no || "-" }}</td>
              <td>{{ row.delivery_no || "-" }}</td>
              <td>{{ formatDateTime(row.return_date) }}</td>
              <td>{{ row.return_reason || "-" }}</td>
              <td>{{ formatStatusLabel(row.status) }}</td>
              <td>{{ formatQty(row.total_return_qty) }}</td>
              <td class="action-row">
                <button class="ghost-button" type="button" @click="openDispositionDrawer(row)">处置</button>
                <button class="ghost-button" type="button" @click="openDispositionRecordsDrawer(row)">处置记录</button>
              </td>
            </tr>
            <tr v-if="!filteredReturnOrders.length">
              <td colspan="10" class="empty-row">暂无退货记录</td>
            </tr>
          </tbody>
        </table>
      </div>
      <PaginationBar v-model:page="returnOrderPage" v-model:page-size="returnOrderPageSize" :total="filteredReturnOrders.length" />
    </section>

    <FormDrawer
      :open="returnDrawerOpen"
      eyebrow="退货登记"
      title="新增退货"
      description="登记客户退货、来源订单和退货明细，退货重量会根据退货数量和产品单重自动补全。"
      tag="退货入仓"
      wide
      @close="returnDrawerOpen = false"
    >
      <form class="stack-form" @submit.prevent="submitReturnOrder">
        <div class="double-field">
          <label class="form-field">
            <span>客户</span>
            <select v-model.number="orderForm.customer_id" required>
              <option disabled value="">请选择客户</option>
              <option v-for="customer in customers" :key="customer.id" :value="customer.id">
                {{ customer.customer_name }}
              </option>
            </select>
          </label>
          <label class="form-field">
            <span>订单</span>
            <select v-model.number="orderForm.sales_order_id">
              <option value="">不关联</option>
              <option v-for="order in orders" :key="order.order_id" :value="order.order_id">
                {{ order.order_no }}
              </option>
            </select>
          </label>
        </div>

        <div class="double-field">
          <label class="form-field">
            <span>发货单</span>
            <select v-model.number="orderForm.delivery_id">
              <option value="">不关联</option>
              <option v-for="delivery in deliveries" :key="delivery.delivery_id" :value="delivery.delivery_id">
                {{ delivery.delivery_no }} · {{ delivery.order_no }}
              </option>
            </select>
          </label>
          <label class="form-field">
            <span>处理人</span>
            <select v-model.number="orderForm.handler_employee_id">
              <option value="">请选择</option>
              <option v-for="employee in employees" :key="employee.id" :value="employee.id">
                {{ employeeOptionLabel(employee) }}
              </option>
            </select>
          </label>
        </div>

        <label class="form-field">
          <span>退货原因</span>
          <textarea v-model.trim="orderForm.return_reason" rows="2"></textarea>
        </label>

        <div class="subsection-head">
          <strong>退货明细</strong>
          <button class="ghost-button" type="button" @click="addRow">增加一行</button>
        </div>

        <div class="order-item-stack">
          <article v-for="(item, index) in orderForm.items" :key="index" class="order-item-card">
            <div class="subsection-head">
              <strong>明细 {{ index + 1 }}</strong>
              <button v-if="orderForm.items.length > 1" class="ghost-button danger-ghost" type="button" @click="removeRow(index)">
                删除
              </button>
            </div>

            <label class="form-field">
              <span>订单行</span>
              <select v-model.number="item.sales_order_item_id" @change="applyOrderItem(index)">
                <option value="">手工选产品</option>
                <option v-for="orderItem in orderItems" :key="orderItem.sales_order_item_id" :value="orderItem.sales_order_item_id">
                  {{ orderItem.order_no }} · {{ orderItem.product_name }}
                </option>
              </select>
            </label>

            <div class="double-field">
              <label class="form-field">
                <span>产品</span>
                <select v-model.number="item.product_item_id" required @change="recalculateReturnWeight(index)">
                  <option disabled value="">请选择产品</option>
                  <option v-for="product in products" :key="product.item_id" :value="product.item_id">
                    {{ product.item_code }} · {{ product.item_name }}
                  </option>
                </select>
              </label>
              <label class="form-field">
                <span>来源批次</span>
                <select v-model.number="item.source_lot_id">
                  <option value="">不指定</option>
                  <option v-for="lot in finishedLots" :key="lot.lot_id" :value="lot.lot_id">
                    {{ lot.lot_no }} · {{ lot.item_name }}
                  </option>
                </select>
              </label>
            </div>

            <div class="triple-field">
              <label class="form-field">
                <span>退货数量</span>
                <input v-model.number="item.return_qty" type="number" min="0" step="1" @input="recalculateReturnWeight(index)" />
              </label>
              <label class="form-field">
                <span>退货重量(kg)</span>
                <input v-model.number="item.return_weight_kg" type="number" min="0" step="0.001" />
              </label>
              <label class="form-field">
                <span>责任归属</span>
                <input v-model.trim="item.responsibility_type" type="text" placeholder="内部 / 外部 / 客户" />
              </label>
            </div>
          </article>
        </div>

        <button class="primary-button" type="submit" :disabled="submittingOrder">
          {{ submittingOrder ? "提交中..." : "创建退货单" }}
        </button>
      </form>
    </FormDrawer>

    <FormDrawer
      :open="dispositionDrawerOpen"
      eyebrow="退货处置"
      :title="activeReturnOrder ? `${activeReturnOrder.return_no} · ${activeReturnOrder.customer_name}` : '退货处置'"
      description="按退货明细选择返工或报废。返工记录额外人工成本，报废记录废料销售金额和报废重量。"
      tag="闭环处理"
      wide
      @close="dispositionDrawerOpen = false"
    >
      <form class="stack-form" @submit.prevent="submitDisposition">
        <label class="form-field">
          <span>待处置退货行</span>
          <select v-model.number="dispositionForm.return_item_id" required @change="applyDispositionItem">
            <option disabled value="">请选择退货行</option>
            <option v-for="item in currentDispositionItems" :key="item.return_item_id" :value="item.return_item_id">
              {{ item.return_no }} · {{ item.product_name }} · {{ formatQty(item.return_qty) }}
            </option>
          </select>
        </label>

        <label class="form-field">
          <span>处置方式</span>
          <select v-model="dispositionForm.disposition_type" @change="applyDispositionType">
            <option value="REWORK">返工</option>
            <option value="SCRAP">报废</option>
          </select>
        </label>

        <label v-if="dispositionForm.disposition_type === 'REWORK'" class="form-field">
          <span>额外人工成本</span>
          <input v-model.number="dispositionForm.extra_cost_amount" type="number" min="0" step="0.01" />
        </label>

        <div v-if="dispositionForm.disposition_type === 'SCRAP'" class="double-field">
          <label class="form-field">
            <span>报废重量(kg)</span>
            <input v-model.number="dispositionForm.scrap_weight_kg" type="number" min="0" step="0.001" />
          </label>
          <label class="form-field">
            <span>废料销售金额</span>
            <input v-model.number="dispositionForm.scrap_sale_amount" type="number" min="0" step="0.01" />
          </label>
        </div>

        <label class="form-field">
          <span>备注</span>
          <textarea v-model.trim="dispositionForm.remark" rows="2"></textarea>
        </label>

        <button class="primary-button" type="submit" :disabled="submittingDisposition">
          {{ submittingDisposition ? "处理中..." : "提交处置" }}
        </button>
      </form>
    </FormDrawer>

    <FormDrawer
      :open="dispositionRecordsDrawerOpen"
      eyebrow="处置记录"
      :title="activeReturnOrder ? `${activeReturnOrder.return_no} · 处置记录` : '处置记录'"
      tag="历史处置"
      size="xl"
      @close="dispositionRecordsDrawerOpen = false"
    >
      <TableControls
        v-model:search="dispositionControls.search.value"
        v-model:sort-key="dispositionControls.sortKey.value"
        v-model:sort-direction="dispositionControls.sortDirection.value"
        :sort-options="dispositionControls.sortOptions"
        placeholder="搜索处置单号、产品、方式、返工工单、状态"
      />
      <DrawerDataTable
        v-model:expanded-rows="expandedDispositionRows"
        :rows="paginatedDispositions"
        :columns="dispositionDrawerColumns"
        row-key="return_disposition_id"
        empty-text="暂无处置记录"
      >
        <template #cell-disposition_no="{ row }">
          <span class="drawer-cell-code" :title="row.disposition_no || ''">{{ row.disposition_no || "-" }}</span>
        </template>
        <template #detail="{ row }">
          <div class="drawer-row-detail-grid">
            <article><span>返工工单</span><strong>{{ row.rework_work_order_no || "-" }}</strong></article>
            <article><span>报废重量</span><strong>{{ formatWeight(row.scrap_weight_kg) }}</strong></article>
            <article><span>废料销售金额</span><strong>¥{{ formatAmount(row.scrap_sale_amount) }}</strong></article>
            <article><span>状态</span><strong>{{ formatStatusLabel(row.status) }}</strong></article>
          </div>
        </template>
      </DrawerDataTable>
      <PaginationBar v-model:page="dispositionPage" v-model:page-size="dispositionPageSize" :total="filteredDispositions.length" />
    </FormDrawer>
  </section>
</template>

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

import DrawerDataTable from "../components/DrawerDataTable.vue";
import FormDrawer from "../components/FormDrawer.vue";
import PaginationBar from "../components/PaginationBar.vue";
import TableControls from "../components/TableControls.vue";
import { fetchResource, postResource } from "../services/api";
import { PERSONNEL_PERMISSION_CODES, employeeOptionLabel, fetchPermissionEmployeeOptions } from "../services/employeeOptions";
import { formatDisposalTypeLabel, formatStatusLabel } from "../utils/dictionaries";
import { formatAmount, formatDateTime, formatQty, formatWeight } from "../utils/formatters";
import { usePagination } from "../utils/pagination";
import { useTableControls } from "../utils/tableControls";

const customers = ref([]);
const orders = ref([]);
const deliveries = ref([]);
const employees = ref([]);
const orderItems = ref([]);
const products = ref([]);
const finishedLots = ref([]);
const returnOrders = ref([]);
const returnItems = ref([]);
const dispositions = ref([]);
const feedbackMessage = ref("");
const errorMessage = ref("");
const submittingOrder = ref(false);
const submittingDisposition = ref(false);
const returnDrawerOpen = ref(false);
const dispositionDrawerOpen = ref(false);
const dispositionRecordsDrawerOpen = ref(false);
const selectedReturnOrderId = ref(null);
const expandedDispositionRows = ref([]);

const orderForm = reactive(buildReturnForm());
const dispositionForm = reactive(buildDispositionForm());

const activeReturnOrder = computed(() =>
  returnOrders.value.find((item) => item.return_order_id === Number(selectedReturnOrderId.value)) || null
);
const pendingItems = computed(() => returnItems.value.filter((item) => item.disposition_status === "PENDING"));
const currentDispositionItems = computed(() => {
  if (!selectedReturnOrderId.value) {
    return pendingItems.value;
  }
  return pendingItems.value.filter((item) => item.return_order_id === Number(selectedReturnOrderId.value));
});
const visibleDispositions = computed(() => {
  const order = activeReturnOrder.value;
  if (!order) {
    return [];
  }
  return dispositions.value.filter((item) => item.return_no === order.return_no);
});
const returnOrderRows = computed(() =>
  returnOrders.value.map((order) => ({
    ...order,
    product_names:
      order.product_names ||
      joinUniqueNames(returnItems.value.filter((item) => item.return_order_id === order.return_order_id).map((item) => item.product_name))
  }))
);
const returnControls = useTableControls(returnOrderRows, {
  searchFields: ["return_no", "customer_name", "product_names", "order_no", "delivery_no", "return_reason", "status"],
  sortOptions: [
    { key: "return_no", label: "退货单号" },
    { key: "customer_name", label: "客户" },
    { key: "product_names", label: "产品" },
    { key: "order_no", label: "订单" },
    { key: "return_date", label: "退货日期" },
    { key: "status", label: "状态" },
    { key: "total_return_qty", label: "退货数量" }
  ],
  defaultSortKey: "return_date",
  defaultSortDirection: "desc"
});
const dispositionControls = useTableControls(visibleDispositions, {
  searchFields: ["disposition_no", "product_name", "disposition_type", "rework_work_order_no", "status"],
  sortOptions: [
    { key: "disposition_no", label: "处置单号" },
    { key: "product_name", label: "产品" },
    { key: "disposition_type", label: "方式" },
    { key: "extra_cost_amount", label: "额外人工成本" },
    { key: "scrap_weight_kg", label: "报废重量" },
    { key: "scrap_sale_amount", label: "废料销售金额" },
    { key: "closed_at", label: "处置时间" }
  ],
  defaultSortKey: "closed_at",
  defaultSortDirection: "desc"
});
const filteredReturnOrders = returnControls.rows;
const filteredDispositions = dispositionControls.rows;
const dispositionDrawerColumns = computed(() => [
  { key: "disposition_no", label: "处置单号", type: "code", width: "22%" },
  { key: "product_name", label: "产品", type: "longText", width: "24%" },
  { key: "disposition_type", label: "处置方式", type: "status", width: "102px", format: (value) => formatDisposalTypeLabel(value) },
  { key: "extra_cost_amount", label: "额外人工成本", compactLabel: "人工成本", type: "number", width: "118px", format: (value) => `¥${formatAmount(value)}` },
  { key: "scrap_weight_kg", label: "报废重量", type: "number", width: "100px", format: (value) => formatWeight(value) },
  { key: "status", label: "状态", type: "status", width: "88px", format: (value) => formatStatusLabel(value) },
  { key: "rework_work_order_no", label: "返工工单", detailOnly: true },
  { key: "scrap_sale_amount", label: "废料销售金额", detailOnly: true, format: (value) => `¥${formatAmount(value)}` }
]);
const {
  page: returnOrderPage,
  pageSize: returnOrderPageSize,
  rows: paginatedReturnOrders
} = usePagination(filteredReturnOrders);
const {
  page: dispositionPage,
  pageSize: dispositionPageSize,
  rows: paginatedDispositions
} = usePagination(filteredDispositions);

function buildItemRow() {
  return {
    sales_order_item_id: "",
    product_item_id: "",
    source_lot_id: "",
    return_qty: 0,
    return_weight_kg: 0,
    responsibility_type: ""
  };
}

function joinUniqueNames(names) {
  const values = names.map((name) => String(name || "").trim()).filter(Boolean);
  return Array.from(new Set(values)).join("、");
}

function buildReturnForm() {
  return {
    customer_id: "",
    sales_order_id: "",
    delivery_id: "",
    handler_employee_id: "",
    return_reason: "",
    items: [buildItemRow()]
  };
}

function buildDispositionForm() {
  return {
    return_item_id: "",
    disposition_type: "REWORK",
    scrap_weight_kg: 0,
    extra_cost_amount: 0,
    scrap_sale_amount: 0,
    remark: ""
  };
}

function resetReturnForm() {
  Object.assign(orderForm, buildReturnForm());
}

function resetDispositionForm() {
  Object.assign(dispositionForm, buildDispositionForm());
}

function productUnitWeight(productItemId) {
  const product = products.value.find((item) => item.item_id === Number(productItemId));
  return Number(product?.unit_weight_kg || 0);
}

function recalculateReturnWeight(index) {
  const row = orderForm.items[index];
  row.return_weight_kg = Number((Number(row.return_qty || 0) * productUnitWeight(row.product_item_id)).toFixed(3));
}

function selectedDispositionItem() {
  return returnItems.value.find((item) => item.return_item_id === Number(dispositionForm.return_item_id)) || null;
}

function applyDispositionItem() {
  const item = selectedDispositionItem();
  if (!item) {
    return;
  }
  const calculatedWeight = Number(item.return_weight_kg || Number(item.return_qty || 0) * productUnitWeight(item.product_item_id));
  if (dispositionForm.disposition_type === "SCRAP") {
    dispositionForm.scrap_weight_kg = Number(calculatedWeight.toFixed(3));
    dispositionForm.extra_cost_amount = 0;
  } else {
    dispositionForm.scrap_weight_kg = 0;
    dispositionForm.scrap_sale_amount = 0;
  }
}

function applyDispositionType() {
  applyDispositionItem();
}

function openReturnDrawer() {
  resetReturnForm();
  feedbackMessage.value = "";
  errorMessage.value = "";
  returnDrawerOpen.value = true;
}

function openDispositionDrawer(order) {
  selectedReturnOrderId.value = order.return_order_id;
  resetDispositionForm();
  const firstItem = currentDispositionItems.value[0];
  if (firstItem) {
    dispositionForm.return_item_id = firstItem.return_item_id;
    applyDispositionItem();
  }
  feedbackMessage.value = "";
  errorMessage.value = "";
  dispositionDrawerOpen.value = true;
}

function openDispositionRecordsDrawer(order) {
  selectedReturnOrderId.value = order.return_order_id;
  expandedDispositionRows.value = [];
  dispositionRecordsDrawerOpen.value = true;
}

function addRow() {
  orderForm.items.push(buildItemRow());
}

function removeRow(index) {
  orderForm.items.splice(index, 1);
}

function applyOrderItem(index) {
  const row = orderForm.items[index];
  const orderItem = orderItems.value.find((item) => item.sales_order_item_id === Number(row.sales_order_item_id));
  if (!orderItem) {
    return;
  }
  row.product_item_id = orderItem.product_item_id;
  row.return_qty = Number(orderItem.delivered_qty || 0);
  recalculateReturnWeight(index);
}

async function loadAll() {
  const [customerRows, orderRows, deliveryRows, employeeRows, orderItemRows, productRows, lotRows, returnOrderRows, returnItemRows, dispositionRows] =
    await Promise.all([
      fetchResource("/sales/customers", []),
      fetchResource("/sales/orders", []),
      fetchResource("/sales/deliveries", []),
      fetchPermissionEmployeeOptions(PERSONNEL_PERMISSION_CODES.INVENTORY_LEDGER),
      fetchResource("/sales/order-items", []),
      fetchResource("/master-data/products", []),
      fetchResource("/inventory/stock-lots?item_type=FINISHED_GOOD", []),
      fetchResource("/returns/orders", []),
      fetchResource("/returns/items", []),
      fetchResource("/returns/dispositions", [])
    ]);
  customers.value = customerRows;
  orders.value = orderRows;
  deliveries.value = deliveryRows;
  employees.value = employeeRows;
  orderItems.value = orderItemRows;
  products.value = productRows;
  finishedLots.value = lotRows;
  returnOrders.value = returnOrderRows;
  returnItems.value = returnItemRows;
  dispositions.value = dispositionRows;
}

async function submitReturnOrder() {
  feedbackMessage.value = "";
  errorMessage.value = "";
  submittingOrder.value = true;
  try {
    const result = await postResource("/returns/orders", {
      customer_id: Number(orderForm.customer_id),
      sales_order_id: orderForm.sales_order_id ? Number(orderForm.sales_order_id) : null,
      delivery_id: orderForm.delivery_id ? Number(orderForm.delivery_id) : null,
      handler_employee_id: orderForm.handler_employee_id ? Number(orderForm.handler_employee_id) : null,
      return_reason: orderForm.return_reason || null,
      items: orderForm.items.map((item) => ({
        sales_order_item_id: item.sales_order_item_id ? Number(item.sales_order_item_id) : null,
        product_item_id: Number(item.product_item_id),
        source_lot_id: item.source_lot_id ? Number(item.source_lot_id) : null,
        return_qty: Number(item.return_qty || 0),
        return_weight_kg: Number(item.return_weight_kg || 0),
        responsibility_type: item.responsibility_type || null
      }))
    });
    feedbackMessage.value = `退货单 ${result.return_no} 已创建`;
    selectedReturnOrderId.value = result.return_order_id;
    returnDrawerOpen.value = false;
    await loadAll();
    resetReturnForm();
  } catch (error) {
    errorMessage.value = error.message || "退货单创建失败";
  } finally {
    submittingOrder.value = false;
  }
}

async function submitDisposition() {
  feedbackMessage.value = "";
  errorMessage.value = "";
  submittingDisposition.value = true;
  try {
    const result = await postResource("/returns/dispositions", {
      return_item_id: Number(dispositionForm.return_item_id),
      disposition_type: dispositionForm.disposition_type,
      scrap_weight_kg: dispositionForm.disposition_type === "SCRAP" ? Number(dispositionForm.scrap_weight_kg || 0) : 0,
      extra_cost_amount: dispositionForm.disposition_type === "REWORK" ? Number(dispositionForm.extra_cost_amount || 0) : 0,
      scrap_sale_amount: dispositionForm.disposition_type === "SCRAP" ? Number(dispositionForm.scrap_sale_amount || 0) : 0,
      remark: dispositionForm.remark || null
    });
    feedbackMessage.value = `退货处置 ${result.disposition_no} 已完成`;
    dispositionDrawerOpen.value = false;
    dispositionRecordsDrawerOpen.value = true;
    await loadAll();
    resetDispositionForm();
  } catch (error) {
    errorMessage.value = error.message || "退货处置失败";
  } finally {
    submittingDisposition.value = false;
  }
}

onMounted(async () => {
  await loadAll();
});
</script>
