<template>
  <ElDialog
    v-model="visible"
    :title="
      editOrderType === 'add'
        ? '新增备货单'
        : editOrderType === 'edit'
        ? '编辑备货单'
        : '审核备货单'
    "
    width="1400px"
    top="15vh"
    :close-on-click-modal="false"
    destroy-on-close
  >
    <div class="add-stocking-order">
      <div class="form-section">
        <ElForm
          ref="formRef"
          :model="formData"
          :rules="formRules"
          label-width="100px"
          inline
        >
          <div class="form-row">
            <ElFormItem label="备货单号" class="form-item">
              <ElInput
                v-model="formData.stockingUpManageNo"
                disabled
                placeholder="系统自动生成"
                style="width: 100%"
              />
            </ElFormItem>
            <ElFormItem label="供应商" prop="supplierId" class="form-item">
              <ElSelect
                v-model="formData.supplierId"
                placeholder="请选择"
                filterable
                clearable
                :disabled="editOrderType === 'audit'"
                style="width: 100%"
                @change="handleSupplierChange"
              >
                <ElOption
                  v-for="item in supplierList"
                  :key="item.id"
                  :label="item.supplierName"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem
              label="备货员"
              prop="stockingUpUserId"
              class="form-item"
            >
              <ElSelect
                v-model="formData.stockingUpUserId"
                placeholder="请选择"
                filterable
                :disabled="editOrderType === 'audit'"
                clearable
                style="width: 100%"
              >
                <ElOption
                  v-for="item in stockKeeperList"
                  :key="item.id"
                  :label="item.account"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="备货仓库" prop="warehouseId" class="form-item">
              <ElSelect
                v-model="formData.warehouseId"
                placeholder="请选择"
                filterable
                :disabled="editOrderType === 'audit'"
                clearable
                style="width: 100%"
              >
                <ElOption
                  v-for="item in warehouseList"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
          </div>
          <div class="form-row">
            <ElFormItem label="期望交货日期" class="form-item">
              <ElDatePicker
                v-model="formData.expectDeliveryTime"
                type="datetime"
                placeholder="请选择"
                value-format="YYYY-MM-DD HH:mm:ss"
                clearable
                style="width: 100%"
              />
            </ElFormItem>
            <ElFormItem label="备货总额" class="form-item">
              <ElInput
                v-model="totalAmount"
                disabled
                placeholder="0"
                style="width: 100%"
              />
            </ElFormItem>
            <ElFormItem label="币种" class="form-item">
              <ElSelect
                v-model="formData.currencyCode"
                placeholder="请选择"
                filterable
                clearable
                disabled
                style="width: 100%"
              >
                <ElOption
                  v-for="item in currencyList"
                  :key="item.id"
                  :label="`${item.currencyName}(${item.currencyCode})`"
                  :value="item.currencyCode"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="备注" class="form-item">
              <ElInput
                v-model="formData.remark"
                placeholder="请输入备注"
                clearable
                style="width: 100%"
              />
            </ElFormItem>
          </div>
        </ElForm>
      </div>
      <div class="table-section">
        <TableView
          :paginated-data="formData.detailsList"
          :serial-numberable="true"
          :columns="tableColumns"
          :selectionable="true"
          @selection-change="handleSelectionChange"
        >
          <template #buyAmount="{ row }">
            <ElInput
              v-model="row.buyAmount"
              clearable
              :disabled="editOrderType === 'audit'"
              size="small"
              style="width: 80px"
              @blur="validateField(row, 'buyAmount')"
            />
            <div v-if="row._buyAmountError" class="field-error">
              {{ row._buyAmountError }}
            </div>
          </template>
          <template #price="{ row }">
            <ElInput
              v-model="row.price"
              clearable
              :disabled="editOrderType === 'audit'"
              size="small"
              style="width: 80px"
              :class="{ 'is-error': row._priceError }"
              @blur="validateField(row, 'price')"
            />
            <div v-if="row._priceError" class="field-error">
              {{ row._priceError }}
            </div>
          </template>
        </TableView>
      </div>

      <div
        v-if="editOrderType === 'add' || editOrderType === 'edit'"
        class="add-sku-section"
      >
        <span class="label">添加SKU</span>
        <ElInput
          v-model="productSku"
          placeholder="商品父SKU"
          clearable
          style="width: 200px"
          @keyup.enter="handleSearchSku"
        />
        <ElPopover
          ref="popoverRef"
          v-model:visible="popoverVisible"
          placement="top-start"
          :width="900"
          trigger="manual"
          popper-class="sku-search-popover"
        >
          <template #reference>
            <ElButton type="primary" @click="handleSearchSku">查询</ElButton>
          </template>

          <div class="popover-table">
            <TableView
              ref="searchTableRef"
              :paginated-data="productList"
              :columns="searchTableColumns"
              :serial-numberable="true"
            >
              <template #operation="{ row }">
                <ElButton
                  type="success"
                  circle
                  size="small"
                  @click="handleAddSingleProduct(row)"
                >
                  <ElIcon><Plus /></ElIcon>
                </ElButton>
              </template>
            </TableView>
          </div>
        </ElPopover>
        <ElButton type="danger" @click="handleDeleteSelected">删除</ElButton>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <ElButton size="large" @click="handleCancel">取消</ElButton>
        <ElButton
          v-if="editOrderType === 'add' || editOrderType === 'edit'"
          size="large"
          type="primary"
          @click="handleSave(false)"
          >保存</ElButton
        >
        <ElButton
          v-if="editOrderType === 'add' || editOrderType === 'edit'"
          size="large"
          type="success"
          @click="handleSaveAndSubmit"
        >
          保存并提交审核
        </ElButton>
        <ElButton
          v-if="editOrderType === 'audit'"
          size="large"
          type="success"
          @click="handleSave(false)"
          >审核通过</ElButton
        >
        <ElButton
          v-if="editOrderType === 'audit'"
          size="large"
          type="danger"
          @click="handleReject"
          >审核驳回</ElButton
        >
      </div>
    </template>
  </ElDialog>
</template>

<script setup lang="tsx">
import { ref, computed, watch } from 'vue'
import type { ElFormItem, FormInstance, FormRules } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import type {
  AddStockingOrderForm,
  StockingOrderProduct,
} from '@/types/api/supply/stockingOrder'
import type { CurrencyCodeData, SupplierItem, WarehouseListData } from '@/types'
import type { userData } from '@/types/api/user'
import {
  addStockingOrderApi,
  getProductBySkuApi,
  getStockingOrderDetailByIdApi,
  rejectedStockingOrderApi,
} from '@/api/stockingOrder'
import ImageView from '@/components/ImageView.vue'
import { BigNumber } from 'bignumber.js'

const calcRowTotalPrice = (row: StockingOrderProduct): string => {
  if (!row.buyAmount || !row.price) return ''
  row.totalPrice = new BigNumber(row.buyAmount ?? 0)
    .multipliedBy(row.price ?? 0)
    .toString()
  return row.totalPrice
}

const props = defineProps<{
  modelValue: boolean
  supplierList: SupplierItem[]
  stockKeeperList: userData[]
  warehouseList: WarehouseListData[]
  currencyList: CurrencyCodeData[]
  editId: number | undefined
  editOrderType: string
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
  (e: 'refresh'): void
}>()

const visible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val),
})

const formRef = ref<FormInstance>()
const formData = ref<AddStockingOrderForm>({
  stockingUpManageNo: '',
  supplierId: undefined,
  stockingUpUserId: undefined,
  warehouseId: undefined,
  totalPrice: '',
  expectDeliveryTime: '',
  currencyCode: '',
  remark: '',
  detailsList: [],
})
type StockingOrderProductWithError = StockingOrderProduct & {
  _buyAmountError?: string
  _priceError?: string
}

const validateField = (
  row: StockingOrderProductWithError,
  field: 'buyAmount' | 'price',
) => {
  const value = row[field]
  const strValue = value === 0 || value === '0' ? '0' : String(value ?? '')

  if (!strValue) {
    if (field === 'buyAmount') row._buyAmountError = '必填项'
    else row._priceError = '必填项'
  } else if (!/^\d+(\.\d+)?$/.test(strValue)) {
    if (field === 'buyAmount') row._buyAmountError = '请输入有效数字'
    else row._priceError = '请输入有效数字'
  } else {
    if (field === 'buyAmount') row._buyAmountError = ''
    else row._priceError = ''
  }
}
const validateDetailsList = (): boolean => {
  if (!formData.value.detailsList?.length) {
    return true
  }

  let isValid = true
  formData.value.detailsList.forEach((row) => {
    const extendedRow = row as StockingOrderProductWithError
    validateField(extendedRow, 'buyAmount')
    validateField(extendedRow, 'price')
    if (extendedRow._buyAmountError || extendedRow._priceError) {
      isValid = false
    }
  })
  return isValid
}
const formRules: FormRules = {
  supplierId: [{ required: true, message: '请选择供应商', trigger: 'change' }],
  stockingUpUserId: [
    { required: true, message: '请选择备货员', trigger: 'change' },
  ],
  warehouseId: [
    { required: true, message: '请选择备货仓库', trigger: 'change' },
  ],
}

const selectedProducts = ref<StockingOrderProduct[]>([])
const productSku = ref('')
const popoverVisible = ref(false)
const tableColumns = [
  {
    label: 'SKU图片',
    prop: 'skuImage',
    width: 180,
    render: (item: StockingOrderProduct) => (
      <ImageView src={item.warehouseSkuImage} width="50px" height="50px" />
    ),
  },
  { label: '商品名称', prop: 'warehouseSkuName', minWidth: 150 },
  { label: '款号', prop: 'productNo', align: 'center', width: 120 },
  { label: '库存SKU', prop: 'warehouseSku', align: 'center', width: 180 },
  {
    label: '备货数量',
    prop: 'buyAmount',
    slot: 'buyAmount',
    width: 120,
    align: 'center',
  },
  {
    label: '备货单价',
    prop: 'price',
    slot: 'price',
    width: 120,
    align: 'center',
  },
  {
    label: '备货金额',
    prop: 'totalPrice',
    width: 120,
    align: 'center',
    render: (item: StockingOrderProduct) => calcRowTotalPrice(item),
  },
]

const searchTableColumns = computed(() => {
  return [
    {
      label: 'SKU图片',
      prop: 'skuImage',
      slot: 'skuImage',
      width: 120,
      align: 'center',
      render: (item: StockingOrderProduct) => (
        <ImageView src={item.warehouseSkuImage} width="50px" height="50px" />
      ),
    },
    { label: '商品名称', prop: 'warehouseSkuName', minWidth: 150 },
    { label: '库存SKU', prop: 'warehouseSku', align: 'center', minWidth: 180 },
    { label: '款号', prop: 'productNo', align: 'center', width: 100 },
    { label: '币种', prop: 'currencyCode', align: 'center', width: 80 },
    { label: '成本价', prop: 'price', align: 'center', width: 80 },
    {
      label: '操作',
      prop: 'operation',
      slot: 'operation',
      width: 70,
      align: 'center',
      fixed: 'right',
    },
  ]
})
const productList = ref<StockingOrderProduct[]>([])

const totalAmount = computed(() => {
  return formData.value.detailsList?.reduce((sum, cur) => {
    return new BigNumber(sum || 0)
      .plus(new BigNumber(cur.totalPrice || 0).toNumber())
      .toString()
  }, new BigNumber(0).toString())
})
const handleSelectionChange = (selection: StockingOrderProduct[]) => {
  selectedProducts.value = selection
}

const handleSearchSku = async () => {
  if (!productSku.value) {
    ElMessage.warning('请输入商品父SKU')
    popoverVisible.value = false
    return
  }
  if (!formData.value.supplierId) {
    ElMessage.warning('请先选择供应商')
    popoverVisible.value = false
    return
  }
  try {
    const res = await getProductBySkuApi(
      productSku.value,
      formData.value.supplierId,
    )
    if (res.code !== 200) {
      ElMessage.warning(res.message)
      popoverVisible.value = false
      return
    }
    productList.value = res.data || []
    if (productList.value.length === 0) {
      ElMessage.warning('未查询到商品数据')
      popoverVisible.value = false
    } else {
      popoverVisible.value = true
    }
  } catch (error) {
    console.error(error)
    popoverVisible.value = false
  }
}

const handleAddSingleProduct = (row: StockingOrderProduct) => {
  if (
    formData.value.detailsList?.some(
      (item) => item.warehouseSku === row.warehouseSku,
    )
  ) {
    ElMessage.warning('商品已添加')
    return
  }

  if (
    formData.value.currencyCode &&
    row.currencyCode !== formData.value.currencyCode
  ) {
    ElMessage.warning(`只能添加币种为 ${formData.value.currencyCode} 的商品`)
    return
  }

  if (!formData.value.currencyCode && row.currencyCode) {
    formData.value.currencyCode = row.currencyCode
  }

  formData.value.detailsList?.push(row)
  const index = productList.value.findIndex(
    (item: StockingOrderProduct) => item.warehouseSku === row.warehouseSku,
  )
  if (index !== -1) {
    productList.value.splice(index, 1)
  }
  if (productList.value.length === 0) {
    popoverVisible.value = false
  }
}

const handleDeleteSelected = () => {
  if (selectedProducts.value.length === 0) {
    ElMessage.warning('请先选择要删除的商品')
    return
  }
  const selectedSkus = selectedProducts.value.map((item) => item.warehouseSku)
  formData.value.detailsList = formData.value.detailsList?.filter(
    (item) => !selectedSkus.includes(item.warehouseSku),
  )
  selectedProducts.value = []

  // 如果商品列表为空，清空币种
  if (!formData.value.detailsList?.length) {
    formData.value.currencyCode = ''
  }
}

const handleCancel = () => {
  visible.value = false
}

const handleSave = async (isSubmit: boolean = false) => {
  if (!formRef.value) return

  try {
    await formRef.value.validate()
  } catch (e) {
    return
  }
  if (!formData.value.detailsList?.length) {
    ElMessage.warning('请先添加商品')
    return
  }
  if (!validateDetailsList()) {
    ElMessage.warning('请检查备货数量和备货单价是否正确填写')
    return
  }
  const { supplierId, warehouseId, stockingUpUserId } = formData.value
  const supplierName = props.supplierList.find(
    (item) => item.id === supplierId,
  )?.supplierName
  const warehouseName = props.warehouseList.find(
    (item) => item.id === warehouseId,
  )?.name
  const stockingUpUserName = props.stockKeeperList.find(
    (item) => item.id === stockingUpUserId,
  )?.account
  const url =
    props.editOrderType === 'add'
      ? 'factory/supply/stockingUpManage/add'
      : props.editOrderType === 'edit'
      ? `factory/supply/stockingUpManage/update`
      : `factory/supply/stockingUpManage/examine`
  const loading = ElLoading.service({
    lock: true,
    text: '加载中...',
    background: 'rgba(0, 0, 0, 0.7)',
  })
  try {
    const res = await addStockingOrderApi(url, {
      ...formData.value,
      id: props.editId,
      supplierName,
      warehouseName,
      stockingUpUserName,
      totalPrice: totalAmount.value,
      submission: props.editOrderType === 'audit' ? undefined : isSubmit,
    })
    if (res.code !== 200) {
      ElMessage.warning(res.message)
      return
    }
    ElMessage.success('保存成功')
    emit('refresh')
    visible.value = false
  } catch (error) {
    console.error(error)
  } finally {
    loading.close()
  }
}

const handleSaveAndSubmit = async () => {
  await handleSave(true)
}

const handleReject = async () => {
  if (!props.editId) return
  try {
    const { value: rejectReason } = await ElMessageBox.prompt(
      '请输入驳回原因',
      '审核驳回',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputType: 'textarea',
        inputPlaceholder: '请输入驳回原因',
        inputValidator: (val) => {
          if (!val || !val.trim()) {
            return '驳回原因不能为空'
          }
          return true
        },
      },
    )

    const loading = ElLoading.service({
      lock: true,
      text: '加载中...',
      background: 'rgba(0, 0, 0, 0.7)',
    })

    try {
      const res = await rejectedStockingOrderApi({
        id: props.editId,
        turnDownReason: rejectReason.trim(),
      })
      if (res.code !== 200) return
      ElMessage.success('驳回成功')
      emit('refresh')
      visible.value = false
    } finally {
      loading.close()
    }
  } catch {
    // 用户取消操作，不做处理
  }
}

const resetForm = () => {
  formRef.value?.resetFields()
  formData.value = {
    stockingUpManageNo: '',
    supplierId: undefined,
    stockingUpUserId: undefined,
    warehouseId: undefined,
    expectDeliveryTime: '',
    currencyCode: '',
    totalPrice: '',
    remark: '',
    detailsList: [],
  }
  selectedProducts.value = []
  productSku.value = ''
  productList.value = []
  popoverVisible.value = false
}
const handleSupplierChange = () => {
  formData.value.currencyCode = ''
  formData.value.detailsList = []
}
const getStockingOrderDetailById = async (id: number) => {
  const loading = ElLoading.service({
    lock: true,
    text: '加载中...',
    background: 'rgba(0, 0, 0, 0.7)',
  })
  try {
    const res = await getStockingOrderDetailByIdApi(id)
    if (res.code !== 200) {
      ElMessage.warning(res.message)
      return
    }
    formData.value = res.data
  } catch (error) {
    console.error(error)
  } finally {
    loading.close()
  }
}
watch(visible, (val) => {
  if (val) {
    if (!props.editId) {
      resetForm()
    } else {
      getStockingOrderDetailById(props.editId)
    }
  }
})
</script>

<style lang="scss" scoped>
.add-stocking-order {
  .form-section {
    .form-row {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
    }

    .form-item {
      flex: 1;
      min-width: 280px;
    }

    :deep(.el-select),
    :deep(.el-input),
    :deep(.el-date-editor) {
      width: 160px;
    }
  }

  .table-section {
    height: 500px;

    .empty-tip {
      text-align: center;
      color: #909399;
      padding: 20px;
    }
  }

  .add-sku-section {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 10px;

    .label {
      font-size: 14px;
      color: #606266;
    }
  }
}

.dialog-footer {
  text-align: center;
}

.popover-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;

  .popover-title {
    font-size: 14px;
    font-weight: bold;
    color: #303133;
    margin-right: auto;
  }

  .close-icon {
    cursor: pointer;
    color: #909399;
    font-size: 18px;

    &:hover {
      color: #409eff;
    }
  }
}

.popover-table {
  height: 600px;

  .sku-image {
    width: 50px;
    height: 50px;
    object-fit: contain;
  }
}
.is-error {
  :deep(.el-input__wrapper) {
    box-shadow: 0 0 0 1px #f56c6c inset;
  }
}

.field-error {
  color: #f56c6c;
  font-size: 12px;
  line-height: 1;
  margin-top: 2px;
}
</style>

<style lang="scss">
.sku-search-popover {
  .el-table {
    .el-button.is-circle {
      padding: 6px;
    }
  }
}
</style>
