<template>
  <ElDialog
    v-model="visible"
    :title="dialogTitle"
    width="1400px"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div v-if="pickData" class="pick-order-data">
      <div class="pick-order-data-message">
        <Icon style="width: 24px; height: 24px" name="tishi" />
        <span> {{ pickData.overallMessage }}! </span>
      </div>
      <div class="pick-complete-actions" style="margin-bottom: 10px">
        <span class="item">
          <ElButton type="success" @click="handleCreateInbound">
            创建入库单
          </ElButton>
        </span>
      </div>
      <div class="table-view">
        <TableView
          :paginated-data="pickData.pickingSituationList || []"
          :columns="columns"
          serial-numberable
          selectionable
          @selection-change="handleSelectionChange"
        >
          <template #skuImage="{ row }">
            <el-image
              v-if="row.skuImage"
              :src="row.skuImage"
              style="width: 50px; height: 50px"
              fit="contain"
              :preview-src-list="[row.skuImage]"
              preview-teleported
            />
          </template>
          <template #pickQuantity="{ row }">
            <span style="color: #e6a23c; font-weight: bold">{{
              row.selectedQuantity
            }}</span>
          </template>
          <template #pickStatus="{ row }">
            <span
              v-if="row.pickingStatus === 'fail'"
              style="color: #f56c6c; font-weight: 500"
            >
              ✕ 无法拣胚
            </span>
            <span v-else-if="row.pickingStatus === 'partial'" class="item">
              <ElButton
                type="warning"
                size="small"
                @click="handleAdjustPickOrder(row)"
                >调整拣胚顺序</ElButton
              >
            </span>
            <span
              v-else-if="row.pickingStatus === 'success'"
              style="color: #67c23a; font-weight: 500"
            >
              ✓ 直接拣胚
            </span>
            <span v-else style="color: #999; font-weight: 500">未知状态</span>
          </template>
        </TableView>
      </div>
    </div>
    <template #footer>
      <div class="dialog-footer" style="text-align: center">
        <span class="item">
          <ElButton @click="visible = false">取消</ElButton>
        </span>
        <span class="item">
          <ElButton type="primary" @click="handleSubmit"> 确定 </ElButton>
        </span>
      </div>
    </template>
  </ElDialog>
  <OperateDetailsDialog
    ref="operateDetailsDialogRef"
    title="调整拣胚顺序"
    :pickable="true"
    @adjust-pick-order-success="onAdjustPickOrderSuccess"
  />
  <ReceiptProductDialog
    ref="receiptProductDialogRef"
    v-model:visible="receiptDialogVisible"
    v-model:user-mark="receiptUserMark"
    v-model:select-sku="receiptSelectSku"
    title="创建入库单"
    :disable-warehouse="true"
    :show-user-mark-filter="false"
    :show-query-button="false"
    :show-batch-add-button="false"
    :show-import-button="false"
    :edit-form="receiptEditForm"
    :rules="receiptRules"
    :warehouse-list="warehouseList"
    :other-purchase-data="otherPurchaseData"
    :location-list="locationList"
    :user-mark-list="userMarkList"
    :sku-data="skuData"
    :filter-sku-data="filterSkuData"
    @warehouse-change="handleReceiptWarehouseChange"
    @selection-change="handleReceiptProductSelectionChange"
    @set-cost-price="setCostPrice"
    @location-change="handleReceiptLocationChange"
    @update:remark="updateReceiptRemark"
    @update:warehouse-id="updateReceiptWarehouseId"
    @delete="deleteReceiptProducts"
    @save="handleReceiptSave"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage, ElLoading } from 'element-plus'
import {
  pickCompleteByIdsDataApi,
  pickCompleteApi,
  replenishmentCompleteApi,
  markStockOutOfApi,
} from '@/api/factoryOrderNew'
import type { PickCompleteData } from '@/types/api/factoryOrderNew'
import type { BaseRespData } from '@/types/api'
import type {
  InterProductList,
  InterWarehouseDetail,
  InterskuList,
  ILocation,
} from '@/types/api/warehouse'
import {
  warehouseInfoGetAll,
  getBySkuAndUserMarkApi,
  getByWareHouseIdAndCodeApi,
  addInRecordApi,
  type warehouseInfo,
} from '@/api/warehouse'
import { useValue } from '@/utils/hooks/useValue'
import { useReceiptProductDialog } from '@/views/warehouse/hooks/useReceiptProductDialog'
import TableView from '@/components/TableView.vue'
import Icon from '@/components/Icon.vue'
import OperateDetailsDialog from './OperateDetailsDialog.vue'
import ReceiptProductDialog from '@/views/warehouse/components/ReceiptProductDialog.vue'
interface PickData {
  overallMessage?: string
  pickingSituationList?: PickCompleteData[]
  allAvailableOrderIds?: number[]
  partialAvailableOrderIds?: number[]
  unavailableOrderIds?: number[]
}
const emit = defineEmits<{
  success: []
}>()

const receiptRules = {
  warehouseId: [{ required: true, message: '请选择仓库', trigger: 'change' }],
}

const [receiptEditForm, resetReceiptEditForm] = useValue<InterWarehouseDetail>({
  inNo: '',
  warehouseId: '',
  warehouseName: '',
  remark: '',
  factoryCode: '',
  factoryId: 0,
  productList: [],
})

const receiptDialogVisible = ref(false)
const warehouseList = ref<warehouseInfo[]>([])
const otherPurchaseData = ref<InterProductList[]>([])
const locationList = ref<ILocation[]>([])
const receiptUserMark = ref(0)
const batchUserMark = ref(0)
const importUserMark = ref(0)
const receiptSelectSku = ref('')
const userMarkList = ref<
  { userId: number; userMark: string; userName: string }[]
>([{ userId: 0, userMark: '', userName: '' }])

const { skuData, setCostPrice, filterSkuData } = useReceiptProductDialog({
  editForm: receiptEditForm,
  otherPurchaseData,
  userMark: receiptUserMark,
  batchUserMark,
  importUserMark,
  selectSku: receiptSelectSku,
  userMarkList,
})

const receiptProductDialogRef = ref<{
  validateForm: () => Promise<void>
} | null>(null)
const otherReceiptSelection = ref<InterProductList[]>([])

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

const updateReceiptRemark = (value: string) => {
  receiptEditForm.value.remark = value
}

const updateReceiptWarehouseId = (value: number | string | undefined) => {
  receiptEditForm.value.warehouseId = value
}

const handleReceiptWarehouseChange = (val: number | string | undefined) => {
  const found = warehouseList.value.find(
    (item: warehouseInfo) => item.id === val,
  )
  receiptEditForm.value.warehouseName = found ? found.name : ''
}

const handleReceiptProductSelectionChange = (v: InterProductList[]) => {
  otherReceiptSelection.value = v
}

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

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

function mapInterskuToProduct(val: InterskuList): InterProductList {
  const warehouseSku = val.warehouseSku || val.sku || ''
  const skuNameVal = val.skuName || val.productName || ''
  let customerId: number | null = null
  if (val.customerId != null && val.customerId !== '') {
    const n = Number(val.customerId)
    if (!Number.isNaN(n)) customerId = n
  }
  return {
    skuImage: val.skuImage || val.image || '',
    warehouseSku,
    skuName: skuNameVal,
    productNo: val.productNo ?? null,
    locationCode: val.locationCode ?? '',
    locationId: val.locationId ?? null,
    costPrice: val.costPrice ?? null,
    buyStored: null,
    totalPrice: null,
    currencyName: val.currencyName ?? null,
    currencyCode: val.currencyCode ?? null,
    customerId,
    customerName: val.customerName ?? null,
    userMark: val.userMark ?? null,
  }
}

const handleReceiptSave = async () => {
  try {
    await receiptProductDialogRef.value?.validateForm()
  } catch {
    return
  }
  const arr = otherPurchaseData.value
  if (arr.length === 0) {
    ElMessage.error('请至少选择一条数据')
    return
  }
  for (let i = 0; i < arr.length; i++) {
    if (!arr[i].buyStored) {
      ElMessage.error('请输入入库数量')
      return
    }
    if (!arr[i].locationId) {
      ElMessage.error('请选择库位')
      return
    }
    const found = locationList.value.find(
      (item: ILocation) => item.locationId === arr[i].locationId,
    )
    if (!arr[i].locationCode) {
      arr[i].locationCode = found ? found?.locationCode : ''
    }
  }
  const params = {
    ...receiptEditForm.value,
    productList: otherPurchaseData.value,
  }
  const loading = ElLoading.service({
    text: '保存中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    await addInRecordApi(params)
    ElMessage.success('保存成功')
    receiptDialogVisible.value = false
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}

const visible = ref(false)
const pickData = ref<PickData | null>(null)
const selections = ref<PickCompleteData[]>([])
const dialogTitle = ref('拣胚完成')
const submitApi =
  ref<(ids: (number | string)[]) => Promise<BaseRespData<void>>>(
    pickCompleteApi,
  )

const columns = [
  {
    prop: 'warehouseName',
    label: '仓库名称',
    minWidth: 120,
  },
  {
    label: 'SKU图片',
    width: 100,
    align: 'center',
    slot: 'skuImage',
  },
  {
    key: 'productName',
    prop: 'productName',
    label: '商品名称',
    minWidth: 120,
    showOverflowTooltip: true,
  },
  {
    prop: 'supplierProductNo',
    label: '款号',
    width: 100,
    align: 'center',
  },
  {
    prop: 'thirdSkuCode',
    label: '库存SKU',
    align: 'center',
    width: 180,
  },
  {
    prop: 'selectedQuantity',
    label: '本次拣胚数量',
    width: 110,
    align: 'right',
    slot: 'pickQuantity',
  },
  {
    prop: 'availableInventory',
    label: '可调配库存',
    width: 100,
    align: 'right',
  },
  {
    prop: 'inventory',
    label: '库存数量',
    width: 90,
    align: 'right',
  },
  {
    prop: 'producingQuantity',
    label: '生产中数量',
    width: 100,
    align: 'right',
  },
  {
    prop: 'occupyInventory',
    label: '占用数量',
    width: 90,
    align: 'right',
  },
  {
    label: '拣胚情况',
    width: 130,
    align: 'center',
    fixed: 'right',
    slot: 'pickStatus',
  },
]

const open = async (
  ids: (number | string)[],
  _adjustOrderIds?: number[],
  _selectedRow?: PickCompleteData,
  options?: {
    title?: string
    submitType?: 'pick' | 'replenish'
  },
) => {
  selections.value = []
  pickData.value = null
  dialogTitle.value = options?.title || '拣胚完成'
  submitApi.value =
    options?.submitType === 'replenish'
      ? replenishmentCompleteApi
      : pickCompleteApi
  const loading = ElLoading.service({
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = await pickCompleteByIdsDataApi(ids)
    if (res.code !== 200) return
    pickData.value = res.data || null
    visible.value = true
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}

const onAdjustPickOrderSuccess = async (
  _: unknown,
  adjustOrderIds: number[],
  selectedRow: PickCompleteData,
) => {
  const previousPickList = pickData.value?.pickingSituationList ?? []
  if (selectedRow && adjustOrderIds && adjustOrderIds.length > 0) {
    const adjustPickData = previousPickList.find(
      (item: PickCompleteData) =>
        item.thirdSkuCode === selectedRow.thirdSkuCode,
    )
    if (adjustPickData) {
      adjustPickData.availableOrderIds = adjustOrderIds
    }
  }
  pickData.value = {
    ...pickData.value,
    pickingSituationList: previousPickList,
  }
}

const handleClose = () => {
  pickData.value = null
}

const handleCreateInbound = async () => {
  if (selections.value.length === 0) {
    ElMessage.warning('请选择需创建入库单的数据')
    return
  }
  const firstWid = selections.value[0].warehouseId
  if (selections.value.some((r) => r.warehouseId !== firstWid)) {
    return ElMessage.error('请选择相同仓库的库存SKU！')
  }
  resetReceiptEditForm()
  otherPurchaseData.value = []
  receiptUserMark.value = 0
  receiptSelectSku.value = ''
  skuData.value = []
  otherReceiptSelection.value = []
  const userJson = localStorage.getItem('user')
  if (userJson) {
    try {
      const userData = JSON.parse(userJson)
      receiptEditForm.value.factoryCode = userData.factoryCode || ''
      receiptEditForm.value.factoryId = userData.factoryId || 0
    } catch {
      // ignore
    }
  }
  receiptEditForm.value.warehouseId = firstWid
  receiptEditForm.value.warehouseName = selections.value[0].warehouseName || ''
  const wh = warehouseList.value.find((w) => w.id == firstWid)
  if (wh) {
    receiptEditForm.value.warehouseName = wh.name
  }
  const loading = ElLoading.service({
    text: '加载中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    warehouseList.value = []
    otherPurchaseData.value = []
    for(const item of selections.value){
      if(item.thirdSkuCode){
        const userMark = item.thirdSkuCode.includes('JM')?null:item.thirdSkuCode.slice(0,4)
        const res = await getBySkuAndUserMarkApi(firstWid, item.thirdSkuCode, userMark)
        if (res.code !== 200) return
        otherPurchaseData.value = otherPurchaseData.value.concat(res.data.map((r: InterskuList) =>
          mapInterskuToProduct(r),
        ) )
      }
    }
    await fetchReceiptLocationList('')
    const listRes = await warehouseInfoGetAll()
    warehouseList.value = listRes.data || []
    receiptDialogVisible.value = true
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}
const operateDetailsDialogRef = ref()
const handleSelectionChange = (selection: PickCompleteData[]) => {
  selections.value = selection
}
const handleAdjustPickOrder = async (row: PickCompleteData) => {
  operateDetailsDialogRef.value?.open({
    row,
    ids: row.allOrderIds as (number | string)[],
    url: 'factory/podOrderOperation/listByIds',
  })
}

const handleSubmit = async () => {
  const loading = ElLoading.service({
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  const orderIds = pickData.value?.pickingSituationList
    ?.map((item) => item.availableOrderIds)
    .flat()
  try {
    if (orderIds && orderIds.length > 0) {
      const res = await submitApi.value(orderIds as (number | string)[])
      if (res.code !== 200) return
    }
    const pickFailedOrderList = pickData.value?.pickingSituationList?.filter(
      (item) => item.pickingStatus !== 'success',
    )
    if (pickFailedOrderList && pickFailedOrderList.length > 0) {
      const warehouseMap: Record<number, PickCompleteData[]> = {}
      for (const item of pickFailedOrderList) {
        const wid = item.warehouseId
        if (!warehouseMap[wid]) warehouseMap[wid] = []
        warehouseMap[wid].push(item)
      }
      try {
        for (const [widStr, rows] of Object.entries(warehouseMap)) {
          const warehouseSkuList = [
            ...new Set(
              rows
                .map((r) => r.thirdSkuCode)
                .filter((s): s is string => typeof s === 'string' && s !== ''),
            ),
          ]
          const markRes = await markStockOutOfApi({
            warehouseId: widStr,
            warehouseSkuList,
          })
          if (markRes.code !== 200) return
        }
      } catch (e) {
        console.error(e)
      }
    }
    ElMessage.success('操作成功')
    visible.value = false
    emit('success')
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}

defineExpose({ open })
</script>

<style scoped lang="scss">
.table-view {
  height: 600px;
}
.pick-order-data-message {
  font-size: 14px;
  color: #f56c6c;
  margin-bottom: 10px;
  font-weight: bold;
  display: flex;
  align-items: center;
}
</style>
