<template>
  <Dialog
    scroll
    @close="dialogVisible = false"
    style="max-width: 100vw; min-width: 800px"
    v-model="dialogVisible"
    :title="dialogTitle"
    class="OutwardRegistrationBak"
    noPaddingEL="OutwardRegistrationBak"
  >
    <el-form ref="formRef" :model="dataForm" :label-width="labelWidth">
      <div style="display: flex; flex-direction: column; margin-top: 20px">
        <text>当前规则：</text>
        <el-radio-group v-model="dataForm.type" class="ml-4">
          <el-radio v-if="!isTodayAdd" :value="1" size="large">每天</el-radio>
          <el-radio v-if="isTodayAdd" :value="2" size="large">单次</el-radio>
        </el-radio-group>
      </div>

      <div style="display: flex; align-items: center; flex-direction: row" v-if="!isEdit">
        <el-button v-if="!isEdit" @click="addTimes" type="primary" style="margin-left: 10px">
          新增时间段
        </el-button>
        <template v-if="formMode === 'dailyAdd'">
          <el-text style="margin-left: 8vw">可提前</el-text>
          <el-input
            :maxlength="2"
            style="max-width: 66px; margin-left: 8px"
            v-model="dataForm.advancedDays"
          />
          <el-text style="margin-left: 8px">天预约</el-text>
        </template>
      </div>

      <div class="info-wrap">
        <el-row
          v-for="(item, index) in dataForm.slots"
          :key="index"
          style="
            position: relative;
            padding: 10px 0;
            margin-bottom: 10px;
            border: #e0e0e0 solid 1px;
            border-radius: 6px;
          "
        >
          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
            <div style="flex-direction: row; display: flex; align-items: center; width: 100%">
              <text
                style="
                  display: flex;
                  width: 20px;
                  height: 20px;
                  margin-left: 10px;
                  border: #ddd solid 1px;
                  border-radius: 50%;
                  align-items: center;
                  justify-content: center;
                "
                >{{ index + 1 }}</text
              >
              <div style="display: flex; flex-direction: column; margin-left: -12px">
                <el-form-item label="开始时间">
                  <el-select
                    v-model="item.hourS"
                    class="m-2"
                    placeholder="Select"
                    style="width: 64px"
                  >
                    <el-option
                      v-for="items in optionsH"
                      :key="items.value"
                      :label="items.label"
                      :value="items.value"
                    />
                  </el-select>
                  点
                  <el-select
                    v-model="item.minuteS"
                    class="m-2"
                    placeholder="Select"
                    style="width: 64px"
                  >
                    <el-option
                      v-for="items in optionsM"
                      :key="items.value"
                      :label="items.label"
                      :value="items.value"
                    />
                  </el-select>
                  分
                </el-form-item>
                <el-form-item label="结束时间">
                  <el-select
                    v-model="item.hourE"
                    class="m-2"
                    placeholder="Select"
                    style="width: 64px"
                  >
                    <el-option
                      v-for="items in optionsH"
                      :key="items.value"
                      :label="items.label"
                      :value="items.value"
                    />
                  </el-select>
                  点
                  <el-select
                    v-model="item.minuteE"
                    class="m-2"
                    placeholder="Select"
                    style="width: 64px"
                  >
                    <el-option
                      v-for="items in optionsM"
                      :key="items.value"
                      :label="items.label"
                      :value="items.value"
                    />
                  </el-select>
                  分
                </el-form-item>
              </div>
              <div style="align-items: center; display: flex; flex-direction: row">
                <text style="margin-left: 2vw">此时间段可预约次数:</text>
                <el-input
                  :maxlength="5"
                  placeholder="输入次数"
                  style="width: 78px; margin-left: 3px"
                  v-model="item.totalQuota"
                />
              </div>

              <el-icon
                v-if="!isEdit"
                @click="deleteItem(index)"
                color="red"
                size="large"
                style="
                  position: absolute;
                  top: 0;
                  right: 0;
                  width: 30px;
                  height: 30px;
                  margin-left: auto;
                  cursor: pointer;
                "
                ><Close
              /></el-icon>
            </div>
          </el-col>
        </el-row>
      </div>
    </el-form>

    <template #footer>
      <el-button @click="handleClosed">关闭</el-button>
      <el-button v-loading="formLoading" type="primary" @click="submitForm">确定</el-button>
    </template>
  </Dialog>
</template>

<script lang="ts" setup>
import { computed, ref } from 'vue'
import { useMediaQuery } from '@vueuse/core'
import { Close } from '@element-plus/icons-vue'
import fetchHttp from '@/config/axios/fetchHttp'
import { compareTimeStrings, isValidTimeFormat } from '@/utils/dateUtil'
import { useUserStore } from '@/store/modules/user'

type FormMode = 'dailyAdd' | 'dailyEdit' | 'todayAdd'

type TimeslotEditItem = {
  id?: number
  timeslot: string
  hourS: string
  minuteS: string
  hourE: string
  minuteE: string
  totalQuota: string | number
}

type DailyEditApiItem = {
  id: number
  timeQuantum: string
  totalQuota: number
}

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

const formRef = ref()
const formLoading = ref(false)
const dialogVisible = ref(false)
const formMode = ref<FormMode>('dailyAdd')

const currentWidth = useMediaQuery('(max-width: 800px)')

const labelWidth = computed(() => (currentWidth.value ? '110px' : '120px'))
const isEdit = computed(() => formMode.value === 'dailyEdit')
const isTodayAdd = computed(() => formMode.value === 'todayAdd')
const isDailyAdd = computed(() => formMode.value === 'dailyAdd')
const dialogTitle = computed(() => {
  if (formMode.value === 'dailyEdit') return '编辑预约时间段'
  if (formMode.value === 'todayAdd') return '新增单日时间段'
  return '新增预约时间段'
})

const dataForm = ref({
  organizationId: undefined as any,
  date: '',
  advancedDays: '',
  type: 1,
  slots: [] as TimeslotEditItem[]
})

const optionsH = ref(
  Array.from({ length: 24 }, (_, i) => {
    const v = String(i).padStart(2, '0')
    return { value: v, label: v }
  })
)

const optionsM = ref([
  { value: '00', label: '00' },
  { value: '30', label: '30' }
])


const makeEmptySlot = (): TimeslotEditItem => ({
  timeslot: '',
  hourS: '00',
  minuteS: '00',
  hourE: '00',
  minuteE: '00',
  totalQuota: '1'
})

const buildTimeslot = (slot: TimeslotEditItem) => {
  const sTime = `${slot.hourS}:${slot.minuteS}`
  const eTime = `${slot.hourE}:${slot.minuteE}`
  if (!isValidTimeFormat(sTime) || !isValidTimeFormat(eTime)) {
    throw new Error('时间格式不正确，请使用HH:mm格式')
  }
  const result = compareTimeStrings(sTime, eTime)
  if (result !== -1) {
    throw new Error('开始时间不能大于等于结束时间!')
  }
  return `${sTime}-${eTime}`
}

const normalizeAndValidateSlots = () => {
  for (const slot of dataForm.value.slots) {
    if (slot.totalQuota === '' || slot.totalQuota === undefined || slot.totalQuota === null) {
      throw new Error('请选择时间和输入次数')
    }
    const total = Number.parseInt(String(slot.totalQuota), 10)
    if (Number.isNaN(total)) {
      throw new Error('请输入数字!')
    }
    slot.totalQuota = total
    slot.timeslot = buildTimeslot(slot) || ''
  }
}

const addTimes = () => {
  dataForm.value.slots.push(makeEmptySlot())
}

const deleteItem = (index: number) => {
  dataForm.value.slots.splice(index, 1)
}

const resetForm = () => {
  dataForm.value = {
    organizationId: undefined,
    date: '',
    advancedDays: '',
    type: 1,
    slots: []
  }
  formRef.value?.resetFields()
}

const open = async (payload:{date: string, organizationId: number}) => {
  formMode.value = 'dailyAdd'
  resetForm()
  dialogVisible.value = true
  dataForm.value.date = payload.date
  dataForm.value.type = 1
  dataForm.value.organizationId = payload.organizationId
}

const openEdit = async (payload: { date: string; organizationId: number; list: DailyEditApiItem[] }) => {
  formMode.value = 'dailyEdit'
  resetForm()
  dialogVisible.value = true
  dataForm.value.date = payload.date
  dataForm.value.organizationId = payload.organizationId
  dataForm.value.type = 1
  dataForm.value.slots = (payload.list || []).map((it) => {
    const [start, end] = (it.timeQuantum || '').split('-')
    const [hourS, minuteS] = (start || '').split(':')
    const [hourE, minuteE] = (end || '').split(':')
    return {
      id: it.id,
      timeslot: it.timeQuantum,
      hourS: hourS || '00',
      minuteS: minuteS || '00',
      hourE: hourE || '00',
      minuteE: minuteE || '00',
      totalQuota: String(it.totalQuota ?? 1)
    }
  })
}

const openToday = async (payload: { date: string; organizationId: number }) => {
  formMode.value = 'todayAdd'
  resetForm()
  dialogVisible.value = true
  dataForm.value.date = payload.date
  dataForm.value.organizationId = payload.organizationId
  dataForm.value.type = 2
  if (dataForm.value.slots.length === 0) addTimes()
}

defineExpose({ open, openEdit, openToday })

const emit = defineEmits(['success'])

const submitForm = async () => {
  if (formLoading.value) return
  formLoading.value = true
  try {
    try {
      if (!formRef.value) return
      const valid = await formRef.value.validate()
      if (!valid) return

      if (isDailyAdd.value) {
        const num = Number.parseInt(String(dataForm.value.advancedDays), 10)
        if (Number.isNaN(num)) {
          message.error('天数请输入数字！')
          return
        }
      }
    } catch {
      if (isDailyAdd.value) {
        message.error('天数请输入数字！')
        return
      }
    }
    try {
      normalizeAndValidateSlots()
    } catch (e: any) {
      message.error(e?.message || '提交失败')
      return
    }
    if (formMode.value === 'dailyEdit') {
      const submitSlots = dataForm.value.slots.map((s) => ({
        slotId: s.id,
        timeslot: s.timeslot,
        totalQuota: Number(s.totalQuota)
      }))
      const res = await fetchHttp.post('/admin/appointment/updateTimeslotInstance', {
        slots: submitSlots
      })
      if (res) {
        dialogVisible.value = false
        emit('success')
      }
      return
    }
    if (formMode.value === 'todayAdd') {
      const submitSlots = dataForm.value.slots.map((s) => ({
        timeslot: s.timeslot,
        totalQuota: Number(s.totalQuota)
      }))
      if(!submitSlots.length) {
        message.success('请添加时间段!')
        return
      }
      const res = await fetchHttp.post('/admin/appointment/addTimeslotForOneDay', {
        organizationId: dataForm.value.organizationId,
        date: dataForm.value.date,
        slots: submitSlots
      })
      if (res) {
        dialogVisible.value = false
        emit('success')
      }
      return
    }
    let params = {
      ...dataForm.value,
      advancedDays: Number(dataForm.value.advancedDays),
      slots: dataForm.value.slots.map((s) => ({
        timeslot: s.timeslot,
        totalQuota: Number(s.totalQuota)
      }))
    }
    const res = await fetchHttp.post('/admin/appointment/setTimeslot', params)
    if (res) {
      dialogVisible.value = false
      emit('success')
    }
  } finally {
    setTimeout(() => {
      formLoading.value = false
    }, 500)
  }
}

const handleClosed = () => {
  dialogVisible.value = false
  formMode.value = 'dailyAdd'
  resetForm()
}
</script>

<style lang="scss" scoped>
.OutwardRegistrationBak {
  @media (width <= 1200) {
    :deep(.el-form-item--default .el-form-item__label) {
      line-height: 0 !important;
    }
  }

  .el-form {
    padding: 15px !important;
  }

  .info-title {
    max-width: 180px;
    min-width: 75px;
    padding: 15px;
    font-weight: bolder;
    background-color: #f3f6fb;
    border-top-right-radius: 50px;
    border-bottom-right-radius: 50px;
  }

  .info-wrap {
    margin: 15px;
  }
}

:deep(.el-form-item--default) {
  display: flex;
  flex-direction: row;
  align-items: center;
}
</style>

