<script setup lang="ts">
import { useTableComponents } from '@/components/ZmTable/useTableComponents'
import { IotMainWorkOrderApi, IotMainWorkOrderVO } from '@/api/pms/iotmainworkorder'
import { useUserStore } from '@/store/modules/user'
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
import download from '@/utils/download'
import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
import type { FormInstance } from 'element-plus'

defineOptions({ name: 'IotMainWorkOrder' })

type MainWorkOrderRow = IotMainWorkOrderVO & {
  mainDistance?: string | number | null
  updateTime?: string | null
  createTime?: string | null
}

interface QueryParams extends PageParam {
  planId?: number
  planSerialNumber?: string
  deptId?: number
  orderNumber?: string
  name?: string
  type?: number
  responsiblePerson?: string
  responsiblePersonName?: string
  cost?: number
  result?: string | number
  otherCost?: number
  laborCost?: number
  outsourcingFlag?: number
  actualStartTime?: string[]
  actualEndTime?: string[]
  remark?: string
  status?: number
  processInstanceId?: string
  auditStatus?: number
  createTime?: string[]
}

type DelayReasonButtonType = 'success' | 'warning'

const message = useMessage()
const { t } = useI18n()
const { push } = useRouter()
const { ZmTable, ZmTableColumn } = useTableComponents<MainWorkOrderRow>()

const userStore = useUserStore()
const rootDeptId = 156
const deptId = userStore.getUser.deptId || rootDeptId
const currentUserId = ref<number | undefined>(userStore.getUser.id)

const initQuery: QueryParams = {
  pageNo: 1,
  pageSize: 10,
  planId: undefined,
  planSerialNumber: undefined,
  deptId: undefined,
  orderNumber: undefined,
  name: undefined,
  type: undefined,
  responsiblePerson: undefined,
  responsiblePersonName: undefined,
  cost: undefined,
  result: undefined,
  otherCost: undefined,
  laborCost: undefined,
  outsourcingFlag: undefined,
  actualStartTime: [],
  actualEndTime: [],
  remark: undefined,
  status: undefined,
  processInstanceId: undefined,
  auditStatus: undefined,
  createTime: []
}

const queryParams = reactive<QueryParams>({ ...initQuery })
const queryFormRef = ref()
const loading = ref(false)
const exportLoading = ref(false)
const list = ref<MainWorkOrderRow[]>([])
const total = ref(0)

const delayReasonDialogVisible = ref(false)
const saveDelayReasonLoading = ref(false)
const delayReasonFormRef = ref<FormInstance>()
const delayReasonForm = reactive({
  id: undefined as number | undefined,
  delayReason: ''
})

const delayReasonRules = computed(() => ({
  delayReason: [
    {
      required: true,
      message: t('workOrderMaterial.inputDelayReason') || '请输入延时原因',
      trigger: 'blur'
    }
  ]
}))

const resultOptions = computed(() => [
  {
    label: t('operationFill.all'),
    value: '0'
  },
  {
    label: t('mainPlan.delayed'),
    value: '3'
  },
  ...getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT)
])

const getList = async () => {
  loading.value = true
  try {
    const data = await IotMainWorkOrderApi.sortedMainWorkOrderPage(queryParams)
    list.value = data.list
    total.value = data.total
  } finally {
    loading.value = false
  }
}

const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

const resetQuery = () => {
  Object.assign(queryParams, { ...initQuery })
  queryFormRef.value?.resetFields()
  handleQuery()
}

const handleSizeChange = (val: number) => {
  queryParams.pageSize = val
  handleQuery()
}

const handleCurrentChange = (val: number) => {
  queryParams.pageNo = val
  getList()
}

const handleDeptNodeClick = async (row: Tree) => {
  queryParams.deptId = row.id
  queryParams.pageNo = 1
  await getList()
}

const formatCellDate = (dateString?: string | null) => {
  if (!dateString) return ''
  return dateFormatter(null, null, dateString)
}

const parseDistanceNumber = (distance: number | string | null | undefined) => {
  if (distance === null || distance === undefined || distance === '') return undefined
  if (typeof distance === 'number') return distance
  const numericPart = distance.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/)?.[0]
  return numericPart ? Number(numericPart) : undefined
}

const isNegativeMainDistance = (mainDistance: number | string | null | undefined) => {
  const value = parseDistanceNumber(mainDistance)
  return value !== undefined && value < 0
}

const getDistanceClass = (distance: number | string | null | undefined) => {
  const value = parseDistanceNumber(distance)
  if (value === undefined || value === 0) return ''
  return value < 0 ? 'negative-distance' : 'positive-distance'
}

const getDelayReasonButtonType = (
  delayReason: string | null | undefined
): DelayReasonButtonType => {
  return delayReason ? 'success' : 'warning'
}

const openDelayReasonDialog = (row: MainWorkOrderRow) => {
  delayReasonForm.id = row.id
  delayReasonForm.delayReason = row.delayReason || ''
  delayReasonDialogVisible.value = true
}

const saveDelayReason = async () => {
  if (!delayReasonFormRef.value) return

  const valid = await delayReasonFormRef.value.validate()
  if (!valid) return

  if (!delayReasonForm.id) {
    message.error('ID不能为空')
    return
  }

  saveDelayReasonLoading.value = true
  try {
    await IotMainWorkOrderApi.updateIotMainWorkOrder({
      id: delayReasonForm.id,
      delayReason: delayReasonForm.delayReason
    } as IotMainWorkOrderVO)
    message.success(t('common.success') || '保存成功')
    delayReasonDialogVisible.value = false
    await getList()
  } catch (error) {
    console.error('保存延保原因失败:', error)
    message.error(t('sys.api.operationFailed') || '保存失败')
  } finally {
    saveDelayReasonLoading.value = false
  }
}

const handleBack = async (id: number) => {
  try {
    await message.confirm(
      '退回到提交人修改？',
      t('common.confirmTitle') || '确认',
      t('common.ok') || '确定',
      t('common.cancel') || '取消'
    )

    await IotMainWorkOrderApi.updateIotMainWorkOrder({
      id,
      backFlag: '1'
    } as unknown as IotMainWorkOrderVO)

    message.success(t('common.success') || '退回成功')
    await getList()
  } catch (error) {
    if (error?.toString().includes('cancel') || error?.toString().includes('取消')) return

    console.error('退回操作失败:', error)
    message.error(t('sys.api.operationFailed') || '退回失败')
  }
}

const openForm = (type: 'create' | 'update', id?: number) => {
  if (type === 'update' && typeof id === 'number') {
    push({ name: 'IotMainWorkOrderOptimize', params: { id } })
    return
  }

  push({ name: 'IotMainWorkOrderAdd', params: {} })
}

const openModifyForm = (type: 'modify', id?: number) => {
  if (type === 'modify' && typeof id === 'number') {
    push({ name: 'IotMainWorkOrderModify', params: { id } })
  }
}

const detail = (id?: number) => {
  push({ name: 'IotMainWorkOrderDetail', params: { id } })
}

const handleExport = async () => {
  exportLoading.value = true
  try {
    const data = await IotMainWorkOrderApi.exportIotMainWorkOrderIndex(queryParams)
    download.excel(data, '保养工单.xls')
  } finally {
    exportLoading.value = false
  }
}

onMounted(() => {
  getList()
})
</script>

<template>
  <div
    class="main-work-order-page grid grid-cols-[auto_1fr] grid-rows-[auto_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]">
    <DeptTreeSelect
      :top-id="rootDeptId"
      :deptId="deptId"
      v-model="queryParams.deptId"
      :init-select="false"
      :show-title="false"
      request-api="getSimpleDeptList"
      class="main-work-order-tree row-span-2"
      @node-click="handleDeptNodeClick" />

    <el-form
      ref="queryFormRef"
      :model="queryParams"
      size="default"
      label-width="68px"
      class="main-work-order-query bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-6 py-3 min-w-0">
      <div class="query-row">
        <el-form-item :label="t('bomList.name')" prop="name">
          <el-input
            v-model="queryParams.name"
            :placeholder="t('bomList.nHolder')"
            clearable
            class="query-control"
            @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item :label="t('bomList.status')" prop="result">
          <el-select
            v-model="queryParams.result"
            :placeholder="t('bomList.status')"
            clearable
            class="query-control query-control--small">
            <el-option
              v-for="dict in resultOptions"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value" />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('common.createTime')" prop="createTime" label-width="100px">
          <el-date-picker
            v-model="queryParams.createTime"
            value-format="YYYY-MM-DD HH:mm:ss"
            type="daterange"
            :start-placeholder="t('operationFill.start')"
            :end-placeholder="t('operationFill.end')"
            :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
            class="query-control query-control--date" />
        </el-form-item>
      </div>

      <el-form-item class="query-actions">
        <el-button type="primary" @click="handleQuery">
          <Icon icon="ep:search" class="mr-5px" />{{ t('operationFill.search') }}
        </el-button>
        <el-button @click="resetQuery">
          <Icon icon="ep:refresh" class="mr-5px" />{{ t('operationFill.reset') }}
        </el-button>
        <el-button
          type="primary"
          plain
          @click="openForm('create')"
          v-hasPermi="['pms:iot-main-work-order:create']">
          <Icon icon="ep:plus" class="mr-5px" />{{ t('operationFill.add') }}
        </el-button>
        <el-button
          type="success"
          plain
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['pms:iot-main-work-order:export']">
          <Icon icon="ep:download" class="mr-5px" />导出
        </el-button>
      </el-form-item>
    </el-form>

    <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg flex flex-col p-4 min-w-0 min-h-0">
      <div class="flex-1 relative min-h-0">
        <el-auto-resizer class="absolute">
          <template #default="{ width, height }">
            <ZmTable
              :data="list"
              :loading="loading"
              :width="width"
              :height="height"
              :max-height="height"
              show-border>
              <ZmTableColumn
                type="index"
                :label="t('iotDevice.serial')"
                :width="70"
                fixed="left"
                hide-in-column-settings />
              <ZmTableColumn prop="name" :label="t('bomList.name')" fixed="left" min-width="300" />
              <ZmTableColumn prop="deptName" :label="t('iotDevice.dept')" min-width="150" />
              <ZmTableColumn prop="result" :label="t('bomList.status')" width="120">
                <template #default="{ row }">
                  <dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT" :value="row.result" />
                </template>
              </ZmTableColumn>
              <ZmTableColumn :label="t('bomList.serviceDue')" min-width="150">
                <template #default="{ row }">
                  <span :class="getDistanceClass(row.mainDistance)">
                    {{ row.mainDistance }}
                  </span>
                </template>
              </ZmTableColumn>
              <ZmTableColumn prop="type" :label="t('bomList.type')" width="120">
                <template #default="{ row }">
                  <dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_TYPE" :value="row.type" />
                </template>
              </ZmTableColumn>
              <ZmTableColumn
                prop="responsiblePersonName"
                :label="t('iotMaintain.PersonInCharge')"
                min-width="150" />
              <ZmTableColumn
                prop="createTime"
                :label="t('dict.createTime')"
                :formatter="dateFormatter2"
                width="180" />
              <ZmTableColumn prop="updateTime" :label="t('dict.fillTime')" width="180">
                <template #default="{ row }">
                  <span v-if="row.result == 2">{{ formatCellDate(row.updateTime) }}</span>
                </template>
              </ZmTableColumn>
              <ZmTableColumn prop="applicant" label="填报人" />
              <ZmTableColumn :label="t('iotMaintain.operation')" width="140" fixed="right" action>
                <template #default="{ row }">
                  <el-button
                    v-if="isNegativeMainDistance(row.mainDistance)"
                    link
                    :type="getDelayReasonButtonType(row.delayReason)"
                    @click="openDelayReasonDialog(row)"
                    v-hasPermi="['pms:iot-main-work-order:update']">
                    {{ t('mainPlan.delayed') || '延时' }}
                  </el-button>
                  <el-button
                    v-if="row.result === 1"
                    link
                    type="primary"
                    @click="openForm('update', row.id)"
                    v-hasPermi="['pms:iot-main-work-order:update']">
                    {{ t('operationFill.fill') }}
                  </el-button>
                  <el-button
                    link
                    type="primary"
                    @click="detail(row.id)"
                    v-hasPermi="['pms:iot-main-work-order:query']">
                    {{ t('operationFill.view') }}
                  </el-button>
                  <el-button
                    v-if="row.result === 2 && row.status === 0"
                    link
                    type="danger"
                    @click="handleBack(row.id)"
                    v-hasPermi="['pms:iot-main-work-order:back']">
                    {{ t('workOrderMaterial.back') }}
                  </el-button>
                  <el-button
                    v-if="
                      row.result === 2 &&
                      row.status === 1 &&
                      currentUserId?.toString() === row.responsiblePerson
                    "
                    link
                    type="warning"
                    class="warning-btn"
                    @click="openModifyForm('modify', row.id)"
                    v-hasPermi="['pms:iot-main-work-order:update']">
                    {{ t('modelTemplate.update') }}
                  </el-button>
                </template>
              </ZmTableColumn>
            </ZmTable>
          </template>
        </el-auto-resizer>
      </div>

      <div class="h-8 mt-2 flex items-center justify-end">
        <el-pagination
          v-show="total > 0"
          size="default"
          :current-page="queryParams.pageNo"
          :page-size="queryParams.pageSize"
          :background="true"
          :page-sizes="[10, 20, 30, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange" />
      </div>
    </div>
  </div>

  <el-dialog
    v-model="delayReasonDialogVisible"
    :title="t('workOrderMaterial.delayReason') || '延时原因'"
    width="500px"
    :close-on-click-modal="false">
    <el-form
      ref="delayReasonFormRef"
      :model="delayReasonForm"
      :rules="delayReasonRules"
      label-width="0px">
      <el-form-item label=" " prop="delayReason" class="required-item" label-width="16px">
        <el-input
          v-model="delayReasonForm.delayReason"
          type="textarea"
          :rows="4"
          :placeholder="t('workOrderMaterial.inputDelayReason') || '请输入延时原因'"
          maxlength="500"
          show-word-limit />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="delayReasonDialogVisible = false">
        {{ t('common.cancel') || '取消' }}
      </el-button>
      <el-button type="primary" :loading="saveDelayReasonLoading" @click="saveDelayReason">
        {{ t('common.save') || '保存' }}
      </el-button>
    </template>
  </el-dialog>
</template>

<style scoped>
.main-work-order-query {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
}

.query-row {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 24px;
  min-width: 0;
}

.query-actions {
  flex: 0 0 auto;
}

.query-actions :deep(.el-form-item__content) {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
}

.query-actions :deep(.el-button) {
  margin-left: 0;
}

.query-control {
  width: 220px;
}

.query-control--small {
  width: 160px;
}

.query-control--date {
  width: 240px;
}

.positive-distance {
  display: inline-block;
  padding: 2px 8px;
  color: #67c23a;
  background-color: rgb(103 194 58 / 10%);
  border-radius: 4px;
}

.negative-distance {
  display: inline-block;
  padding: 2px 8px;
  color: #f56c6c;
  background-color: rgb(245 108 108 / 10%);
  border-radius: 4px;
}

:deep(.required-item .el-form-item__label::before) {
  margin-right: 2px;
  color: #ff4d4f;
  content: '*';
}

:deep(.required-item .el-form-item__label) {
  padding-right: 0 !important;
}

:deep(.el-form-item) {
  margin-bottom: 0;
}

@media (width >= 2200px) {
  .main-work-order-query,
  .query-row {
    flex-wrap: nowrap;
  }
}

@media (width <= 1500px) {
  .main-work-order-query,
  .query-row {
    gap: 12px 18px;
  }

  .query-control {
    width: 200px;
  }

  .query-control--small {
    width: 150px;
  }

  .query-control--date {
    width: 220px;
  }
}

@media (width <= 1200px) {
  .main-work-order-page {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto minmax(480px, 1fr);
    height: auto;
    min-height: calc(
      100vh - 20px - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height)
    );
  }

  :deep(.main-work-order-tree) {
    grid-row: auto !important;
    width: 100% !important;
    height: 320px !important;
    min-width: 0 !important;
  }

  .query-actions {
    width: 100%;
  }
}

@media (width <= 768px) {
  .main-work-order-query {
    padding: 12px;
  }

  .query-row,
  .query-row :deep(.el-form-item),
  .query-actions {
    width: 100%;
  }

  .query-control,
  .query-control--small,
  .query-control--date {
    width: 100%;
  }

  .query-actions :deep(.el-form-item__content) {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    width: 100%;
  }

  .query-actions :deep(.el-button) {
    width: 100%;
    margin-left: 0;
  }
}
</style>
