<template>
  <el-drawer
    :append-to-body="true"
    :model-value="modelValue"
    :show-close="false"
    direction="rtl"
    :size="computedSize"
    :before-close="handleClose"
    class="material-detail-drawer"
    @update:model-value="$emit('update:modelValue', $event)">
    <template #header>
      <div class="drawer-header">
        <div class="drawer-header__main">
          <div class="drawer-header__icon">
            <Icon icon="ep:goods" :size="22" />
          </div>
          <div>
            <div class="drawer-title">物料详情</div>
            <div class="drawer-subtitle">查看并维护当前 BOM 节点关联的物料数量</div>
          </div>
        </div>
        <el-button circle size="default" @click="handleClose">
          <Icon icon="ep:close" />
        </el-button>
      </div>
    </template>

    <template v-if="nodeId">
      <div v-loading="loading" class="drawer-body">
        <section class="info-card">
          <div class="info-card__header">
            <div class="info-card__title">
              <span class="info-card__marker"></span>
              <span>BOM 信息</span>
            </div>
          </div>

          <div class="info-card__body">
            <div class="detail-grid">
              <div class="detail-item">
                <div class="detail-item__label">设备分类</div>
                <div class="detail-item__value">{{ rowInfo.deviceCategoryName }}</div>
              </div>
              <div class="detail-item">
                <div class="detail-item__label">BOM节点</div>
                <div class="detail-item__value">{{ rowInfo.bomNodeName }}</div>
              </div>
            </div>
          </div>
        </section>

        <section class="info-card material-card">
          <div class="info-card__header">
            <div class="info-card__title">
              <span class="info-card__marker"></span>
              <span>关联物料</span>
            </div>
            <span class="material-total">共 {{ total }} 条</span>
          </div>

          <div class="info-card__body material-card__body">
            <ZmTable
              :data="materials"
              :loading="loading"
              :show-border="true"
              settings-cache-key="pms-bom-material-detail"
              class="material-table">
              <ZmTableColumn
                prop="name"
                :label="t('workOrderMaterial.materialName')"
                min-width="180"
                align="left"
                fixed="left" />
              <ZmTableColumn
                prop="code"
                :label="t('workOrderMaterial.materialCode')"
                min-width="130" />
              <ZmTableColumn prop="quantity" :label="t('route.quantity')" min-width="130">
                <template #default="{ row }">
                  <el-form
                    :model="row"
                    :rules="quantityRules"
                    size="default"
                    class="quantity-form"
                    @submit.prevent>
                    <el-form-item prop="quantity" :error="row.quantityError">
                      <el-input
                        v-model.number="row.quantity"
                        type="number"
                        size="default"
                        placeholder="请输入数量"
                        min="0"
                        class="quantity-input"
                        @blur="clearQuantityError(row)"
                        @keyup.enter="handleUpdate(row)" />
                    </el-form-item>
                  </el-form>
                </template>
              </ZmTableColumn>
              <ZmTableColumn prop="unit" :label="t('workOrderMaterial.unit')" min-width="90" />
              <ZmTableColumn
                :label="t('deviceList.createTime')"
                prop="createTime"
                min-width="170"
                :formatter="dateFormatter" />
              <ZmTableColumn label="操作" width="180" fixed="right" action>
                <template #default="{ row }">
                  <div class="table-actions">
                    <el-button
                      size="default"
                      type="primary"
                      link
                      :loading="row.updating"
                      @click="handleUpdate(row)">
                      <Icon icon="ep:check" class="mr-4px" />修改
                    </el-button>
                    <el-button size="default" type="danger" link @click="handleDelete(row)">
                      <Icon icon="ep:delete" class="mr-4px" />删除
                    </el-button>
                  </div>
                </template>
              </ZmTableColumn>
            </ZmTable>

            <Pagination
              v-show="total > 0"
              :total="total"
              v-model:page="queryParams.pageNo"
              v-model:limit="queryParams.pageSize"
              @pagination="loadMaterials(props.nodeId, false)" />
          </div>
        </section>
      </div>
    </template>
  </el-drawer>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage, type FormRules } from 'element-plus'
import { useTableComponents } from '@/components/ZmTable/useTableComponents'
import { CommonBomMaterialApi, type CommonBomMaterialVO } from '@/api/pms/commonbommaterial'
import { dateFormatter } from '@/utils/formatTime'

const emit = defineEmits(['update:modelValue', 'add', 'delete', 'refresh'])
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化

type MaterialDetailRow = CommonBomMaterialVO & {
  updating?: boolean
  quantityError?: string
}

const { ZmTable, ZmTableColumn } = useTableComponents<MaterialDetailRow>()

defineOptions({
  name: 'MaterialListDrawer'
})

const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  createTime: [],
  bomNodeId: '',
  name: '',
  code: ''
})

const quantityRules: FormRules = {
  quantity: [
    { required: true, message: '数量不能为空', trigger: 'blur' },
    {
      validator: (rule, value, callback) => {
        if (isNaN(value)) {
          callback(new Error('请输入有效数字'))
        } else if (value <= 0) {
          callback(new Error('数量必须大于0'))
        } else {
          callback()
        }
      },
      trigger: 'blur'
    }
  ]
}

const windowWidth = ref(window.innerWidth)
// 动态计算百分比
const computedSize = computed(() => {
  if (windowWidth.value <= 768) return '100%'
  return windowWidth.value > 1200 ? '60%' : '80%'
})
const updateWindowWidth = () => {
  windowWidth.value = window.innerWidth
}

const loading = ref(false)
const total = ref(0) // 列表的总页数
const materials = ref<MaterialDetailRow[]>([])

const props = defineProps({
  modelValue: Boolean,
  nodeId: Number,
  rowInfo: {
    type: Object,
    default: () => ({
      deviceCategoryName: '',
      bomNodeName: ''
    })
  }
})

// 加载指定bom节点下的物料数据
const loadMaterials = async (nodeId?: number, resetPage = true) => {
  if (!nodeId) return
  queryParams.bomNodeId = nodeId as any
  if (resetPage) {
    queryParams.pageNo = 1
  }
  try {
    loading.value = true
    // API调用
    const data = await CommonBomMaterialApi.getCommonBomMaterialPage(queryParams)
    materials.value = data.list.map((item) => ({
      ...item,
      updating: false, // 更新状态标记
      quantityError: '' // 错误状态标记
    }))
    total.value = data.total
  } catch (error) {
    ElMessage.error('数据加载失败')
  } finally {
    loading.value = false
  }
}

/** 清除数量错误状态 */
const clearQuantityError = (row: MaterialDetailRow) => {
  // 延迟清除错误状态，避免在验证过程中清除
  setTimeout(() => {
    row.quantityError = ''
  }, 100)
}

/** 更新物料数据 */
const handleUpdate = async (row: MaterialDetailRow) => {
  try {
    if (isNaN(row.quantity)) {
      row.quantityError = '请输入有效数字'
      ElMessage.warning('请输入有效的数字')
      return
    }

    if (row.quantity <= 0) {
      row.quantityError = '数量必须大于0'
      ElMessage.warning('数量必须大于0')
      return
    }

    // 清除错误状态
    row.quantityError = ''

    // 设置更新状态
    row.updating = true
    // 构造更新参数
    const updateParams = {
      ...row,
      bomNodeId: props.nodeId
    }
    // 调用更新接口
    await CommonBomMaterialApi.updateCommonBomMaterial(updateParams as CommonBomMaterialVO)
    // 更新成功反馈
    message.success('数量更新成功')
    emit('refresh')
  } catch (error) {
    ElMessage.error('更新失败')
  } finally {
    row.updating = false
  }
}

/** 删除BOM节点已经挂载的物料 */
const handleDelete = async (row: MaterialDetailRow) => {
  if (!props.nodeId) return

  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await CommonBomMaterialApi.deleteBomMaterial(props.nodeId, row.code)
    message.success(t('common.delSuccess'))
    // 刷新列表
    await loadMaterials(props.nodeId, false)
    emit('refresh')
  } catch {}
}

// 打开抽屉
const openDrawer = () => {
  emit('update:modelValue', true)
}

// 关闭抽屉
const closeDrawer = () => {
  handleClose()
}

// 关闭抽屉
const handleClose = () => {
  emit('update:modelValue', false)
  materials.value = []
}

defineExpose({ openDrawer, closeDrawer, loadMaterials }) // 暴露方法给父组件

onMounted(() => {
  window.addEventListener('resize', updateWindowWidth)
})

onUnmounted(() => {
  window.removeEventListener('resize', updateWindowWidth)
})
</script>

<style lang="scss" scoped>
.drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
}

.drawer-header__main {
  display: flex;
  gap: 12px;
  align-items: center;
}

.drawer-header__icon {
  display: flex;
  width: 44px;
  height: 44px;
  color: var(--el-color-primary);
  background: rgb(64 158 255 / 12%);
  border: 1px solid rgb(64 158 255 / 18%);
  border-radius: 8px;
  align-items: center;
  justify-content: center;
}

.drawer-title {
  font-size: 18px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.drawer-subtitle {
  margin-top: 4px;
  font-size: 13px;
  color: var(--el-text-color-secondary);
}

.drawer-body {
  display: flex;
  flex-direction: column;
  gap: 18px;
  height: 100%;
  padding: 4px 4px 0;
}

.info-card {
  overflow: hidden;
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 8px;
  box-shadow: 0 10px 28px rgb(31 45 61 / 6%);
}

.info-card__header {
  display: flex;
  min-height: 58px;
  padding: 0 20px;
  background: linear-gradient(90deg, rgb(64 158 255 / 8%) 0%, rgb(255 255 255 / 0%) 72%);
  border-bottom: 1px solid var(--el-border-color-lighter);
  align-items: center;
  justify-content: space-between;
}

.info-card__title {
  display: flex;
  gap: 10px;
  font-size: 16px;
  font-weight: 600;
  line-height: 22px;
  color: var(--el-text-color-primary);
  align-items: center;
}

.info-card__marker {
  width: 4px;
  height: 18px;
  background: var(--el-color-primary);
  border-radius: 2px;
}

.info-card__body {
  padding: 20px;
}

.detail-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.detail-item {
  min-width: 0;
  padding: 14px 16px;
  background: var(--el-fill-color-lighter);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 8px;
}

.detail-item__label {
  margin-bottom: 6px;
  font-size: 13px;
  line-height: 18px;
  color: var(--el-text-color-secondary);
}

.detail-item__value {
  overflow: hidden;
  font-size: 15px;
  font-weight: 600;
  line-height: 22px;
  color: var(--el-text-color-primary);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.material-card {
  flex: 1;
  min-height: 0;
}

.material-card__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
  min-height: 0;
}

.material-total {
  font-size: 13px;
  color: var(--el-text-color-secondary);
}

.material-table {
  flex: 1;
  min-height: 0;
}

.quantity-form {
  display: flex;
  justify-content: center;
}

.quantity-form :deep(.el-form-item) {
  width: 96px;
  margin-bottom: 0;
}

.quantity-form :deep(.el-form-item__error) {
  position: absolute;
  top: 100%;
  left: 0;
  padding-top: 2px;
  font-size: 12px;
  line-height: 1;
  color: var(--el-color-danger);
  white-space: nowrap;
}

.quantity-input :deep(.el-input__inner) {
  text-align: center;
}

.table-actions {
  display: flex;
  justify-content: center;
  gap: 8px;
  align-items: center;
}

@media (width <= 768px) {
  .drawer-body {
    padding: 0;
  }

  .info-card__header {
    padding: 12px 16px;
    align-items: flex-start;
    flex-direction: column;
    gap: 4px;
  }

  .info-card__body {
    padding: 16px;
  }

  .detail-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
</style>
