<template>
  <div class="dv-repair-panel">
    <div class="dv-repair-panel__header">
      <div class="dv-repair-panel__title">{{ dialogTitle }}</div>
      <el-button text @click="closeForm">
        <Icon icon="ep:close" />
      </el-button>
    </div>
    <div class="dv-repair-dialog" v-loading="formLoading">
      <el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px">
        <section class="dv-repair-section">
          <div class="dv-repair-section__title">基本信息</div>
          <el-row :gutter="20">
            <el-col :span="8">
              <el-form-item :label="t('MoldManagement.MoldRepair.repairCode')" prop="repairCode">
                <template #label>
                  <span>
                    {{ t('MoldManagement.MoldRepair.repairCode') }}
                    <el-tooltip :content="t('MoldManagement.MoldRepair.repairCode')" placement="top">
                      <Icon icon="ep:question-filled" />
                    </el-tooltip>
                  </span>
                </template>
                <div class="dv-repair-code-row">
                  <el-input
                    :disabled="formData.isCode == true || formType === 'update'"
                    v-model="formData.repairCode"
                    :placeholder="t('common.code')"
                  />
                  <el-switch
                    v-model="formData.isCode"
                    :disabled="formType === 'update'"
                  />
                </div>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item :label="t('MoldManagement.MoldRepair.repairName')" prop="repairName">
                <el-input
                  v-model="formData.repairName"
                  :placeholder="t('MoldManagement.MoldRepair.placeholderRepairName')"
                  :disabled="isRepairMode"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item :label="t('MoldManagement.MoldRepair.mold')" prop="moldId">
                <el-select
                  v-model="formData.moldId" filterable clearable :loading="moldLoading"
                  :disabled="isRepairMode"
                  :placeholder="t('MoldManagement.MoldRepair.placeholderMold')"
                  class="!w-full"
                >
                  <el-option v-for="opt in moldOptions" :key="String(opt.value)" :label="opt.label" :value="opt.value" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="8">
              <el-form-item :label="t('MoldManagement.MoldRepair.moldName')" prop="moldName" :required="false">
                <el-input v-model="formData.moldName" :placeholder="t('MoldManagement.MoldRepair.placeholderMoldNameAuto')" disabled />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item :label="t('MoldManagement.MoldRepair.moldCode')" prop="moldCode" :required="false">
                <el-input v-model="formData.moldCode" :placeholder="t('MoldManagement.MoldRepair.placeholderMoldCodeAuto')" disabled />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="8">
              <el-form-item :label="t('MoldManagement.MoldRepair.repairUser')" prop="acceptedBy">
                <el-select
                  v-model="formData.acceptedBy" filterable clearable
                  :placeholder="t('MoldManagement.MoldRepair.placeholderAcceptUser')"
                  class="!w-full"
                  :disabled="isRepairMode">
                  <el-option v-for="item in users" :key="String(item.id)" :label="item.nickname" :value="String(item.id)" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item :label="t('MoldManagement.MoldRepair.confirmUser')" prop="confirmBy">
                <el-select
                  v-model="formData.confirmBy" filterable clearable
                  :placeholder="t('MoldManagement.MoldRepair.placeholderConfirmUser')"
                  class="!w-full"
                  :disabled="isRepairMode">
                  <el-option v-for="item in users" :key="String(item.id)" :label="item.nickname" :value="String(item.id)" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
        </section>

        <section v-if="showRepairFields" class="dv-repair-section">
          <div class="dv-repair-section__title">处理结果</div>
          <el-row :gutter="20">
            <el-col :span="8">
              <el-form-item :label="t('MoldManagement.MoldRepair.requireDate')" prop="requireDate">
                <el-date-picker
                  v-model="formData.requireDate" type="date" value-format="x"
                  :placeholder="t('MoldManagement.MoldRepair.placeholderRequireDate')"
                  class="!w-full" :disabled="repairFieldsDisabled"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item :label="t('MoldManagement.MoldRepair.finishDate')" prop="finishDate">
                <el-date-picker
                  v-model="formData.finishDate" type="date" value-format="x"
                  :placeholder="t('MoldManagement.MoldRepair.placeholderFinishDate')"
                  class="!w-full" :disabled="repairFieldsDisabled"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item :label="t('MoldManagement.MoldRepair.confirmDate')" prop="confirmDate">
                <el-date-picker
                  v-model="formData.confirmDate" type="date" value-format="x"
                  :placeholder="t('MoldManagement.MoldRepair.placeholderConfirmDate')"
                  class="!w-full" :disabled="repairFieldsDisabled"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="24">
              <el-form-item :label="t('MoldManagement.MoldRepair.repairResult')" prop="repairResult">
                <Editor v-model="formData.repairResult" height="150px" :readonly="repairFieldsDisabled" />
              </el-form-item>
            </el-col>
          </el-row>
        </section>
      </el-form>

      <el-tabs v-model="subTabsName" style="margin-top: 16px;">
        <el-tab-pane :label="t('MoldManagement.MoldRepair.tabMoldRepairLine')" name="moldRepairLine">
          <MoldRepairLineForm ref="moldRepairLineFormRef" :repair-id="formData.id" :line-mode="lineMode" />
        </el-tab-pane>
      </el-tabs>
    </div>

    <div class="dv-repair-footer">
      <el-button @click="closeForm">{{ t('common.cancel') }}</el-button>
      <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('common.ok') }}</el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { MoldRepairApi, MoldRepairVO } from '@/api/mold/moldrepair'
import { MoldRepairItemsApi } from '@/api/mold/moldRepairItems'
import MoldRepairLineForm from './components/MoldRepairLineForm.vue'
import { MoldBrandApi, MoldVO } from '@/api/erp/mold'
import { getSimpleUserList, UserVO } from '@/api/system/user'

defineOptions({ name: 'MoldRepairForm' })

const { t } = useI18n()
const message = useMessage()

const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref('')
const isRepairMode = computed(() => formType.value === 'update' || formType.value === 'repair')
const showRepairFields = computed(() => formType.value === 'update' || formType.value === 'repair')
const repairFieldsDisabled = computed(() => formType.value !== 'repair')
const isHydrating = ref(false)
const openRequestId = ref(0)
const emit = defineEmits(['success', 'closed'])
const formData = ref({
  id: undefined,
  repairCode: undefined,
  repairName: undefined,
  moldId: undefined as number | undefined,
  moldCode: undefined,
  moldName: undefined,
  machineryBrand: undefined,
  machinerySpec: undefined,
  requireDate: undefined,
  finishDate: undefined,
  confirmDate: undefined,
  repairResult: '',
  acceptedBy: undefined,
  confirmBy: undefined,
  status: undefined,
  remark: undefined,
  isCode: undefined
})

const moldLoading = ref(false)
const moldOptions = ref<{ label: string; value: number; raw?: MoldVO }[]>([])
const moldOptionsLoaded = ref(false)

const lineMode = computed(() => {
  if (formType.value === 'repair') return 'repair' as const
  if (formType.value === 'update') {
    const v = formData.value.status === '' || formData.value.status === null || formData.value.status === undefined
      ? undefined
      : String(formData.value.status)
    if (v === '1') return 'readonlyWithResult' as const
  }
  return 'edit' as const
})

const users = ref<UserVO[]>([])

const ensureUsersLoaded = async () => {
  if (users.value.length) return
  users.value = (await getSimpleUserList()) ?? []
}

const normalizeUserId = (value: any) => {
  if (value === undefined || value === null || value === '') return undefined
  const str = String(value)
  if (/^\d+$/.test(str)) return str
  const matched = users.value.find((u) => u.nickname === str)
  return matched ? String(matched.id) : str
}

const upsertMoldOption = (
  options: { label: string; value: number; raw?: MoldVO }[],
  option: { label: string; value: number; raw?: MoldVO }
) => {
  const existed = options.some((o) => o.value === option.value)
  return existed ? options : [option, ...options]
}

const toMoldOption = (item: any) => {
  const id = typeof item?.id === 'number' ? item.id : Number(item?.id)
  if (Number.isNaN(id)) return undefined
  const code = item?.code ?? item?.moldCode
  const name = item?.name ?? item?.moldName
  const label = `${code ?? ''} ${name ?? ''}`.trim() || String(id)
  return { label, value: id, raw: item as MoldVO }
}

const ensureMoldOptionsLoaded = async () => {
  if (moldOptionsLoaded.value) return
  moldLoading.value = true
  try {
    const data = await MoldBrandApi.getMoldPageWithoutPaging()
    const rows = (Array.isArray(data) ? data : data?.list ?? data?.data ?? []) as any[]
    moldOptions.value = rows.map(toMoldOption).filter(Boolean) as { label: string; value: number; raw?: MoldVO }[]
    moldOptionsLoaded.value = true
  } finally {
    moldLoading.value = false
  }
}

watch(
  () => formData.value.moldId,
  async (moldId) => {
    if (isHydrating.value) return
    if (typeof moldId !== 'number') {
      formData.value.moldCode = undefined
      formData.value.moldName = undefined
      formData.value.machinerySpec = undefined
      formData.value.machineryBrand = undefined
      if (formType.value === 'create') setLineRows([])
      return
    }

    const option = moldOptions.value.find((o) => o.value === moldId)
    if (option?.raw) {
      const raw: any = option.raw
      const code = raw?.code ?? raw?.moldCode
      const name = raw?.name ?? raw?.moldName
      formData.value.moldCode = code
      formData.value.moldName = name
      formData.value.machinerySpec = raw?.moldType ?? raw?.spec ?? raw?.moldSpec
      formData.value.machineryBrand = raw?.brandName ?? raw?.brand ?? raw?.moldBrand
    }

    await prefillLinesByMold(moldId as number)
  }
)
const formRules = reactive({
  repairCode: [
    {
      validator: (_: any, value: any, callback: any) => {
        if (formType.value === 'update') {
          callback()
          return
        }
        if (formData.value.isCode === true) {
          callback()
          return
        }
        if (value === undefined || value === null || String(value).trim() === '') {
          callback(new Error(t('MoldManagement.MoldRepair.validatorRepairCodeRequired')))
          return
        }
        callback()
      },
      trigger: 'blur',
    },
  ],
  repairName: [],
  moldId: [{ required: true, message: t('MoldManagement.MoldRepair.validatorMoldRequired'), trigger: 'change' }],
  requireDate: [
    {
      validator: (_: any, value: any, callback: any) => {
        if (formType.value === 'repair' && !value) {
          callback(new Error(t('MoldManagement.MoldRepair.validatorRequireDateRequired')))
          return
        }
        callback()
      },
      trigger: 'change',
    },
  ],
  finishDate: [
    {
      validator: (_: any, value: any, callback: any) => {
        if (formType.value === 'repair' && !value) {
          callback(new Error(t('MoldManagement.MoldRepair.validatorFinishDateRequired')))
          return
        }
        callback()
      },
      trigger: 'change',
    },
  ],
  confirmDate: [
    {
      validator: (_: any, value: any, callback: any) => {
        if (formType.value === 'repair' && !value) {
          callback(new Error(t('MoldManagement.MoldRepair.validatorConfirmDateRequired')))
          return
        }
        callback()
      },
      trigger: 'change',
    },
  ],
  repairResult: [
    {
      validator: (_: any, value: any, callback: any) => {
        if (formType.value === 'repair' && !value) {
          callback(new Error(t('MoldManagement.MoldRepair.validatorRepairResultRequired')))
          return
        }
        callback()
      },
      trigger: 'blur',
    },
  ],
})
const formRef = ref()

const subTabsName = ref('moldRepairLine')
const moldRepairLineFormRef = ref()

watch(
  () => formData.value.isCode,
  (val) => {
    if (val === true) {
      formData.value.repairCode = undefined
    }
    formRef.value?.clearValidate?.(['repairCode'])
  }
)

const setLineRows = (rows: any[]) => {
  moldRepairLineFormRef.value?.setData(rows)
}

const normalizeMoldRepairItemList = (data: any) => {
  const rows = (Array.isArray(data) ? data : data?.list ?? data?.data ?? []) as any[]
  return rows
}

const toMoldRepairLineRow = (item: any) => {
  const subjectId = item?.subjectId ?? item?.id
  return {
    id: undefined,
    repairId: formData.value.id,
    subjectId,
    subjectCode: item?.subjectCode ?? item?.subject_code ?? item?.code,
    subjectName: item?.subjectName ?? item?.subject_name ?? item?.name,
    subjectType: item?.subjectType ?? item?.subject_type ?? item?.type,
    subjectContent: item?.subjectContent ?? item?.projectContent ?? item?.subject_content,
    subjectStandard: item?.subjectStandard ?? item?.judgmentCriteria ?? item?.subject_standard,
    malfunction: undefined,
    malfunctionUrl: undefined,
    repairDes: undefined,
    remark: undefined,
  }
}

const prefillLinesByMold = async (moldId: number | undefined) => {
  if (formType.value !== 'create') return
  if (typeof moldId !== 'number') {
    setLineRows([])
    return
  }
  const data = await MoldRepairItemsApi.getRepairItemsPage({ pageNo: 1, pageSize: 100, moldId })
  const list = normalizeMoldRepairItemList(data)
  setLineRows(list.map(toMoldRepairLineRow))
}

const open = async (type: string, id?: number) => {
  const currentOpenId = ++openRequestId.value
  dialogTitle.value = type === 'repair' ? '维修处理结果' : t('action.' + type)
  formType.value = type
  resetForm()
  await ensureUsersLoaded()
  await ensureMoldOptionsLoaded()
  if (currentOpenId !== openRequestId.value) return
  if (id) {
    formLoading.value = true
    try {
      isHydrating.value = true
      formData.value = await MoldRepairApi.getMoldRepair(id)

      if (currentOpenId !== openRequestId.value) return

      ;(formData.value as any).requireDate = (formData.value as any).requireDate ?? undefined
      ;(formData.value as any).finishDate = (formData.value as any).finishDate ?? undefined
      ;(formData.value as any).confirmDate = (formData.value as any).confirmDate ?? undefined
      ;(formData.value as any).repairResult = (formData.value as any).repairResult ?? ''

      ;(formData.value as any).acceptedBy = normalizeUserId((formData.value as any).acceptedBy)
      ;(formData.value as any).confirmBy = normalizeUserId((formData.value as any).confirmBy)

      ;(formData.value as any).moldCode = (formData.value as any).moldCode ?? (formData.value as any).machineryCode
      ;(formData.value as any).moldName = (formData.value as any).moldName ?? (formData.value as any).machineryName
      const rawMoldId = (formData.value as any).moldId
      const rawMachineryId = (formData.value as any).machineryId
      const resolvedMoldId =
        typeof rawMoldId === 'number'
          ? rawMoldId
          : typeof rawMachineryId === 'number'
            ? rawMachineryId
            : Number(rawMachineryId)

      delete (formData.value as any).machineryId
      delete (formData.value as any).machineryCode
      delete (formData.value as any).machineryName
      if (typeof resolvedMoldId === 'number' && !Number.isNaN(resolvedMoldId)) {
        formData.value.moldId = resolvedMoldId
        const label = `${formData.value.moldCode ?? ''} ${formData.value.moldName ?? ''}`.trim() || `ID:${resolvedMoldId}`
        moldOptions.value = upsertMoldOption(moldOptions.value, { label, value: resolvedMoldId })
      }
    } finally {
      isHydrating.value = false
      formLoading.value = false
    }
  }
}
defineExpose({ open })

const closeForm = () => {
  openRequestId.value++
  emit('closed')
}

const submitForm = async () => {
  await formRef.value.validate()
  formLoading.value = true
  try {
    const data = { ...formData.value }
    if (formType.value === 'create') {
      await MoldRepairApi.createMoldRepair(data)
      message.success(t('common.createSuccess'))
    } else {
      await MoldRepairApi.updateMoldRepair(data)
      message.success(t('common.updateSuccess'))
    }
    await moldRepairLineFormRef.value?.submit()
    closeForm()
    emit('success')
  } finally {
    formLoading.value = false
  }
}

const resetForm = () => {
  formData.value = {
    id: undefined,
    repairCode: undefined,
    repairName: undefined,
    moldId: undefined,
    moldCode: undefined,
    moldName: undefined,
    machineryBrand: undefined,
    machinerySpec: undefined,
    requireDate: undefined,
    finishDate: undefined,
    confirmDate: undefined,
    repairResult: '',
    acceptedBy: undefined,
    confirmBy: undefined,
    status: undefined,
    remark: undefined,
    isCode: true
  }
  moldOptionsLoaded.value = false
  formRef.value?.resetFields()
}
</script>

<style lang="scss" scoped>
.dv-repair-panel {
  background: #fff;
  border-radius: 12px;
  box-shadow: var(--el-box-shadow-light);
}

.dv-repair-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid #ebeef5;
}

.dv-repair-panel__title {
  color: #1f2937;
  font-size: 18px;
  font-weight: 600;
}

.dv-repair-dialog {
  max-height: calc(100vh - 220px);
  padding: 20px 20px 0;
  padding-right: 16px;
  overflow-y: auto;
}

.dv-repair-section {
  margin-bottom: 20px;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 8px;
}

.dv-repair-section__title {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 16px;
  padding-left: 8px;
  border-left: 3px solid #409eff;
}

.dv-repair-code-row {
  display: flex;
  gap: 10px;
  align-items: center;
}

.dv-repair-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  width: 100%;
  padding: 16px 20px 20px;
  border-top: 1px solid #ebeef5;
}

@media (max-width: 1200px) {
  .dv-repair-section .el-col {
    flex: 0 0 100%;
  }
}

@media (max-width: 768px) {
  .dv-repair-panel__header {
    padding: 14px 16px;
  }

  .dv-repair-dialog {
    max-height: none;
    padding: 16px 16px 0;
    overflow-y: visible;
  }

  .dv-repair-footer {
    padding: 16px;
  }
}
</style>
