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

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

const getPageUrl = "/production/finishedproductshipment/getFinishedProductShipmentPage";
const addUrl = "/production/finishedproductshipment/addFinishedProductShipment";
const editUrl = "/production/finishedproductshipment/updateFinishedProductShipment";
const removeUrl = "/production/finishedproductshipment/deleteFinishedProductShipment";
const approveUrl = "/production/finishedproductshipment/approveFinishedProductShipment";
const rejectUrl = "/production/finishedproductshipment/rejectFinishedProductShipment";
const getDetailUrl = "/production/finishedproductshipment/getFinishedProductShipmentDetail";
const getWarehouseSelectListUrl = "/warehouse/warehouse/getWarehouseSelectList";
const itemArrayName = "shipmentItems";
const searchers = [
  { name: "searchCode", type: "text" as const, placeholder: $t("_prop.production.finishedproductshipment.formCode") },
  { name: "formName", type: "text" as const, placeholder: $t("_prop.production.finishedproductshipment.formName") },
];
const rules = reactive<FormRules>({
  formCode: [
    { required: true, message: $t("_message.production.finishedproductshipment.input_formCode"), trigger: "blur" },
  ],
  formName: [
    { required: true, message: $t("_message.production.finishedproductshipment.input_formName"), trigger: "blur" },
  ],
  storeNo: [
    { required: true, message: $t("_message.production.finishedproductshipment.select_storeId"), trigger: "blur" },
  ],
  outStockType: [
    { required: true, message: $t("_message.production.finishedproductshipment.select_outStockType"), trigger: "blur" },
  ],
  shipmentItems: [
    {
      required: true,
      validator: (rule, value, callback) => {
        if (value === undefined || value.length === 0) {
          callback($t("_message.production.finishedproductshipment.no_shipment_items"));
        }
        callback();
      },
      trigger: "change",
    },
  ],
});

const outStockTypeOptions = [
  { label: $t("_enum.outStockType.material"), value: 1 },
  { label: $t("_enum.outStockType.finishedProduct"), value: 2 },
];

const mappingConfig: FieldMappingConfig = {
  partNumber: {
    sourceKey: "物料编号",
    defaultValue: "",
  },
  productCount: {
    sourceKey: "数量",
    defaultValue: 0,
    transform: (val: any) => {
      const num = Number(val);
      return isNaN(num) ? 0 : num;
    },
  },
  productMark: {
    sourceKey: "备注",
    defaultValue: "",
  },
};

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

/**
 * 根据 formType 获取出库类型标签
 * formType = 4 (WAREHOUSE_ISSUE) -> 物料出库
 * formType = 7 (FINISHED_PRODUCT_SHIPMENT) -> 成品出库
 */
const getOutStockTypeLabelByFormType = (formTypeValue: number) => {
  if (formTypeValue === 4) {
    return outStockTypeOptions.find(opt => opt.value === 1)?.label || "";
  }
  if (formTypeValue === 7) {
    return outStockTypeOptions.find(opt => opt.value === 2)?.label || "";
  }
  return "";
};

/**
 * 可以自定义的变量
 */

const add = () => {
  form.value = {};
  title.value = "_title.production.finishedproductshipment.add";
  visible.value = true;
  formType.value = false;
  // 默认生成成品出库单号
  form.value["formCode"] = generateDucumentNo("CPCK");
};

// 监听出库类型变化，动态生成单号
watch(
  () => form.value?.outStockType,
  newVal => {
    if (newVal === 1) {
      // 物料出库 - 使用 WarehouseIssue (4) 的单号前缀
      form.value["formCode"] = generateDucumentNo("CK");
    } else if (newVal === 2) {
      // 成品出库 - 使用 FinishedProductShipment (7) 的单号前缀
      form.value["formCode"] = generateDucumentNo("CPCK");
    }
  }
);

const edit = (row: any) => {
  title.value = "_title.production.finishedproductshipment.edit";
  form.value = { ...row };
  visible.value = true;
  formType.value = true;
};

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

// 表单状态标签类型映射
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 approve = (row: any) => {
  ElMessageBox.confirm($t("_message.production.finishedproductshipment.approve_confirm"), $t("_level.warning"), {
    confirmButtonText: $t("_button.confirm"),
    cancelButtonText: $t("_button.cancel"),
    type: "warning",
  }).then(async () => {
    try {
      await post(approveUrl, { id: row.id });
      ElMessage.success($t("_message.production.finishedproductshipment.approve_success"));
      tableRef.value?.reload();
    } catch (err: any) {
      ElMessage.error($t("_message.production.finishedproductshipment.approve_fail") + err);
    }
  });
};

const reject = (row: any) => {
  ElMessageBox.confirm($t("_message.production.finishedproductshipment.reject_confirm"), $t("_level.warning"), {
    confirmButtonText: $t("_button.confirm"),
    cancelButtonText: $t("_button.cancel"),
    type: "warning",
  }).then(async () => {
    try {
      await post(rejectUrl, { id: row.id });
      ElMessage.success($t("_message.production.finishedproductshipment.reject_success"));
      tableRef.value?.reload();
    } catch (err: any) {
      ElMessage.error($t("_message.production.finishedproductshipment.reject_fail") + err);
    }
  });
};

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

const submit = (form: any, formRef: FormInstance | undefined) => {
  setName();
  if (formRef !== undefined) {
    formRef.validate(valid => {
      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 "approve":
      approve(row);
      break;
    case "reject":
      reject(row);
      break;
    case "showItem":
      showItem(row);
      break;
  }
};

const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
  // 已审核(formStatus=1)时不显示审核按钮，显示反审按钮
  // 未审核(formStatus=0)时显示审核按钮，不显示反审按钮
  if (row.formStatus === 0 && button.eventName === "reject") return false;
  if (row.formStatus === 1 && button.eventName === "approve") return false;
  // 已审核后不能编辑和删除
  if (row.formStatus === 1 && (button.eventName === "edit" || button.eventName === "remove")) return false;
  return true;
};

const setName = () => {
  form.value["storeName"] = warehouseSelectRef.value?.getLabel();
};

const handleReset = () => {
  form.value["formCode"] = generateDucumentNo("CPCK");
};
</script>
<template>
  <ExpandablePageableTable
    :url="getPageUrl"
    :searchers="searchers"
    ref="tableRef"
    :item-url="getDetailUrl"
    item-id-key="id"
    item-id-name="id"
    itemFieldName="shipmentItems"
  >
    <template #tool-button>
      <DefaultToolButton @top-button-click="topButtonClick" />
    </template>
    <template #columns>
      <el-table-column :label="$t('_prop.production.finishedproductshipment.formCode')" prop="formCode" />
      <el-table-column :label="$t('_prop.production.finishedproductshipment.storeName')" prop="storeName" />
      <el-table-column :label="$t('_prop.production.finishedproductshipment.formName')" prop="formName" />
      <el-table-column :label="$t('_prop.production.finishedproductshipment.outStockType')" prop="formType">
        <template #default="{ row }">
          {{ getOutStockTypeLabelByFormType(row.formType) }}
        </template>
      </el-table-column>
      <el-table-column :label="$t('_prop.production.finishedproductshipment.formMark')" prop="formMark" />
      <el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
      <DefaultStatusSwitchColumn
        status-param-name="formStatus"
        :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.production.finishedproductshipment.partNumber')"
          prop="partNumber"
          width="150"
        />
        <el-table-column
          :label="$t('_prop.production.finishedproductshipment.productSpecs')"
          prop="productSpecs"
          width="200"
        />
        <el-table-column :label="$t('_prop.production.finishedproductshipment.productCount')" prop="productCount" />
        <el-table-column :label="$t('_prop.production.finishedproductshipment.productMark')" prop="productMark" />
      </el-table>
    </template>
  </ExpandablePageableTable>
  <BaseFormWithTable
    v-model:visible="visible"
    @submit="submit"
    v-model:form="form"
    :title="$t(title)"
    :rules="rules"
    :base-title="$t('_title.production.finishedproductshipment.baseTitle')"
    :table-title="$t('_title.production.finishedproductshipment.tableTitle')"
    :item-array-name="itemArrayName"
    upload-desc="物料信息"
    :mapping-config="mappingConfig"
    @reset="handleReset"
  >
    <template #form-items>
      <el-form-item prop="id" v-if="false"><el-input v-model="form.id" /></el-form-item>
      <el-form-item prop="storeName" v-if="false"><el-input v-model="form.storeName" /></el-form-item>

      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item :label="$t('_prop.production.finishedproductshipment.formCode')" prop="formCode">
            <el-input
              v-model="form.formCode"
              :placeholder="$t('_message.production.finishedproductshipment.input_formCode')"
              disabled
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item :label="$t('_prop.production.finishedproductshipment.formName')" prop="formName">
            <el-input
              v-model="form.formName"
              :placeholder="$t('_message.production.finishedproductshipment.input_formName')"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item :label="$t('_prop.production.finishedproductshipment.storeNo')" prop="storeNo">
            <BaseSelect v-model="form.storeNo" :url="getWarehouseSelectListUrl" ref="warehouseSelectRef" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item :label="$t('_prop.production.finishedproductshipment.outStockType')" prop="outStockType">
            <el-select
              v-model="form.outStockType"
              :placeholder="$t('_message.production.finishedproductshipment.select_outStockType')"
            >
              <el-option
                v-for="item in outStockTypeOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item :label="$t('_prop.production.finishedproductshipment.formMark')" prop="formMark">
        <el-input
          v-model="form.formMark"
          :placeholder="$t('_message.production.finishedproductshipment.input_formMark')"
          type="textarea"
          autosize
        />
      </el-form-item>
    </template>
    <template #form-table-columns>
      <el-table-column :label="$t('_prop.production.finishedproductshipment.partNumber')" width="150">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${itemArrayName}.${$index}.partNumber`">
            <el-input
              v-model="row.partNumber"
              size="small"
              :placeholder="$t('_message.production.finishedproductshipment.input_partNumber')"
            />
          </el-form-item>
        </template>
      </el-table-column>

      <el-table-column :label="$t('_prop.production.finishedproductshipment.productSpecs')" width="200">
        <template #default="{ row }">
          <span>{{ row.productSpecs }}</span>
        </template>
      </el-table-column>

      <el-table-column :label="$t('_prop.production.finishedproductshipment.productCount')" width="150">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${itemArrayName}.${$index}.productCount`">
            <el-input-number v-model="row.productCount" size="small" :min="1" />
          </el-form-item>
        </template>
      </el-table-column>

      <el-table-column :label="$t('_prop.production.finishedproductshipment.productMark')" width="200">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${itemArrayName}.${$index}.productMark`">
            <el-input
              v-model="row.productMark"
              size="small"
              :placeholder="$t('_message.production.finishedproductshipment.input_productMark')"
            />
          </el-form-item>
        </template>
      </el-table-column>
    </template>
  </BaseFormWithTable>
  <BaseItemDialog
    :title="$t('_title.production.finishedproductshipment.showItem')"
    v-model:visible="itemVisible"
    :url="getDetailUrl"
    parent-param-name="id"
    v-model:parent-param-value="itemParentId"
  >
    <template #columns>
      <el-table-column
        :label="$t('_prop.production.finishedproductshipment.partNumber')"
        prop="partNumber"
        width="150"
      />
      <el-table-column
        :label="$t('_prop.production.finishedproductshipment.productSpecs')"
        prop="productSpecs"
        width="200"
      />
      <el-table-column :label="$t('_prop.production.finishedproductshipment.productCount')" prop="productCount" />
      <el-table-column :label="$t('_prop.production.finishedproductshipment.productMark')" prop="productMark" />
    </template>
  </BaseItemDialog>
</template>
