<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { ref, reactive, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { GlobalStore } from '@/stores/index'
import type { FormInstance, FormRules } from 'element-plus'
import { Delete, CirclePlus } from '@element-plus/icons-vue'
import ReceiveUser from './receiveUser.vue'
import InStorageSn from '../inventory/InStorageSn.vue'
import ContractNumber from './ContractNumber.vue'
import { depotHooks, SaleFormType, delivery_type } from '@/hooks/useDepot'
import { Storehouse_StockOut_Add, Storehouse_Contract_Product_List, Storehouse_StockOut_Generate_Number } from '@/api/storehouse/index'
import ImageCom from '@/components/Image/index.vue'

const router = useRouter()
const tableData = ref<any[]>([])
const globalStore = GlobalStore()
const formLabelWidth = ref('120px')
const ruleFormRef = ref<FormInstance>()
const drawerSnRef = ref<InstanceType<typeof InStorageSn> | null>(null)
const receiveUserdialog = ref<InstanceType<typeof ReceiveUser> | null>(null)
const contractNumberRef = ref<InstanceType<typeof ContractNumber> | null>(null)

// 防抖相关
const isSubmitting = ref(false)
const isGeneratingNumber = ref(false)
let generateNumberTimer: NodeJS.Timeout | null = null
const form = ref<SaleFormType>({
  T_type: 2,
  T_uuid: '',
  T_receive: '',
  T_number: '',
  T_depot_id: '',
  T_product: '',
  T_date: '',
  T_remark: '',
  T_delivery_type: '',
  T_signer_unit: '',
  T_signer: '',
  T_signer_phone: '',
  T_signer_date: '',
  T_courier_number: '',
  T_contract_number: ''
})

const columns = [
  { type: 'index', label: '序号', width: 80, align: 'center ' },
  { label: '产品图片', prop: 'T_product_img', align: 'center ', name: 'T_product_img', width: 100 },
  { label: '产品名称', prop: 'T_product_name', align: 'center ' },
  { label: '产品型号', prop: 'T_product_model', align: 'center ' },
  { label: '产品分类', prop: 'T_product_class_name', align: 'center ' },
  { label: '产品型号', prop: 'T_product_model', align: 'center ', ellipsis: true },
  { label: '产品规格', prop: 'T_product_spec', align: 'center ' },
  { label: '是否关联SN', prop: 'T_product_relation_sn', align: 'center ', width: 120, name: 'T_product_relation_sn' },
  { label: '库存数量', prop: 'T_stock_total', align: 'center ', width: 100 },
  { label: '预计出库数量', prop: 'T_product_total', align: 'center ', width: 130 },
  { label: '已出库数量', prop: 'T_product_out', align: 'center ', width: 120 },
  { label: '*实际出库数量', prop: 'count', align: 'center ', name: 'count', width: 140 },
  { label: '*关联设备', prop: 'sn', align: 'center ', name: 'sn', width: 100 },
  { prop: 'operation', label: '操作', width: 80, fixed: 'right' }
]

const validate_T_product = (rule: any, value: any, callback: any) => {
  if (value.includes(undefined) || value === '') {
    callback(new Error('请填写产品数量,出库数量不能大于库存数量!'))
  } else if (value.includes(null)) {
    callback(new Error('请添加产品SN'))
  } else {
    callback()
  }
}

const rules = reactive<FormRules>({
  T_product: [{ required: true, validator: validate_T_product, trigger: 'blur' }],
  T_receive: [{ required: true, message: '请选择经办人', trigger: 'change' }],
  T_depot_id: [{ required: true, message: '请选择仓库', trigger: 'blur' }],
  T_date: [{ required: true, message: '请选择出库日期', trigger: 'blur' }],
  T_contract_number: [{ required: true, message: '请选择合同编号', trigger: 'change' }]
})

const countBlurHandle = () => {
  form.value.T_product = tableData.value.map(item => {
    if (!item.count && item.T_product_relation_sn !== 1) return undefined
    if (item.count > item.T_stock_total && item.count > item.T_product_total) return undefined
    return `${item.T_product_id},${item.count}|`
  })
}
const getDeviceSnToProduct = () => {
  const DeviceSnData: any = drawerSnRef.value?.getDeviceSn()
  const isEmpty = determineSNorCount(DeviceSnData)
  if (isEmpty && isEmpty === 'count') return [undefined]
  if (isEmpty && isEmpty === 'sn') return [null]

  return tableData.value.map((item: any) => {
    let product: any = ''
    if (item.T_product_relation_sn === 1) {
      DeviceSnData?.forEach((value: any, key: number) => {
        if (item.T_product_id === key) {
          let str = ''
          value.forEach(
            (snObj: any, index: number, arr: any[]) => (str += `${snObj.sn}${index === arr.length - 1 ? '' : ','}`)
          )
          product = `${item.T_product_id}-${item.count}-${str}`
        }
      })
    } else {
      product = `${item.T_product_id}-${item.count}-`
    }
    return product + '|'
  })
}
/**
 * 判断sn or 数量是否为空
 */
const determineSNorCount = (DeviceSnData: any) => {
  for (const item of tableData.value) {
    if (
      (!item.count && item.T_product_relation_sn !== 1) ||
      (item.count > item.T_stock_total && item.count > item.T_product_total)
    )
      return 'count'
    if (
      (item.T_product_relation_sn === 1 && !DeviceSnData.get(item.Id) && !DeviceSnData.size) ||
      (item.count > item.T_stock_total && item.count > item.T_product_total)
    )
      return 'sn'
  }
  return false
}

/**
 * 生成出库单号（防抖）
 */
const generateStockOutNumber = async () => {
  if (isGeneratingNumber.value) return
  
  // 清除之前的定时器
  if (generateNumberTimer) {
    clearTimeout(generateNumberTimer)
  }
  
  generateNumberTimer = setTimeout(async () => {
    try {
      isGeneratingNumber.value = true
      const res: any = await Storehouse_StockOut_Generate_Number({
        User_tokey: globalStore.GET_User_tokey
      })
      if (res.Code === 200) {
        form.value.T_number = res.Data
      } else {
        ElMessage.error('生成出库单号失败：' + (res.Msg || '系统错误'))
      }
    } catch (error) {
      console.error('生成出库单号失败:', error)
      ElMessage.error('生成出库单号失败，请重试')
    } finally {
      isGeneratingNumber.value = false
    }
  }, 500) // 500ms 防抖延迟
}

/**
 * 页面加载时自动生成出库单号
 */
const initializeOutStockNumber = () => {
  if (!form.value.T_number) {
    generateStockOutNumber()
  }
}

// 页面加载时生成出库单号
if (!form.value.T_number) {
  generateStockOutNumber()
}

/**
 * 添加sn 号
 */
const addDeviceSn = (id: number) => {
  if (!form.value.T_date) {
		ElMessage.warning('请先填写出库日期')
		return
	}
  drawerSnRef.value?.addDeviceSn(id, 1, id, form.value.T_date)
}
/**
 * 自动计算 count
 */
const autoGetCount = (length: number, id: number) => {
  tableData.value.forEach((item: any) => {
    if (item.T_product_id === id) {
      item.count = length
    }
  })
}
/**
 * 选择经办人
 */
const selectApprover = () => receiveUserdialog.value?.openDrawer()
const getReceiveInfo = ({ T_uuid, T_name }: { T_uuid: string; T_name: string }) => {
  form.value.T_receive = T_name
  form.value.T_uuid = T_uuid
}
/**
 * 选择仓库
 */
const selectDepot = (val: any) => {
  form.value.T_depot_id = val

  if (form.value.T_depot_id && form.value.T_contract_number) getProductList()
}
/**
 * 选择合同
 */
const selectContract = () => contractNumberRef.value?.openDrawer()
const getContactInfo = ({ T_number }: { T_number: string }) => {
  if (form.value.T_contract_number === T_number) return
  form.value.T_contract_number = T_number
  if (form.value.T_depot_id && form.value.T_contract_number) getProductList()
}
/**
 * 通过合同获取产品
 */
const getProductList = async () => {
  const res: any = await Storehouse_Contract_Product_List({
    User_tokey: globalStore.GET_User_tokey,
    T_number: form.value.T_contract_number,
    T_depot_id: form.value.T_depot_id
  })
  if (res.Code === 200 && res.Data.length) {
    tableData.value = res.Data
  }
}
/**
 * 删除产品
 */
const deleteProduct = (row: any) => {
  tableData.value = tableData.value.filter(item => item.Id !== row.Id)

  // 设置产品的选中
  // drawerProductRef.value?.selectTableChange(row)
  // 删除设备得sn
  drawerSnRef.value?.deleteDeviceSn(row.Id)
}
/**
 * 重置表单
 */
const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  tableData.value = []
  formEl.resetFields()
  
  // 清理防抖定时器
  if (generateNumberTimer) {
    clearTimeout(generateNumberTimer)
    generateNumberTimer = null
  }
  isSubmitting.value = false
  isGeneratingNumber.value = false
}
/**
 * 取消出库
 */
const closeSaleOutStock = () => {
  resetForm(ruleFormRef.value)
  drawerSnRef.value?.clearDeviceSn()
  router.back()
}
/**
 * 提交内容
 */
const AddSaleOutStock = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  
  // 防止重复提交
  if (isSubmitting.value) {
    ElMessage.warning('正在提交中，请勿重复操作')
    return
  }
  
  form.value.T_product = getDeviceSnToProduct()
  formEl.validate(async valid => {
    if (valid) {
      try {
        isSubmitting.value = true
        const res: any = await Storehouse_StockOut_Add({
          User_tokey: globalStore.GET_User_tokey,
          ...form.value,
          T_product: form.value.T_product.join(''),
          T_receive: form.value.T_uuid
        })
        if (res.Code === 200) {
          ElMessage.success('出库成功！')
          nextTick(() => {
            closeSaleOutStock()
          })
        } else {
          ElMessage.error('出库失败：' + (res.Msg || '系统错误'))
        }
      } catch (error) {
        console.error('出库失败:', error)
        ElMessage.error('出库失败，请重试')
      } finally {
        isSubmitting.value = false
      }
    }
  })
}

const { options } = depotHooks()
</script>
<template>
  <div class="receive-outStock">
    <div>
      <h4 class="title">销售出库</h4>
      <el-divider border-style="dashed" />
    </div>
    <el-form ref="ruleFormRef" :model="form" :rules="rules">
      <el-form-item label="出库单号：" :label-width="formLabelWidth" prop="T_number">
        <div class="w-50" style="display: flex; align-items: center; gap: 8px;">
          <el-input 
            v-model="form.T_number" 
            type="text" 
            :disabled="true"
            style="flex: 1;"
          />
          <el-button 
            type="primary" 
            size="small" 
            :loading="isGeneratingNumber"
            :disabled="isGeneratingNumber"
            @click="generateStockOutNumber"
          >
            {{ isGeneratingNumber ? '生成中...' : '重新生成' }}
          </el-button>
        </div>
      </el-form-item>
      <el-form-item label="合同编号：" :label-width="formLabelWidth" prop="T_contract_number">
        <el-input v-model="form.T_contract_number" placeholder="请选择合同编号" class="w-50" @focus="selectContract" />
      </el-form-item>
      <el-form-item label="出库仓库：" :label-width="formLabelWidth" prop="T_depot_id">
        <el-select v-model="form.T_depot_id" class="w-50" clearable placeholder="请选择出库仓库~" @change="selectDepot">
          <el-option v-for="item in options" :key="item.Id" :label="item.T_name" :value="item.Id" />
        </el-select>
      </el-form-item>
      <el-form-item label="出库日期：" :label-width="formLabelWidth" prop="T_date">
        <el-date-picker
          class="my-date-picker"
          style="flex: 0 0 33.33%"
          v-model="form.T_date"
          type="date"
          placeholder="选择日期"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
        />
      </el-form-item>
      <el-form-item label="经办人：" :label-width="formLabelWidth" prop="T_receive">
        <el-input v-model="form.T_receive" placeholder="请选择经办人" class="w-50" @focus="selectApprover" />
      </el-form-item>
      <el-form-item label="出库明细：" :label-width="formLabelWidth" prop="T_product">
        <el-table
          :data="tableData"
          style="width: 100%"
          border
          stripe
          :header-cell-style="{
            background: '#dedfe0',
            height: '50px'
          }"
        >
          <template v-for="item in columns" :key="item.prop">
            <el-table-column v-bind="item" v-if="item.fixed !== 'right' && !item.ellipsis" tooltip-effect="dark" :show-overflow-tooltip="true">
              <template #header v-if="item.prop === 'count' || item.prop === 'sn'">
                <span style="color: red">{{ item.label }}</span>
              </template>
              <template #default="{ row }" v-if="item.prop === item.name">
                <el-input
                  v-if="item.prop === 'count' && row.T_product_relation_sn !== 1"
                  v-model.number="row.count"
                  type="text"
                  autocomplete="off"
                  @blur="countBlurHandle"
                />
                <div v-if="item.prop === 'sn'">
                  <el-button
                    v-if="row.T_product_relation_sn === 1"
                    link
                    type="primary"
                    size="small"
                    :icon="CirclePlus"
                    @click="addDeviceSn(row.T_product_id)"
                    >添加</el-button
                  >
                  <span v-else>-</span>
                </div>
                <span v-if="item.prop === 'T_product_relation_sn'">
                  <el-tag v-if="row.T_product_relation_sn === 1" effect="dark">是</el-tag>
                  <el-tag v-else type="success" effect="dark">否</el-tag>
                </span>
                        <ImageCom v-if="item.prop === 'T_product_img'" :src="row.T_product_img" :key="row.Id"/>
              </template>
            </el-table-column>
            <el-table-column v-if="item.ellipsis && item.prop === 'T_model'" v-bind="item" tooltip-effect="dark" :show-overflow-tooltip="true">
              <template #default="{ row }">
                <el-tooltip effect="dark" :content="row.T_model" placement="bottom">
                  {{ row.T_model }}
                </el-tooltip>
              </template>
            </el-table-column>
            <el-table-column v-bind="item" v-if="item.fixed === 'right'" tooltip-effect="dark" :show-overflow-tooltip="true">
              <template #default="{ row }">
                <el-button link type="danger" size="small" :icon="Delete" @click="deleteProduct(row)">删除</el-button>
              </template>
            </el-table-column>
          </template>
        </el-table>
      </el-form-item>
      <el-form-item label="送货方式：" :label-width="formLabelWidth" prop="T_delivery_type">
        <el-select v-model="form.T_delivery_type" clearable placeholder="请选择送货方式~" class="w-50">
          <el-option v-for="item in delivery_type" :key="item.id" :label="item.name" :value="item.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="签收单位：" :label-width="formLabelWidth" prop="T_signer_unit">
        <el-input v-model="form.T_signer_unit" type="text" placeholder="请输入签收单位" class="w-50" />
      </el-form-item>
      <el-form-item label="签收人：" :label-width="formLabelWidth" prop="T_signer">
        <el-input v-model="form.T_signer" type="text" placeholder="请输入签收人" class="w-50" />
      </el-form-item>
      <el-form-item label="签收人电话：" :label-width="formLabelWidth" prop="T_signer_phone">
        <el-input v-model="form.T_signer_phone" type="text" placeholder="请输入签收人电话" class="w-50" />
      </el-form-item>
      <el-form-item label="签收日期：" :label-width="formLabelWidth" prop="T_signer_date">
        <el-date-picker
          class="my-date-picker"
          style="flex: 0 0 33.33%"
          v-model="form.T_signer_date"
          type="date"
          placeholder="选择签收日期"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
        />
      </el-form-item>
      <el-form-item label="物流单号：" :label-width="formLabelWidth" prop="T_courier_number">
        <el-input v-model="form.T_courier_number" type="text" placeholder="请输入物流单号" class="w-50" />
      </el-form-item>
      <el-form-item label="备注：" :label-width="formLabelWidth" prop="T_remark">
        <el-input
          v-model="form.T_remark"
          :autosize="{ minRows: 4, maxRows: 6 }"
          type="textarea"
          placeholder="请输入备注信息"
        />
      </el-form-item>
      <div class="btn">
        <el-divider>
          <el-button @click="closeSaleOutStock">取消</el-button>
          <el-button 
            color="#626aef" 
            :loading="isSubmitting"
            :disabled="isSubmitting || isGeneratingNumber"
            @click="AddSaleOutStock(ruleFormRef)"
          >
            {{ isSubmitting ? '提交中...' : '提交' }}
          </el-button>
        </el-divider>
      </div>
    </el-form>
    <InStorageSn ref="drawerSnRef" @onCount="autoGetCount" />
    <ReceiveUser ref="receiveUserdialog" :dept_leader="0" @onUserInfo="getReceiveInfo" title="选择经办人" />
    <ContractNumber ref="contractNumberRef" @onContactInfo="getContactInfo" />
  </div>
</template>

<style scoped lang="scss">
@import './index.scss';
</style>
