<template>
  <ElDialog
    v-model="newDialogVisible"
    title="创建出库单"
    width="80%"
    :close-on-click-modal="false"
  >
    <div class="dialog-form">
      <ElForm
        ref="editFormRef"
        :model="editForm"
        :rules="rules"
        inline
        label-width="90px"
      >
        <ElFormItem label="出库单号" prop="account">
          <ElInput v-model.trim="editForm.outNo" clearable disabled />
        </ElFormItem>
        <ElFormItem label="工厂：" prop="factoryCode">
          <span>{{ editForm.factoryCode }}</span>
        </ElFormItem>
        <ElFormItem label="仓库" prop="warehouseId" required>
          <ElSelect
            v-model="editForm.warehouseId"
            clearable
            disabled
            placeholder="请选择仓库"
            style="width: 160px"
          >
            <ElOption
              v-for="item in warehouseList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            ></ElOption>
          </ElSelect>
        </ElFormItem>
        <ElFormItem label="备注" prop="remark" style="width: 45%">
          <ElInput
            v-model.trim="editForm.remark"
            placeholder="请输入备注"
            clearable
          />
        </ElFormItem>
      </ElForm>
      <ElTable
        size="small"
        :data="otherPurchaseData"
        height="500px"
        border
        @selection-change="productSelectionChange"
      >
        <ElTableColumn
          type="selection"
          width="70"
          header-align="center"
          align="center"
        ></ElTableColumn>
        <ElTableColumn
          show-overflow-tooltip
          width="60"
          align="center"
          label="序号"
          type="index"
        ></ElTableColumn>
        <ElTableColumn
          show-overflow-tooltip
          align="center"
          width="100"
          label="SKU图片"
          prop="skuImage"
        >
          <template #default="{ row }">
            <ImageView :src="row.skuImage" width="40px" height="40px" />
          </template>
        </ElTableColumn>
        <ElTableColumn
          show-overflow-tooltip
          align="center"
          label="库存SKU"
          prop="warehouseSku"
        />
        <ElTableColumn
          show-overflow-tooltip
          align="center"
          label="商品名称"
          prop="skuName"
        />
        <ElTableColumn
          show-overflow-tooltip
          align="center"
          label="款号"
          prop="productNo"
        />
        <ElTableColumn
          show-overflow-tooltip
          align="center"
          label="可用库存数量"
          prop="usableInventory"
        />
        <ElTableColumn align="center" label="出库数量" prop="outCount">
          <template #default="{ row }">
            <el-input
              v-model.number="row.outCount"
              placeholder="出库数量"
              style="width: 120px"
              clearable
              size="small"
              @input="setCostPrice(row)"
            ></el-input>
          </template>
        </ElTableColumn>
        <ElTableColumn
          width="80"
          align="center"
          label="币种"
          prop="currencyName"
        />
        <ElTableColumn
          width="100"
          align="center"
          label="成本价"
          prop="costPrice"
        />
        <ElTableColumn
          align="center"
          width="100"
          label="总成本"
          prop="totalPrice"
        />
        <ElTableColumn align="center" label="库位" prop="locationCode">
          <template #default="{ row }">
            <span v-if="row.locationCode">{{ row.locationCode }}</span>
            <ElSelect
              v-else
              v-model="row.locationId"
              clearable
              placeholder="请输入库位"
              style="width: 120px"
              filterable
              @change="handleLocationChange(row.locationId, row)"
            >
              <ElOption
                v-for="item in locationList"
                :key="item.locationId"
                :label="item.locationCode"
                :value="item.locationId"
              ></ElOption>
            </ElSelect>
          </template>
        </ElTableColumn>
        <ElTableColumn
          show-overflow-tooltip
          align="center"
          label="所属客户"
          prop="userMark"
        />
        <ElTableColumn
          show-overflow-tooltip
          align="center"
          width="240"
          label="备注"
          prop="remark"
        >
          <template #default="{ row }">
            <ElInput v-model.trim="row.remark" clearable size="small" />
          </template>
        </ElTableColumn>
      </ElTable>
    </div>
    <template #footer>
      <div class="product-dialog-footer">
        <div>
          <el-button
            type="danger"
            size="small"
            @click="deleteOtherWarehousing()"
          >
            删除
          </el-button>
        </div>
        <div>
          <el-button
            size="small"
            style="margin-left: 10px"
            @click="newDialogVisible = false"
          >
            取消
          </el-button>
          <el-button type="primary" size="small" @click="addOtherCurrency()">
            保存
          </el-button>
        </div>
      </div>
    </template>
  </ElDialog>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import BigNumber from 'bignumber.js'
import { ElMessage, ElLoading } from 'element-plus'
import ImageView from '@/components/ImageView.vue'
import {
  type InterWarehouseDetail,
  type InterProductList,
  type InterskuList,
  type ILocation,
} from '@/types/api/warehouse'
import {
  warehouseInfoGetAll,
  type warehouseInfo,
  getBySkuAndWarehouseIdApi,
  getByWareHouseIdAndCodeApi,
  addOutRecordApi,
} from '@/api/warehouse'

interface OpenParamsItem {
  thirdSkuCode: string
  suggestOutQuantity: number
}

interface OpenParams {
  warehouseId: number | string
  warehouseName?: string
  items: OpenParamsItem[]
}

const emit = defineEmits<{
  success: []
}>()

const warehouseList = ref<warehouseInfo[]>([])
const locationList = ref<ILocation[]>([])
const newDialogVisible = ref(false)
const editFormRef = ref()
const editForm = ref<InterWarehouseDetail>({
  outNo: '',
  warehouseId: '',
  warehouseName: '',
  remark: '',
  factoryCode: '',
  factoryId: 0,
  productList: [],
})
const rules = {
  warehouseId: [{ required: true, message: '请选择仓库', trigger: 'change' }],
}
const otherPurchaseData = ref<InterProductList[]>([])
const otherWarehouseSelection = ref<InterProductList[]>([])

const setCostPrice = (item: InterProductList) => {
  if (item.costPrice !== 0 && !item.costPrice) {
    ElMessage.warning('商品成本价为空，请完善商品成本价')
    return
  }
  if (item) {
    const outCount = item.outCount ?? 0
    const costPrice = item.costPrice ?? 0
    const amount = new BigNumber(outCount).multipliedBy(costPrice).toFixed(2)
    item.totalPrice = Number(amount)
  }
}

const fetchWarehouseList = async () => {
  if (warehouseList.value.length) return
  try {
    const res = await warehouseInfoGetAll()
    warehouseList.value = res.data || []
  } catch (e) {
    console.error(e)
  }
}

const fetchLocationList = async (warehouseId: number | string | undefined) => {
  if (!warehouseId) return
  try {
    const res = await getByWareHouseIdAndCodeApi(warehouseId, '')
    const result = res.data || []
    locationList.value = result.map((item: ILocation) => {
      return {
        locationId: item.id,
        locationCode: item.locationCode,
      }
    })
  } catch (e) {
    console.error(e)
    locationList.value = []
  }
}

const handleLocationChange = (val: number, row: InterProductList) => {
  const found = locationList.value.find(
    (item: ILocation) => item.locationId === val,
  )
  row.locationCode = found ? found.locationCode : ''
}

const productSelectionChange = (v: InterProductList[]) => {
  otherWarehouseSelection.value = v
}

const deleteOtherWarehousing = () => {
  const arr = otherWarehouseSelection.value
  if (!arr.length) return
  const idList = arr.map((v: InterProductList) => v.warehouseSku)
  otherPurchaseData.value = otherPurchaseData.value.filter(
    (item: InterProductList) => !idList.includes(item.warehouseSku),
  )
}

const addOtherCurrency = async () => {
  try {
    await editFormRef.value?.validate()
  } catch {
    return
  }
  const arr = otherPurchaseData.value
  if (!arr.length) {
    ElMessage.error('请至少选择一条数据')
    return
  }
  for (let i = 0; i < arr.length; i++) {
    if (!arr[i].outCount) {
      ElMessage.error('请输入出库数量')
      return
    }
    const usableInventory = arr[i].usableInventory || 0
    if ((arr[i].outCount as number) > usableInventory) {
      ElMessage.error('出库数量不能大于可用库存数量')
      return
    }
    if (!arr[i].locationId) {
      ElMessage.error('请选择库位')
      return
    }
  }
  const params: InterWarehouseDetail = {
    ...editForm.value,
    productList: otherPurchaseData.value,
  }
  try {
    await addOutRecordApi(params)
    ElMessage.success('保存成功')
    newDialogVisible.value = false
    emit('success')
  } catch (e) {
    console.error(e)
  }
}

const open = async (params: OpenParams) => {
  editForm.value.outNo = ''
  editForm.value.warehouseId = params.warehouseId
  editForm.value.warehouseName =
    params.warehouseName ||
    warehouseList.value.find(
      (item: warehouseInfo) => item.id === params.warehouseId,
    )?.name ||
    ''
  editForm.value.remark = ''

  const userJson = localStorage.getItem('user')
  if (userJson) {
    try {
      const userData = JSON.parse(userJson)
      editForm.value.factoryCode = userData.factoryCode || ''
      editForm.value.factoryId = userData.factoryId || 0
    } catch {
      // ignore
    }
  }

  otherPurchaseData.value = []

  const skuList = params.items
    .map((item) => item.thirdSkuCode)
    .filter((sku) => !!sku)

  const skuToSuggestQuantity = new Map<string, number>()
  params.items.forEach((item) => {
    if (item.thirdSkuCode) {
      skuToSuggestQuantity.set(item.thirdSkuCode, item.suggestOutQuantity || 0)
    }
  })
  const loading = ElLoading.service({
    text: '加载库存中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = await getBySkuAndWarehouseIdApi(
      params.warehouseId,
      skuList.join(','),
    )
    if (res.code !== 200) return
    await fetchWarehouseList()
    await fetchLocationList(params.warehouseId)
    const arr: InterskuList[] = res.data || []

    const mergedProductList = arr.map((skuItem) => {
      const warehouseSku = skuItem.warehouseSku || ''
      const suggestOutQuantity = skuToSuggestQuantity.get(warehouseSku) ?? 0

      const outCount = suggestOutQuantity
      const costPrice = skuItem.price ?? 0
      const totalPrice = new BigNumber(outCount)
        .multipliedBy(costPrice || 0)
        .toNumber()

      return {
        skuImage: skuItem.image,
        customerId: skuItem.customerId,
        userMark: skuItem.userMark,
        customerName: skuItem.customerName,
        currencyName: skuItem.currencyName ?? undefined,
        currencyCode: skuItem.currencyCode ?? undefined,
        warehouseSku: skuItem.warehouseSku,
        skuName: skuItem.skuName,
        productNo: skuItem.productNumber,
        locationCode: skuItem.locationCode ?? '',
        locationId: skuItem.locationId ?? null,
        costPrice,
        outCount,
        totalPrice,
        usableInventory: skuItem.usableInventory,
        inventoryId: skuItem.id,
        remark: skuItem.remark ?? null,
      } as InterProductList
    })

    otherPurchaseData.value = mergedProductList
  } catch (e) {
    console.error(e)
    otherPurchaseData.value = []
  } finally {
    loading.close()
  }

  newDialogVisible.value = true
}

defineExpose({ open })
</script>

<style scoped lang="scss">
.product-dialog-footer {
  display: flex;
  justify-content: space-between;
  margin: 8px 0;
}
</style>
