<script lang="ts" setup>
import DefaultToolButton from "@/components/base/default-tool-button/DefaultToolButton.vue";
import DefaultOperateButtonColumn from "@/components/base/default-column/DefaultOperateButtonColumn.vue";
import { usePage } from "@/composables/use-page";
import { $t } from "@/common/languages";
import type { FormInstance, FormItemRule, FormRules } from "element-plus";
import { formatDate } from "@/common/utils/format-utils";
import ExpandablePageableTable from "@/components/base/expandable-pageable-table/ExpandablePageableTable.vue";
import BaseFormWithTable from "@/components/base/base-form-with-table/BaseFormWithTable.vue";
import { get, post } from "@/common/http/request";
import { ElMessage } from "element-plus";
import { type FieldMappingConfig } from "@/components/base/base-form-with-table/type";
import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultStatusSwitchColumn.vue";
import { useStatus } from "@/common/languages/mapping/base-info-mapping";
import { generateDucumentNo } from "@/common/utils/document-no-generator/document-no-generator";
import { DocumentType } from "@/common/enums/DocumentType";
import BaseItemDialog from "@/components/base/base-item-dialog/BaseItemDialog.vue";

/**
 * 必须要的变量
 */

const getPageUrl = "/warehouse/stocktransferorder/getStockTransferOrderPage";
const getItemUrl = "/warehouse/stocktransferorder/getStockTransferOrderItem";
const addUrl = "/warehouse/stocktransferorder/addStockTransferOrder";
const editUrl = "/warehouse/stocktransferorder/updateStockTransferOrder";
const removeUrl = "/warehouse/stocktransferorder/deleteStockTransferOrder";
const approveUrl = "/warehouse/stocktransferorder/approveStockTransferOrder";
const rejectUrl = "/warehouse/stocktransferorder/rejectStockTransferOrder";
const warehouseSelectUrl = "/warehouse/warehouse/getWarehouseSelectList";
const partNumberExistsUrl = "/warehouse/warehouseitem/existsWarehouseItem";
const checkStockUrl = "/warehouse/stock/checkStock";
const searchers = [
  { name: "searchCode", type: "text" as const, placeholder: $t("_prop.warehouse.stocktransferorder.searchCode") },
  { name: "partNumber", type: "text" as const, placeholder: $t("_prop.warehouse.stocktransferorder.partNumber") },
];
const rules = reactive<FormRules>({
  formCode: [{ required: true, message: $t("_message.warehouse.stocktransferorder.input_formCode"), trigger: "blur" }],
  formName: [{ required: true, message: $t("_message.warehouse.stocktransferorder.input_formName"), trigger: "blur" }],
  formMark: [{ required: false, message: $t("_message.warehouse.stocktransferorder.input_formMark"), trigger: "blur" }],
  storeNo: [{ required: true, message: $t("_message.warehouse.stocktransferorder.select_storeId"), trigger: "change" }],
  outStoreNo: [
    { required: true, message: $t("_message.warehouse.stocktransferorder.select_outStoreId"), trigger: "change" },
    {
      validator: (rule: any, value: any, callback: any) => {
        if (form.value.storeNo && form.value.outStoreNo && form.value.storeNo === form.value.outStoreNo) {
          callback($t("_message.warehouse.stocktransferorder.same_warehouse"));
        }
        callback();
      },
      trigger: "change",
    },
  ],
  partNumber: [
    {
      required: true,
      validator: (rule, value, callback) => {
        if (!value) {
          callback($t("_message.warehouse.stocktransferorder.input_partNumber"));
        }
        (async () => {
          try {
            const isExists = await get(partNumberExistsUrl, { partNumber: value }).then(res => res.data);
            if (isExists) {
              callback();
            }
            callback($t("_message.warehouse.stocktransferorder.not_exist_partNumber"));
          } catch (err: any) {
            callback(new Error(err));
          }
        })();
      },
      trigger: "blur",
    },
  ],
  productCount: [
    {
      required: true,
      message: $t("_message.warehouse.stocktransferorder.input_productCount"),
      trigger: "blur",
    },
    {
      type: "number",
      min: 1,
      message: $t("_message.warehouse.stocktransferorder.productCount_min_1"),
      trigger: "blur",
    },
  ],
  transferOrderItems: [
    {
      required: true,
      validator: (rule, value, callback) => {
        if (value === undefined || value.length === 0) {
          callback($t("_message.warehouse.stocktransferorder.no_materials"));
        }
        callback();
      },
      trigger: "change",
    },
  ],
  stockCheck: [
    {
      validator: (rule, value, callback) => {
        const items = form.value.transferOrderItems || [];
        const partCountMap: Record<string, number> = {};
        items.forEach((item: any) => {
          if (item.partNumber) {
            partCountMap[item.partNumber] = (partCountMap[item.partNumber] || 0) + (item.productCount || 0);
          }
        });
        const stockCheckItems = Object.keys(partCountMap).map(partNumber => ({
          partNumber,
          requiredCount: partCountMap[partNumber],
        }));
        post(checkStockUrl, { storeNo: form.value.outStoreNo, items: stockCheckItems })
          .then(() => {
            callback();
          })
          .catch((err: any) => {
            callback(new Error(err));
          });
      },
      trigger: "submit",
    },
  ],
});
const itemArrayName = "transferOrderItems";

const mappingConfig: FieldMappingConfig = {
  partNumber: {
    sourceKey: "物料编号",
    defaultValue: "",
  },

  productCount: {
    sourceKey: "调拨数量",
    defaultValue: 0,
    transform: (val: any) => {
      const num = Number(val);
      return isNaN(num) ? 0 : num;
    },
  },
};

const validateProductCount = (index: number) => {
  return [
    {
      required: true,
      validator: (rule: any, value: any, callback: any) => {
        if (!value) {
          callback($t("_message.warehouse.stocktransferorder.input_productCount"));
        }
        if (value < 1) {
          callback($t("_message.warehouse.stocktransferorder.productCount_min_1"));
        }
        callback();
      },
      trigger: "blur",
    },
  ];
};

/**
 * 基本不变通用变量
 */
const tableRef = ref<InstanceType<typeof ExpandablePageableTable> | null>(null);
const { useAdd, useEdit, useRemove, useGeneralPageRef, useApprove, useReject } = usePage(tableRef);
const { title, visible, formType, form, itemVisible, itemParentId } = useGeneralPageRef();
const { getFormStatusLabel } = useStatus();

// 表单状态标签类型映射
const getFormStatusTagType = (code: number | null): string => {
  const tagTypeMap: Record<number, string> = {
    0: "info", // 未审核
    1: "success", // 已审核
    2: "danger", // 已驳回
    3: "warning", // 未完成
    4: "success", // 已完成
    5: "primary", // 入库中
    6: "info", // 已导入
    7: "warning", // 审核中
    8: "danger", // 已退回
  };
  return tagTypeMap[code ?? -1] || "info";
};

const baseFormWithTableRef = ref<InstanceType<typeof BaseFormWithTable>>();

const warehouseOptions = ref<Array<{ label: string; value: number }>>([]);

const loadWarehouseOptions = async () => {
  try {
    const res = await get(warehouseSelectUrl).then(res => res.data);
    warehouseOptions.value = res.map((item: any) => ({
      label: item.label,
      value: item.value,
    }));
  } catch (err) {
    console.error("Failed to load warehouse options:", err);
  }
};

onMounted(() => {
  loadWarehouseOptions();
});

const add = () => {
  form.value = {};
  title.value = "_title.warehouse.stocktransferorder.add";
  form.value["formCode"] = generateDucumentNo(DocumentType.StockTransferOrder);
  visible.value = true;
  formType.value = false;
};

const edit = (row: any) => {
  title.value = "_title.warehouse.stocktransferorder.edit";
  form.value = {
    ...row,
    transferOrderItems: [],
  };
  visible.value = true;
  formType.value = true;

  get(getItemUrl, { orderId: row.id })
    .then(res => {
      form.value.transferOrderItems = res.data || [];
    })
    .catch(err => {
      console.error("Failed to load transfer order items:", err);
    });
};

const remove = (row: any) => {
  useRemove(removeUrl, row.id, "_message.warehouse.stocktransferorder.delete_message");
};

const showItem = (row: any) => {
  itemParentId.value = row.id;
  itemVisible.value = true;
};

const approve = (row: any) => {
  useApprove(approveUrl, row.id, "_message.warehouse.stocktransferorder.approve_confirm");
};

const reject = (row: any) => {
  useReject(rejectUrl, row.id, "_message.warehouse.stocktransferorder.reject_confirm");
};

const submit = (form: any, formRef: FormInstance | undefined) => {
  const targetRef = formRef || (baseFormWithTableRef.value as any)?.baseFormRef;

  if (targetRef !== undefined) {
    targetRef.validate((valid: any) => {
      if (valid) {
        if (formType.value) {
          useEdit(editUrl, form, visible);
        } else {
          useAdd(addUrl, form, visible);
        }
      }
    });
  }
};

const topButtonClick = (eventName: string) => {
  switch (eventName) {
    case "add":
      add();
      break;
  }
};

const operateButtonClick = (eventName: string, row: any) => {
  switch (eventName) {
    case "edit":
      edit(row);
      break;
    case "remove":
      remove(row);
      break;
    case "showItem":
      showItem(row);
      break;
    case "approve":
      approve(row);
      break;
    case "reject":
      reject(row);
      break;
  }
};

const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
  if (row.status === 0 && button.eventName === "reject") return false;
  if (row.status === 1 && button.eventName === "approve") return false;
  return true;
};
</script>
<template>
  <ExpandablePageableTable
    :url="getPageUrl"
    :searchers="searchers"
    ref="tableRef"
    :item-url="getItemUrl"
    item-id-key="id"
    item-id-name="orderId"
    itemFieldName="orderItems"
  >
    <template #tool-button>
      <DefaultToolButton @top-button-click="topButtonClick" />
    </template>
    <template #columns>
      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.formCode')" prop="formCode" />
      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.formName')" prop="formName" />
      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.storeName')" prop="storeName" />
      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.outStoreName')" prop="outStoreName" />
      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.formMark')" prop="formMark" />
      <el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
      <DefaultStatusSwitchColumn
        status-param-name="status"
        :status-label-mapping="getFormStatusLabel"
        :tag-type-mapping="getFormStatusTagType"
      />
      <DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
    </template>
    <template #item-content="{ itemData }">
      <el-table :data="itemData" size="small" border stripe>
        <el-table-column :label="$t('_prop.warehouse.stocktransferorder.partNumber')" prop="partNumber" width="150" />
        <el-table-column
          :label="$t('_prop.warehouse.stocktransferorder.productSpecs')"
          prop="productSpecs"
          width="200"
        />
        <el-table-column
          :label="$t('_prop.warehouse.stocktransferorder.productCount')"
          prop="productCount"
          width="200"
        />
        <el-table-column :label="$t('_prop.warehouse.stocktransferorder.demandCount')" prop="demandCount" width="200" />
      </el-table>
    </template>
  </ExpandablePageableTable>
  <BaseFormWithTable
    ref="baseFormWithTableRef"
    v-model:visible="visible"
    @submit="submit"
    v-model:form="form"
    :title="$t(title)"
    :rules="rules"
    :base-title="$t('_title.warehouse.stocktransferorder.baseTitle')"
    :table-title="$t('_title.warehouse.stocktransferorder.tableTitle')"
    item-array-name="transferOrderItems"
    :mapping-config="mappingConfig"
    :template-file-name="$t('_title.warehouse.stocktransferorder.templateFileName')"
  >
    <template #form-items>
      <el-form-item prop="id" v-if="false"><el-input v-model="form.id" /></el-form-item>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item :label="$t('_prop.warehouse.stocktransferorder.storeId')" prop="storeNo">
            <el-select
              v-model="form.storeNo"
              :placeholder="$t('_message.warehouse.stocktransferorder.select_storeId')"
              filterable
              style="width: 100%"
            >
              <el-option v-for="item in warehouseOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item :label="$t('_prop.warehouse.stocktransferorder.outStoreId')" prop="outStoreNo">
            <el-select
              v-model="form.outStoreNo"
              :placeholder="$t('_message.warehouse.stocktransferorder.select_outStoreId')"
              filterable
              style="width: 100%"
            >
              <el-option v-for="item in warehouseOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item :label="$t('_prop.warehouse.stocktransferorder.formCode')" prop="formCode">
            <el-input
              v-model="form.formCode"
              :placeholder="$t('_message.warehouse.stocktransferorder.input_formCode')"
              :disabled="true"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item :label="$t('_prop.warehouse.stocktransferorder.formName')" prop="formName">
            <el-input
              v-model="form.formName"
              :placeholder="$t('_message.warehouse.stocktransferorder.input_formName')"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item :label="$t('_prop.warehouse.stocktransferorder.formMark')" prop="formMark">
        <el-input
          v-model="form.formMark"
          :placeholder="$t('_message.warehouse.stocktransferorder.input_formMark')"
          type="textarea"
          autosize
        />
      </el-form-item>
    </template>
    <template #form-table-columns>
      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.partNumber')" width="150">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${itemArrayName}.${$index}.partNumber`" :rules="rules.partNumber">
            <el-input v-model="row.partNumber" size="small" />
          </el-form-item>
        </template>
      </el-table-column>

      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.productCount')" width="150">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${itemArrayName}.${$index}.productCount`" :rules="validateProductCount($index)">
            <el-input-number v-model="row.productCount" size="small" :min="1" />
          </el-form-item>
        </template>
      </el-table-column>
    </template>
  </BaseFormWithTable>
  <BaseItemDialog
    :title="$t('_title.warehouse.stocktransferorder.showItem')"
    v-model:visible="itemVisible"
    :url="getItemUrl"
    parent-param-name="orderId"
    v-model:parent-param-value="itemParentId"
  >
    <template #columns>
      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.partNumber')" prop="partNumber" width="150" />
      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.productSpecs')" prop="productSpecs" width="200" />
      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.productCount')" prop="productCount" width="200" />
      <el-table-column :label="$t('_prop.warehouse.stocktransferorder.demandCount')" prop="demandCount" width="200" />
    </template>
  </BaseItemDialog>
</template>
