<script setup lang="ts">
import { IotRyImproveDailyReportApi } from '@/api/pms/iotryimprovedailyreport'
import { useTableComponents } from '@/components/ZmTable/useTableComponents'
import { FormInstance, FormRules } from 'element-plus'
import { Close, Delete, Plus } from '@element-plus/icons-vue'

defineOptions({ name: 'IotRyEquipmentReportForm' })

type FormMode = 'create' | 'edit' | 'detail' | 'approval' | 'modify'

interface EquipmentReportForm {
  id?: number
  title: string
  createTime: number | undefined
  workLocation: string
  workPurpose: string
  relocationDays: number | undefined
  improveReportDetails: ImproveReportDetail[]
  personnel: string
  auditStatus?: 0 | 10 | 20 | 30 | 40
  opinion?: string
  modifyFlag?: 'Y'
}

interface ImproveReportDetail {
  detailKey?: string
  projectName: string
  constructionDetail: string
  nextPlan: string
}

interface Props {
  visible?: boolean
  loadList: () => void | Promise<void>
  reloadAfterCreate?: () => void | Promise<void>
}

const props = withDefaults(defineProps<Props>(), {
  visible: false
})

const emits = defineEmits<{
  'update:visible': [value: boolean]
}>()

const defaultForm: EquipmentReportForm = {
  title: '',
  createTime: undefined,
  workLocation: '',
  workPurpose: '',
  relocationDays: undefined,
  improveReportDetails: [],
  personnel: '',
  auditStatus: undefined,
  opinion: ''
}

const formRef = ref<FormInstance>()
const formMode = ref<FormMode>('create')
const form = ref<EquipmentReportForm>({ ...defaultForm })
const formLoading = ref(false)
const detailLoading = ref(false)
const message = useMessage()
const { ZmTable, ZmTableColumn } = useTableComponents<ImproveReportDetail>()

const auditStatusMap = {
  0: { label: '未提交', type: 'info' },
  10: { label: '审批中', type: 'warning' },
  20: { label: '审核通过', type: 'success' },
  30: { label: '审核不通过', type: 'danger' },
  40: { label: '已取消', type: 'info' }
} as const

let detailKeySeed = 0

const rules: FormRules = {
  title: [{ required: true, message: '请输入标题', trigger: ['blur', 'change'] }],
  createTime: [{ required: true, message: '请选择汇报时间', trigger: ['blur', 'change'] }],
  workLocation: [{ required: true, message: '请输入工作地点', trigger: ['blur', 'change'] }],
  workPurpose: [{ required: true, message: '请输入施工目的', trigger: ['blur', 'change'] }],
  relocationDays: [{ required: true, message: '请输入安全作业天数', trigger: ['blur', 'change'] }],
  personnel: [{ required: true, message: '请输入人员情况', trigger: ['blur', 'change'] }]
}

const drawerTitle = computed(() => {
  const titleMap: Record<FormMode, string> = {
    create: '新建设备汇报',
    edit: '编辑设备汇报',
    detail: '查看设备汇报',
    approval: '审批设备汇报',
    modify: '修改设备汇报'
  }

  return titleMap[formMode.value]
})

const formDisabled = computed(() => formMode.value === 'detail')
const mainFieldDisabled = computed(
  () => formMode.value === 'detail' || formMode.value === 'approval'
)
const showAuditInfo = computed(() => formMode.value !== 'create')

function getAuditStatus(status?: number) {
  return auditStatusMap[status as keyof typeof auditStatusMap] || auditStatusMap[0]
}

function createDefaultDetail(): ImproveReportDetail {
  return {
    detailKey: createDetailKey(),
    projectName: '',
    constructionDetail: '',
    nextPlan: ''
  }
}

function createDetailKey() {
  detailKeySeed += 1
  return `detail-${Date.now()}-${detailKeySeed}`
}

function getDefaultDetails() {
  return [createDefaultDetail()]
}

function normalizeDetails(details?: ImproveReportDetail[]) {
  if (!Array.isArray(details) || !details.length) {
    return getDefaultDetails()
  }

  return details.map((item) => ({
    detailKey: item.detailKey || createDetailKey(),
    projectName: item.projectName || '',
    constructionDetail: item.constructionDetail || '',
    nextPlan: item.nextPlan || ''
  }))
}

function resolveDetailIndex(row: ImproveReportDetail) {
  const index = form.value.improveReportDetails.findIndex(
    (item) => item.detailKey === row.detailKey
  )
  return index >= 0 ? index : 0
}

function getDetailFieldProp(row: ImproveReportDetail, field: keyof ImproveReportDetail) {
  return `improveReportDetails.${resolveDetailIndex(row)}.${field}`
}

function getDetailRowKey(row: ImproveReportDetail) {
  return row.detailKey || ''
}

function getSubmitDetails(details: ImproveReportDetail[]) {
  return details.map(({ detailKey: _detailKey, ...item }) => item)
}

function toFormData(row?: any): EquipmentReportForm {
  if (!row) return { ...defaultForm, improveReportDetails: getDefaultDetails() }

  return {
    id: row.id,
    title: row.title,
    createTime: row.createTime,
    workLocation: row.workLocation,
    workPurpose: row.workPurpose,
    relocationDays: row.relocationDays,
    improveReportDetails: normalizeDetails(row.improveReportDetails),
    personnel: row.personnel,
    auditStatus: row.auditStatus,
    opinion: row.opinion || ''
  }
}

async function handleOpenForm(mode: FormMode = 'create', row?: any) {
  formMode.value = mode
  form.value =
    mode === 'create'
      ? { ...defaultForm, improveReportDetails: getDefaultDetails() }
      : toFormData(row)
  emits('update:visible', true)

  if (mode !== 'create' && row?.id) {
    detailLoading.value = true
    try {
      const detail = await IotRyImproveDailyReportApi.getIotRyImproveDailyReport(row.id)
      form.value = toFormData(detail)
    } finally {
      detailLoading.value = false
    }
  }

  nextTick(() => {
    formRef.value?.clearValidate()
  })
}

function handleCloseForm() {
  emits('update:visible', false)
}

function addImproveReportDetail() {
  form.value.improveReportDetails.push(createDefaultDetail())
}

function removeImproveReportDetail(row: ImproveReportDetail) {
  if (form.value.improveReportDetails.length <= 1) {
    return
  }

  form.value.improveReportDetails.splice(resolveDetailIndex(row), 1)
}

async function submitForm() {
  if (!formRef.value || formDisabled.value || formMode.value === 'approval') return

  try {
    formLoading.value = true
    await formRef.value.validate()

    const data = {
      ...form.value,
      createTime: Number(form.value.createTime),
      improveReportDetails: getSubmitDetails(form.value.improveReportDetails)
    }

    if (data.id) {
      await IotRyImproveDailyReportApi.updateIotRyImproveDailyReport({
        id: data.id,
        title: data.title,
        createTime: data.createTime,
        workLocation: data.workLocation,
        workPurpose: data.workPurpose,
        relocationDays: Number(data.relocationDays),
        personnel: data.personnel,
        improveReportDetails: data.improveReportDetails,
        ...(formMode.value === 'modify' ? { modifyFlag: 'Y' as const } : {})
      })
      message.success(formMode.value === 'modify' ? '修改成功' : '编辑成功')
      await props.loadList()
    } else {
      await IotRyImproveDailyReportApi.createIotRyImproveDailyReport({
        title: data.title,
        createTime: data.createTime,
        workLocation: data.workLocation,
        workPurpose: data.workPurpose,
        relocationDays: Number(data.relocationDays),
        personnel: data.personnel,
        improveReportDetails: data.improveReportDetails
      })
      message.success('新增成功')
      await (props.reloadAfterCreate ? props.reloadAfterCreate() : props.loadList())
    }

    handleCloseForm()
  } finally {
    formLoading.value = false
  }
}

async function submitApproval(auditStatus: 20 | 30) {
  if (!form.value.id) return

  try {
    formLoading.value = true
    await IotRyImproveDailyReportApi.approvalIotRyImproveDailyReport({
      id: form.value.id,
      auditStatus,
      opinion: form.value.opinion
    })
    message.success(auditStatus === 20 ? '审批通过' : '审批不通过')
    await props.loadList()
    handleCloseForm()
  } finally {
    formLoading.value = false
  }
}

defineExpose({ handleOpenForm })
</script>

<template>
  <el-drawer
    :model-value="visible"
    @update:model-value="emits('update:visible', $event)"
    header-class="mb-0!"
    :with-header="false"
    size="70%"
    :close-on-press-escape="false"
    :close-on-click-modal="false">
    <div class="size-full flex flex-col gap-4">
      <div class="flex justify-between items-center">
        <div class="flex items-center gap-4">
          <div class="text-xl font-bold text-gray-900 leading-tight">{{ drawerTitle }}</div>
          <template v-if="showAuditInfo">
            <el-tag :type="getAuditStatus(form.auditStatus).type">
              {{ getAuditStatus(form.auditStatus).label }}
            </el-tag>
          </template>
        </div>
        <el-button link @click="handleCloseForm">
          <el-icon size="24"><Close /></el-icon>
        </el-button>
      </div>

      <el-form
        ref="formRef"
        v-loading="detailLoading"
        size="default"
        label-position="top"
        :model="form"
        require-asterisk-position="right"
        class="flex flex-col"
        :rules="rules"
        :disabled="formDisabled">
        <div class="grid grid-cols-2 gap-x-8">
          <el-form-item class="col-span-2" label="标题" prop="title">
            <el-input
              v-model="form.title"
              clearable
              placeholder="请输入标题"
              :disabled="mainFieldDisabled" />
          </el-form-item>

          <el-form-item label="汇报时间" prop="createTime">
            <el-date-picker
              v-model="form.createTime"
              type="date"
              clearable
              class="w-full!"
              placeholder="请选择汇报时间"
              value-format="x"
              :disabled="mainFieldDisabled" />
          </el-form-item>

          <el-form-item label="工作地点" prop="workLocation">
            <el-input
              v-model="form.workLocation"
              clearable
              placeholder="请输入工作地点"
              :disabled="mainFieldDisabled" />
          </el-form-item>

          <el-form-item label="施工目的" prop="workPurpose">
            <el-input
              v-model="form.workPurpose"
              clearable
              placeholder="请输入施工目的"
              :disabled="mainFieldDisabled" />
          </el-form-item>

          <el-form-item label="安全作业天数" prop="relocationDays">
            <el-input-number
              v-model="form.relocationDays"
              :min="0"
              :controls="false"
              align="left"
              class="w-full!"
              placeholder="请输入安全作业天数"
              :disabled="mainFieldDisabled">
              <template #suffix>天</template>
            </el-input-number>
          </el-form-item>

          <el-form-item label="人员情况" prop="personnel">
            <el-input
              v-model="form.personnel"
              clearable
              placeholder="请输入人员情况"
              :disabled="mainFieldDisabled" />
          </el-form-item>

          <div class="col-span-2 detail-toolbar">
            <div class="text-base font-medium text-[var(--el-text-color-primary)]">
              施工动态明细
            </div>
            <el-button
              type="primary"
              plain
              :icon="Plus"
              @click="addImproveReportDetail"
              :disabled="mainFieldDisabled">
              新增明细
            </el-button>
          </div>

          <div class="col-span-2">
            <ZmTable
              :data="form.improveReportDetails"
              :loading="false"
              class="detail-table"
              :row-key="getDetailRowKey"
              :show-border="true"
              :show-overflow-tooltip="false">
              <ZmTableColumn label="项目名称" prop="projectName" :width="220">
                <template #default="{ row }">
                  <el-form-item
                    class="mb-0!"
                    :show-message="false"
                    :prop="getDetailFieldProp(row, 'projectName')"
                    :rules="{
                      required: true,
                      message: '请输入项目名称',
                      trigger: ['blur', 'change']
                    }">
                    <el-input
                      v-model="row.projectName"
                      clearable
                      placeholder="请输入项目名称"
                      :disabled="mainFieldDisabled" />
                  </el-form-item>
                </template>
              </ZmTableColumn>

              <ZmTableColumn label="施工动态" min-width="280">
                <template #default="{ row }">
                  <el-form-item
                    class="mb-0!"
                    :show-message="false"
                    :prop="getDetailFieldProp(row, 'constructionDetail')"
                    :rules="{
                      required: true,
                      message: '请输入施工动态',
                      trigger: ['blur', 'change']
                    }">
                    <el-input
                      v-model="row.constructionDetail"
                      type="textarea"
                      :autosize="{ minRows: 2, maxRows: 8 }"
                      resize="vertical"
                      :maxlength="1000"
                      placeholder="请输入施工动态"
                      :disabled="mainFieldDisabled" />
                  </el-form-item>
                </template>
              </ZmTableColumn>

              <ZmTableColumn label="下步计划" min-width="240">
                <template #default="{ row }">
                  <el-form-item
                    class="mb-0!"
                    :show-message="false"
                    :prop="getDetailFieldProp(row, 'nextPlan')"
                    :rules="{
                      required: true,
                      message: '请输入下步计划',
                      trigger: ['blur', 'change']
                    }">
                    <el-input
                      v-model="row.nextPlan"
                      type="textarea"
                      :autosize="{ minRows: 2, maxRows: 8 }"
                      resize="vertical"
                      :maxlength="1000"
                      placeholder="请输入下步计划"
                      :disabled="mainFieldDisabled" />
                  </el-form-item>
                </template>
              </ZmTableColumn>

              <ZmTableColumn label="操作" width="90" fixed="right">
                <template #default="{ row }">
                  <el-button
                    link
                    type="danger"
                    :icon="Delete"
                    @click="removeImproveReportDetail(row)"
                    :disabled="mainFieldDisabled || form.improveReportDetails.length <= 1">
                    删除
                  </el-button>
                </template>
              </ZmTableColumn>
            </ZmTable>
          </div>

          <el-form-item v-if="showAuditInfo" class="col-span-2" label="审批意见" prop="opinion">
            <el-input
              v-model="form.opinion"
              type="textarea"
              :autosize="{ minRows: 3 }"
              resize="none"
              show-word-limit
              :maxlength="1000"
              :placeholder="formMode === 'approval' ? '请输入审批意见' : '暂无审批意见'"
              :disabled="formMode !== 'approval'" />
          </el-form-item>
        </div>
      </el-form>
    </div>

    <template #footer>
      <el-button
        v-if="formMode === 'create' || formMode === 'edit' || formMode === 'modify'"
        size="default"
        type="primary"
        @click="submitForm"
        :loading="formLoading">
        确 定
      </el-button>
      <el-button
        v-if="formMode === 'approval'"
        size="default"
        type="success"
        @click="submitApproval(20)"
        :loading="formLoading">
        审批通过
      </el-button>
      <el-button
        v-if="formMode === 'approval'"
        size="default"
        type="danger"
        @click="submitApproval(30)"
        :loading="formLoading">
        审批不通过
      </el-button>
      <el-button size="default" @click="handleCloseForm">取 消</el-button>
    </template>
  </el-drawer>
</template>

<style scoped>
:deep(.el-form-item__label) {
  font-weight: 500;
}

.detail-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 8px;
  margin-bottom: 12px;
}

.detail-table :deep(.el-form-item) {
  width: 100%;
}

.detail-table :deep(.el-table__body .el-table__cell) {
  .cell {
    padding: 10px 8px;
  }
}
</style>
