<script lang="ts" setup>
import BasePageableTable from "@/components/base/base-pageable-table/BasePageableTable.vue";
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 BaseForm from "@/components/base/base-form/BaseForm.vue";
import { $t } from "@/common/languages";
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
import { formatDate } from "@/common/utils/format-utils";
import { get, post } from "@/common/http/request";
import BaseTableForm from "@/components/base/base-table-form/BaseTableForm.vue";
import QrCodeDialog from "@/components/base/base-qrcode/QrCodeDialog.vue";
import { Delete, Edit, Plus } from "@element-plus/icons-vue";

const getPageUrl = "/warehouse/warehouseitem/getWarehouseItemPage";
const addUrl = "/warehouse/warehouseitem/addWarehouseItem";
const editUrl = "/warehouse/warehouseitem/updateWarehouseItem";
const removeUrl = "/warehouse/warehouseitem/deleteWarehouseItem";
const getPartNumberUrl = "/warehouse/warehouseitem/getPartNumberForQrCode";
const getVendorListUrl = "/warehouse/warehouseitem/getVendorList";
const saveVendorListUrl = "/warehouse/warehouseitem/saveVendorList";
const getVendorSelectListUrl = "/sys/vendor/getVendorList";

const searchers = [
  { name: "searchCode", type: "text" as const, placeholder: $t("_prop.warehouse.warehouse_item.partNumber") },
];

const rules = reactive<FormRules>({
  partNumber: [{ required: true, message: $t("_message.warehouse.warehouse_item.input_partNumber"), trigger: "blur" }],
  productType: [
    { required: true, message: $t("_message.warehouse.warehouse_item.input_productType"), trigger: "blur" },
  ],
  productSpecs: [
    { required: true, message: $t("_message.warehouse.warehouse_item.input_productSpecs"), trigger: "blur" },
  ],
});

const tableRef = ref<InstanceType<typeof BasePageableTable> | null>(null);
const { useAdd, useEdit, useRemove, useGeneralPageRef } = usePage(tableRef);
const { title, visible, formType, form } = useGeneralPageRef();

const vendorDialogVisible = ref(false);
const vendorDialogTitle = ref("");
const currentWarehouseItemId = ref<number>();
const dialogTableData = ref([] as any[]);
const allVendors = ref([] as any[]);
const vendorFormRef = ref<FormInstance>();
const vendorFormRules = reactive<FormRules>({
  vendorId: [
    { required: true, message: () => $t("_message.warehouse.warehouse_item.select_vendor"), trigger: "change" },
    {
      validator: (rule: any, value: any, callback: any) => {
        if (!value) {
          callback();
          return;
        }
        const duplicateCount = dialogTableData.value.filter((item: any) => item.vendorId === value).length;
        if (duplicateCount > 1) {
          callback(new Error($t("_message.warehouse.warehouse_item.vendor_duplicate")));
        } else {
          callback();
        }
      },
      trigger: "change",
    },
  ],
  costPrice: [
    { required: true, message: () => $t("_message.warehouse.warehouse_item.input_costPrice"), trigger: "blur" },
    { type: "number", min: 0, message: () => $t("_message.warehouse.warehouse_item.input_costPrice"), trigger: "blur" },
  ],
});

const qrCodeDialogVisible = ref(false);
const qrCodeContent = ref("");
const qrCodeLabel = ref("");

const add = () => {
  form.value = {};
  title.value = "_title.warehouse.warehouseitem.add";
  visible.value = true;
  formType.value = false;
};

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

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

const editVendors = async (row: any) => {
  currentWarehouseItemId.value = row.id;
  vendorDialogTitle.value = $t("_title.warehouse.warehouseitem.vendorList");
  vendorDialogVisible.value = true;

  try {
    const [vendorListResponse, allVendorResponse] = await Promise.all([
      get(getVendorListUrl, { warehouseItemId: row.id }),
      get(getVendorSelectListUrl),
    ]);

    dialogTableData.value = vendorListResponse.data || [];
    allVendors.value = allVendorResponse.data || [];
  } catch (error) {
    console.error("Load vendor list failed:", error);
  }
};

const printQrCode = async (row: any) => {
  try {
    const partNumber = await get(getPartNumberUrl, { warehouseItemId: row.id }).then(res => res.data);
    qrCodeContent.value = partNumber;
    qrCodeLabel.value = partNumber;
    qrCodeDialogVisible.value = true;
  } catch (error) {
    console.error("Get part number failed:", error);
  }
};

const submit = (form: any, formRef: FormInstance | undefined) => {
  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 "editVendors":
      editVendors(row);
      break;
    case "printQrCode":
      printQrCode(row);
      break;
  }
};

const saveVendorList = async () => {
  if (!vendorFormRef.value) return;

  try {
    await vendorFormRef.value.validate();
  } catch (error) {
    console.error("Validation failed:", error);
    return;
  }

  const validVendors = dialogTableData.value.filter(v => v.vendorId !== null && v.vendorId !== undefined);

  if (validVendors.length === 0) {
    return;
  }

  const vendorList = validVendors.map(v => ({
    vendorId: v.vendorId,
    costPrice: v.costPrice,
  }));

  await post(saveVendorListUrl, {
    warehouseItemId: currentWarehouseItemId.value,
    vendorList,
  })
    .then(res => {
      if (res.code === 0) {
        ElMessage.info($t("_message.warehouse.warehouse_item.save_vendors_success"));
        vendorDialogVisible.value = false;
        tableRef.value?.reload();
      } else {
        ElMessage.error($t("_message.warehouse.warehouse_item.save_vendors_success") + res.msg);
      }
    })
    .catch(err => {
      ElMessage.error($t("_message.warehouse.warehouse_item.save_vendors_success") + err);
    });
};

const addVendorRow = () => {
  dialogTableData.value.push({
    id: null,
    vendorId: null,
    vendorName: "",
    costPrice: null,
    procureDate: null,
    isEditing: true,
  });
};

const editVendorRow = (row: any) => {
  row.isEditing = true;
};

const deleteVendorRow = (index: number) => {
  dialogTableData.value.splice(index, 1);
};

const saveVendorRow = async (row: any) => {
  if (!vendorFormRef.value) return;

  const rowIndex = dialogTableData.value.indexOf(row);
  if (rowIndex === -1) return;

  try {
    await vendorFormRef.value.validateField(`dialogTableData[${rowIndex}].vendorId`);
    await vendorFormRef.value.validateField(`dialogTableData[${rowIndex}].costPrice`);
    row.isEditing = false;
  } catch (error) {
    console.error("Validation failed:", error);
  }
};

const cancelVendorEdit = (row: any, originalRow: any) => {
  row.vendorId = originalRow.vendorId;
  row.costPrice = originalRow.costPrice;
  row.procureDate = originalRow.procureDate;
  row.isEditing = false;
};
</script>

<template>
  <BasePageableTable :url="getPageUrl" :searchers="searchers" ref="tableRef">
    <template #tool-button>
      <DefaultToolButton @top-button-click="topButtonClick" />
    </template>
    <template #columns>
      <el-table-column :label="$t('_prop.warehouse.warehouse_item.partNumber')" prop="partNumber" width="150" />
      <el-table-column :label="$t('_prop.warehouse.warehouse_item.productType')" prop="productType" />
      <el-table-column :label="$t('_prop.warehouse.warehouse_item.productSpecs')" prop="productSpecs" width="150" />
      <el-table-column :label="$t('_prop.warehouse.warehouse_item.productBrand')" prop="productBrand" />
      <el-table-column :label="$t('_prop.warehouse.warehouse_item.productPacking')" prop="productPacking" />
      <el-table-column :label="$t('_prop.warehouse.warehouse_item.productPackSize')" prop="productPackSize" />
      <el-table-column :label="$t('_prop.warehouse.warehouse_item.productPrice')" prop="productPrice" />
      <el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
      <el-table-column :label="$t('_prop.warehouse.warehouse_item.createUserName')" prop="createUserName" />
      <DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
    </template>
  </BasePageableTable>
  <BaseForm v-model:visible="visible" @submit="submit" v-model:form="form" :title="$t(title)" :rules="rules">
    <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.warehouse_item.partNumber')" prop="partNumber">
            <el-input
              v-model="form.partNumber"
              :placeholder="$t('_message.warehouse.warehouse_item.input_partNumber')"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item :label="$t('_prop.warehouse.warehouse_item.productSpecs')" prop="productSpecs">
            <el-input
              v-model="form.productSpecs"
              :placeholder="$t('_message.warehouse.warehouse_item.input_productSpecs')"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item :label="$t('_prop.warehouse.warehouse_item.productType')" prop="productType">
            <el-input
              v-model="form.productType"
              :placeholder="$t('_message.warehouse.warehouse_item.input_productType')"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item :label="$t('_prop.warehouse.warehouse_item.productBrand')" prop="productBrand">
            <el-input
              v-model="form.productBrand"
              :placeholder="$t('_message.warehouse.warehouse_item.input_productBrand')"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item :label="$t('_prop.warehouse.warehouse_item.productPacking')" prop="productPacking">
            <el-input-number
              v-model="form.productPacking"
              :min="1"
              :placeholder="$t('_message.warehouse.warehouse_item.input_productPacking')"
              style="width: 100%"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item :label="$t('_prop.warehouse.warehouse_item.productPackSize')" prop="productPackSize">
            <el-input
              v-model="form.productPackSize"
              :placeholder="$t('_message.warehouse.warehouse_item.input_productPackSize')"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item :label="$t('_prop.warehouse.warehouse_item.productMark')" prop="productMark">
        <el-input
          v-model="form.productMark"
          type="textarea"
          :rows="2"
          :placeholder="$t('_message.warehouse.warehouse_item.input_productMark')"
        />
      </el-form-item>
    </template>
  </BaseForm>
  <el-dialog v-model="vendorDialogVisible" :title="vendorDialogTitle" width="80%" :close-on-click-modal="false">
    <el-form ref="vendorFormRef" :model="{ dialogTableData }" :rules="vendorFormRules">
      <el-table :data="dialogTableData" border stripe style="width: 100%" max-height="50vh">
        <el-table-column :label="$t('_prop.warehouse.warehouse_item.vendorName')" width="250" show-overflow-tooltip>
          <template #default="{ row, $index }">
            <el-form-item
              v-if="row.isEditing"
              :prop="`dialogTableData[${$index}].vendorId`"
              :rules="vendorFormRules.vendorId"
            >
              <el-select
                v-model="row.vendorId"
                :placeholder="$t('_message.warehouse.warehouse_item.select_vendor')"
                filterable
                style="width: 100%"
                @change="
                  value => {
                    const vendor = allVendors.find(v => v.value === value);
                    if (vendor) {
                      row.vendorName = vendor.label;
                    }
                  }
                "
              >
                <el-option
                  v-for="vendor in allVendors"
                  :key="vendor.value"
                  :label="vendor.label"
                  :value="vendor.value"
                />
              </el-select>
            </el-form-item>
            <span v-else>{{ row.vendorName }}</span>
          </template>
        </el-table-column>

        <el-table-column :label="$t('_prop.warehouse.warehouse_item.costPrice')" width="150">
          <template #default="{ row, $index }">
            <el-form-item
              v-if="row.isEditing"
              :prop="`dialogTableData[${$index}].costPrice`"
              :rules="vendorFormRules.costPrice"
            >
              <el-input-number
                v-model="row.costPrice"
                :min="0"
                :precision="2"
                :placeholder="$t('_message.warehouse.warehouse_item.input_costPrice')"
                style="width: 100%"
              />
            </el-form-item>
            <span v-else>{{ row.costPrice }}</span>
          </template>
        </el-table-column>

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

        <el-table-column :label="$t('_prop.common.operate')" width="150" align="center">
          <template #default="{ row, $index }">
            <template v-if="row.isEditing">
              <el-button type="primary" link size="small" @click="saveVendorRow(row)">
                {{ $t("_button.confirm") }}
              </el-button>
              <el-button link size="small" @click="cancelVendorEdit(row, { ...row })">
                {{ $t("_button.cancel") }}
              </el-button>
            </template>
            <template v-else>
              <el-button type="primary" link size="small" @click="editVendorRow(row)">
                <el-icon><Edit /></el-icon>
              </el-button>
              <el-button type="danger" link size="small" @click="deleteVendorRow($index)">
                <el-icon><Delete /></el-icon>
              </el-button>
            </template>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="addVendorRow">
          <el-icon><Plus /></el-icon>
          {{ $t("_button.add") }}
        </el-button>
        <el-button type="success" @click="saveVendorList">
          <el-icon><Edit /></el-icon>
          {{ $t("_button.save") }}
        </el-button>
        <el-button @click="vendorDialogVisible = false">
          {{ $t("_button.cancel") }}
        </el-button>
      </div>
    </template>
  </el-dialog>
  <QrCodeDialog
    v-model:visible="qrCodeDialogVisible"
    :title="$t('_title.warehouse.warehouseitem.printQrCode')"
    :qr-code-content="qrCodeContent"
    :label="qrCodeLabel"
  />
</template>
