<script setup lang="ts">
import { FormInstance, FormRules } from 'element-plus'
import { Close } from '@element-plus/icons-vue'
import * as UserApi from '@/api/system/user'
import { useUserStore } from '@/store/modules/user'
import { getStrDictOptions } from '@/utils/dict'
import * as DeptApi from '@/api/system/dept'
import { IotRdDailyReportApi } from '@/api/pms/iotrddailyreport'
import { formatT } from '@/utils/formatTime'
import { defaultProps, handleTree } from '@/utils/tree'

const user = useUserStore().getUser

const deptId = user.deptId

interface Props {
  visible: boolean
  loadList: () => void
  isview: 'detail' | 'create' | 'time'
  id?: number
}

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

const emits = defineEmits(['update:visible'])

const NON_PROD_FIELDS = [
  { key: 'repairTime', label: '设备故障' },
  { key: 'selfStopTime', label: '设备保养' },
  { key: 'accidentTime', label: '工程质量' },
  { key: 'complexityTime', label: '技术受限' },
  { key: 'rectificationTime', label: '生产组织' },
  { key: 'waitingStopTime', label: '不可抗力' },
  { key: 'partyaDesign', label: '甲方设计' },
  { key: 'partyaPrepare', label: '甲方准备' },
  { key: 'partyaResource', label: '甲方资源' },
  { key: 'relocationTime', label: '生产配合' },
  { key: 'winterBreakTime', label: '待命' },
  { key: 'otherNptTime', label: '其他非生产时间' }
]

interface Form {
  deptId: number
  location: string
  responsiblePerson: number
  timeRange: string[]
  rdStatus: string
  dailyFuel: number
  productionStatus: string
  nextPlan: string
  externalRental: string
  malfunction: string
  otherNptReason: string
  createTime: number
  constructionBrief: string
  [key: (typeof NON_PROD_FIELDS)[number]['key']]: any
}

const original = {
  timeRange: ['08:00', '08:00'],
  ...NON_PROD_FIELDS.reduce((acc, field) => ({ ...acc, [field.key]: 0 }), {}),
  winterBreakTime: 24
}

const formRef = ref<FormInstance>()

const form = ref<Partial<Form>>({ ...original })

function noProductionTimeRule() {
  return {
    validator: (_rule: any, _value: any, callback: any) => {
      let totalTime = 0
      NON_PROD_FIELDS.forEach((field) => {
        const val = parseFloat(form.value[field.key])
        if (!isNaN(val)) {
          totalTime += val
        }
      })
      const fixedTotal = Number(totalTime.toFixed(2))
      if (fixedTotal > 24) {
        callback(new Error(`总时间(${fixedTotal}h)不能超过 24 小时`))
      } else {
        callback()
      }
    },
    trigger: 'blur'
  }
}

function handleRowValidate(key: string) {
  if (!formRef.value) return

  const propsToValidate = NON_PROD_FIELDS.map((field) => field.key)

  if (key === 'otherNptTime') propsToValidate.push('otherNptReason')

  formRef.value.validateField(propsToValidate)
}

const rules: FormRules = {
  deptId: [{ required: true, message: '请选择施工队伍', trigger: ['blur', 'change'] }],
  createTime: [{ required: true, message: '请选择施工日期', trigger: ['blur', 'change'] }],
  constructionBrief: [{ required: true, message: '请输入施工简报', trigger: ['blur', 'change'] }],
  timeRange: [
    { required: true, message: '请选择时间节点', trigger: ['blur', 'change'], type: 'array' }
  ],
  location: [{ required: true, message: '请输入施工地点', trigger: ['blur', 'change'] }],
  responsiblePerson: [
    { required: true, message: '请选择带班干部', trigger: ['blur', 'change'], type: 'array' }
  ],
  rdStatus: [{ required: true, message: '请选择施工状态', trigger: ['blur', 'change'] }],
  dailyFuel: [{ required: true, message: '请输入当日油耗', trigger: ['blur', 'change'] }],
  productionStatus: [{ required: true, message: '请输入生产状态', trigger: ['blur', 'change'] }],
  nextPlan: [{ required: true, message: '请输入下计划', trigger: ['blur', 'change'] }]
}

interface UserOptions {
  label: string
  value: number
  raw: any
  disabled: boolean
}

const userOptions = ref<UserOptions[]>([])

const deptLoading = ref(false)
const deptOptions = ref<any[]>([])

const submitterNames = ref('')

async function loadDept() {
  deptLoading.value = true
  try {
    function sortTreeBySort(treeNodes: Tree[]) {
      if (!treeNodes || !Array.isArray(treeNodes)) return treeNodes
      const sortedNodes = [...treeNodes].sort((a, b) => {
        const sortA = a.sort != null ? a.sort : 999999
        const sortB = b.sort != null ? b.sort : 999999
        return sortA - sortB
      })

      sortedNodes.forEach((node) => {
        node.disabled = (node as any).type !== '3'
        if (node.children && Array.isArray(node.children)) {
          node.children = sortTreeBySort(node.children)
        }
      })
      return sortedNodes
    }

    const depts = await DeptApi.specifiedSimpleDepts(deptId)
    deptOptions.value = sortTreeBySort(handleTree(depts))
  } catch (error) {
  } finally {
    deptLoading.value = false
  }
}

async function loadUserOptions() {
  const res = await UserApi.selectedDeptsEmployee({ deptIds: [deptId] })
  userOptions.value = res.map((item: any) => ({
    label: item.nickname,
    value: item.id,
    raw: item
  }))
}

const loading = ref(false)

const detail = ref<any>()

async function load() {
  loading.value = true

  await loadUserOptions()
  await loadDept()

  submitterNames.value = user.nickname

  if (props.isview && props.id) {
    const res = await IotRdDailyReportApi.getIotRdDailyReport(props.id)
    detail.value = res
    submitterNames.value = res.submitterNames
    form.value = {
      deptId: res.deptId,
      location: res.location,
      responsiblePerson: res.responsiblePerson,
      timeRange: [formatT(res.startTime), formatT(res.endTime)],
      rdStatus: res.rdStatus,
      dailyFuel: res.dailyFuel,
      productionStatus: res.productionStatus,
      nextPlan: res.nextPlan,
      externalRental: res.externalRental,
      malfunction: res.malfunction,
      otherNptReason: res.otherNptReason,
      createTime: res.createTime,
      constructionBrief: res.constructionBrief,
      ...NON_PROD_FIELDS.reduce((acc, field) => ({ ...acc, [field.key]: res[field.key] }), {})
    }
  }

  loading.value = false
}

const rdStatusOptions = getStrDictOptions(DICT_TYPE.PMS_PROJECT_RD_STATUS)

function handleOpenForm() {
  form.value = { ...original }
  load()
  emits('update:visible', true)
}

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

defineExpose({ handleOpenForm })

const formLoading = ref(false)

const message = useMessage()

async function submitForm() {
  if (!formRef.value) return

  try {
    formLoading.value = true
    await formRef.value.validate()
    const { timeRange, ...rest } = form.value
    const data: any = { ...rest, startTime: timeRange?.[0], endTime: timeRange?.[1] }

    if (props.id) {
      data.id = props.id
    }
    await IotRdDailyReportApi.createIotRdDailyReport(data)

    if (props.id) message.success('更新成功')
    else message.success('新增成功')
    handleCloseForm()
    props.loadList()
  } catch (error) {
    console.log('error :>> ', error)
  } finally {
    formLoading.value = false
  }
}

const disabled = computed(() => {
  if (props.isview !== 'create') {
    if (props.isview === 'time') {
      return !(detail.value?.contractName === null && detail.value?.taskName === null)
    }

    return true
  }

  return false
})
</script>

<template>
  <el-drawer
    :model-value="visible"
    @update:model-value="emits('update:visible', $event)"
    header-class="mb-0!"
    :with-header="false"
    size="50%"
    :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="text-xl font-bold text-gray-900 leading-tight"> 新建日报 </div>
        <el-button link @click="handleCloseForm">
          <el-icon size="24"><Close /></el-icon>
        </el-button>
      </div>
      <el-form
        ref="formRef"
        size="default"
        label-position="top"
        :model="form"
        require-asterisk-position="right"
        class="flex flex-col"
        :rules="rules"
        :loading="loading"
        :disabled="disabled"
      >
        <div class="grid grid-cols-2 gap-x-8">
          <el-form-item label="施工队伍" prop="deptId">
            <el-tree-select
              v-model="form.deptId"
              :data="deptOptions"
              :props="defaultProps"
              check-strictly
              node-key="id"
              filterable
              class="w-full"
              placeholder="请选择施工队伍"
            />
          </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"
            />
          </el-form-item>
          <el-form-item label="施工地点" prop="location">
            <el-input v-model="form.location" clearable placeholder="请输入施工地点" />
          </el-form-item>
          <el-form-item label="带班干部" prop="responsiblePerson">
            <el-select
              v-model="form.responsiblePerson"
              multiple
              :options="userOptions"
              clearable
              filterable
              collapse-tags
              collapse-tags-tooltip
              :max-collapse-tags="5"
              tag-type="primary"
              placeholder="请选择带班干部"
            />
          </el-form-item>
          <el-form-item label="填报人" prop="submitterNames"> {{ submitterNames }} </el-form-item>
          <el-form-item label="时间节点" prop="timeRange">
            <el-time-picker
              v-model="form.timeRange"
              is-range
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              placeholder="选择时间范围"
              clearable
              format="HH:mm"
              value-format="HH:mm"
            />
          </el-form-item>
          <el-form-item label="施工状态" prop="rdStatus">
            <el-select
              v-model="form.rdStatus"
              :options="rdStatusOptions"
              placeholder="请选择"
              class="w-full"
              clearable
            />
          </el-form-item>
          <el-form-item label="当日油耗(L)" prop="dailyFuel">
            <el-input-number
              v-model="form.dailyFuel"
              :min="0"
              :controls="false"
              align="left"
              class="w-full!"
              placeholder="请输入当日油耗"
            >
              <template #suffix>升（L）</template>
            </el-input-number>
          </el-form-item>
          <el-form-item label="当日生产动态" prop="productionStatus">
            <el-input
              v-model="form.productionStatus"
              type="textarea"
              :autosize="{ minRows: 2 }"
              resize="none"
              show-word-limit
              :maxlength="1000"
              placeholder="请输入外组设备"
            />
          </el-form-item>
          <el-form-item label="下步工作计划" prop="nextPlan">
            <el-input
              v-model="form.nextPlan"
              type="textarea"
              :autosize="{ minRows: 2 }"
              resize="none"
              show-word-limit
              :maxlength="1000"
              placeholder="请输入下步工作计划"
            />
          </el-form-item>

          <el-form-item label="外租设备" prop="externalRental">
            <el-input
              v-model="form.externalRental"
              type="textarea"
              :autosize="{ minRows: 2 }"
              resize="none"
              show-word-limit
              :maxlength="1000"
              placeholder="请输入外组设备"
            />
          </el-form-item>
          <el-form-item label="故障情况" prop="malfunction">
            <el-input
              v-model="form.malfunction"
              type="textarea"
              :autosize="{ minRows: 2 }"
              show-word-limit
              resize="none"
              :maxlength="1000"
              placeholder="请输入故障情况"
            />
          </el-form-item>
          <el-form-item class="col-span-2" label="施工简报" prop="constructionBrief">
            <el-input
              v-model="form.constructionBrief"
              type="textarea"
              :autosize="{ minRows: 2 }"
              show-word-limit
              resize="none"
              :maxlength="1000"
              placeholder="请输入施工简报"
            />
          </el-form-item>
        </div>
        <el-divider class="m-0! mb-3! border-2! border-[var(--el-color-primary)]!" />
        <h3 class="text-lg font-bold text-gray-800 mb-6 flex items-center gap-2">
          <div class="w-1 h-4 bg-blue-600 rounded-full"></div>
          非生产时间
        </h3>
        <div class="grid grid-cols-4 gap-x-8">
          <el-form-item
            v-for="field in NON_PROD_FIELDS"
            :key="field.key"
            :label="field.label"
            :prop="field.key"
            :rules="noProductionTimeRule()"
          >
            <el-input-number
              v-model="form[field.key]"
              :min="0"
              :max="24"
              :controls="false"
              class="w-full!"
              align="left"
              @blur="handleRowValidate(field.key)"
              :disabled="isview === 'detail'"
            >
              <template #suffix>小时（H）</template>
            </el-input-number>
          </el-form-item>

          <el-form-item
            class="col-span-4"
            label="其他非生产原因"
            prop="otherNptReason"
            :rules="{
              required: form.otherNptTime > 0,
              message: '请填写原因',
              trigger: ['blur', 'change']
            }"
          >
            <el-input
              v-model="form.otherNptReason"
              type="textarea"
              :autosize="{ minRows: 2 }"
              resize="none"
              show-word-limit
              :maxlength="1000"
              placeholder="当'其他非生产时间'大于0时必填"
              :disabled="isview === 'detail'"
            />
          </el-form-item>
        </div>
      </el-form>
    </div>
    <template #footer>
      <el-button
        :disabled="isview === 'detail'"
        size="default"
        type="primary"
        @click="submitForm"
        :loading="formLoading"
      >
        确 定
      </el-button>
      <el-button size="default" @click="emits('update:visible', false)">取 消</el-button>
    </template>
  </el-drawer>
</template>

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