<template>
  <Teleport to="body">
    <div
      v-if="open"
      class="risk-waiver-dialog-backdrop"
      @click.self="cancel"
      @keydown.esc.prevent="cancel"
    >
      <section
        class="risk-waiver-dialog"
        role="dialog"
        aria-modal="true"
        :aria-labelledby="titleId"
      >
        <header>
          <div>
            <span>风险豁免</span>
            <h3 :id="titleId">{{ dialogTitle }}</h3>
          </div>
          <button type="button" :disabled="busy" aria-label="关闭" @click="cancel">
            <i class="mdi mdi-close"></i>
          </button>
        </header>

        <p class="risk-waiver-dialog-notice" :class="dialogTone">
          {{ dialogNotice }}
        </p>

        <dl v-if="!isRequest" class="risk-waiver-dialog-summary">
          <div>
            <dt>申请人</dt>
            <dd>{{ disposition.waiverRequesterName || disposition.waiverRequesterId || '未记录' }}</dd>
          </div>
          <div>
            <dt>申请理由</dt>
            <dd>{{ disposition.waiverReason || '未记录' }}</dd>
          </div>
          <div>
            <dt>豁免范围</dt>
            <dd>{{ disposition.waiverScope || '未记录' }}</dd>
          </div>
          <div>
            <dt>有效期至</dt>
            <dd>{{ formatDateTime(disposition.waiverExpiresAt) }}</dd>
          </div>
          <div v-if="disposition.waiverConditions?.length">
            <dt>补偿条件</dt>
            <dd>{{ disposition.waiverConditions.join('；') }}</dd>
          </div>
        </dl>

        <form @submit.prevent="confirm">
          <template v-if="isRequest">
            <label>
              <span>申请理由 <em>必填</em></span>
              <textarea
                v-model="form.reason"
                :disabled="busy"
                maxlength="2000"
                placeholder="说明为什么需要例外处理，以及无法按常规流程解决的原因"
              ></textarea>
            </label>
            <label>
              <span>豁免范围 <em>必填</em></span>
              <textarea
                v-model="form.scope"
                :disabled="busy"
                maxlength="1000"
                placeholder="限定到本次单据、具体材料或风险项，避免扩大豁免范围"
              ></textarea>
            </label>
            <label>
              <span>有效期 <em>必填</em></span>
              <input
                v-model="form.expiresAt"
                type="datetime-local"
                :min="minimumExpiry"
                :disabled="busy"
              />
            </label>
            <label>
              <span>补偿条件 <small>选填，每行一项</small></span>
              <textarea
                v-model="form.conditions"
                :disabled="busy"
                maxlength="4000"
                placeholder="例如：三日内补交原件&#10;到期前由财务复核"
              ></textarea>
            </label>
          </template>
          <label v-else>
            <span>{{ decisionReasonLabel }} <em>必填</em></span>
            <textarea
              v-model="form.decisionReason"
              :disabled="busy"
              maxlength="1000"
              :placeholder="decisionReasonPlaceholder"
            ></textarea>
          </label>

          <p v-if="validationMessage" class="risk-waiver-dialog-validation" role="alert">
            {{ validationMessage }}
          </p>

          <footer>
            <button type="button" :disabled="busy" @click="cancel">取消</button>
            <button
              type="submit"
              class="primary"
              :class="dialogTone"
              :disabled="busy"
            >
              <i v-if="busy" class="mdi mdi-loading mdi-spin"></i>
              {{ busy ? '正在提交' : confirmLabel }}
            </button>
          </footer>
        </form>
      </section>
    </div>
  </Teleport>
</template>

<script setup>
import { computed, reactive, ref, watch } from 'vue'

const props = defineProps({
  open: { type: Boolean, default: false },
  action: { type: String, default: '' },
  busy: { type: Boolean, default: false },
  disposition: { type: Object, default: () => ({}) }
})

const emit = defineEmits(['cancel', 'confirm'])
const titleId = 'risk-waiver-action-dialog-title'
const validationMessage = ref('')
const form = reactive({
  reason: '',
  scope: '',
  expiresAt: '',
  conditions: '',
  decisionReason: ''
})

const isRequest = computed(() => props.action === 'request_waiver')
const isRejection = computed(() => props.action === 'reject_waiver')
const dialogTitle = computed(() => (
  isRequest.value ? '申请风险豁免' : isRejection.value ? '拒绝风险豁免' : '批准风险豁免'
))
const dialogTone = computed(() => (isRejection.value ? 'danger' : 'warning'))
const dialogNotice = computed(() => {
  if (isRequest.value) {
    return '提交后仍会保持风险阻断，必须由另一位有权决定人批准后才会在有效期内解除。'
  }
  if (isRejection.value) {
    return '拒绝后该风险仍会阻断审批；拒绝理由将写入审计记录且不可省略。'
  }
  return '批准后仅在申请有效期内解除风险阻断，到期后系统会自动恢复风险控制。'
})
const confirmLabel = computed(() => (
  isRequest.value
    ? '确认提交豁免申请'
    : isRejection.value
      ? '确认拒绝豁免'
      : '确认批准豁免'
))
const decisionReasonLabel = computed(() => (isRejection.value ? '拒绝理由' : '批准理由'))
const decisionReasonPlaceholder = computed(() => (
  isRejection.value
    ? '说明拒绝原因和仍需补充的控制措施'
    : '说明批准依据和已确认的补偿控制'
))
const minimumExpiry = computed(() => toLocalDateTime(new Date(Date.now() + 60 * 1000)))

watch(
  () => [props.open, props.action],
  ([open]) => {
    if (!open) return
    validationMessage.value = ''
    form.reason = ''
    form.scope = ''
    form.conditions = ''
    form.decisionReason = ''
    form.expiresAt = isRequest.value
      ? toLocalDateTime(new Date(Date.now() + 7 * 24 * 60 * 60 * 1000))
      : ''
  }
)

function cancel() {
  if (!props.busy) emit('cancel')
}

function confirm() {
  validationMessage.value = ''
  if (props.busy) return
  if (isRequest.value) {
    const reason = form.reason.trim()
    const scope = form.scope.trim()
    const expiry = new Date(form.expiresAt)
    if (!reason || !scope || !form.expiresAt) {
      validationMessage.value = '请完整填写申请理由、豁免范围和有效期。'
      return
    }
    if (Number.isNaN(expiry.getTime()) || expiry.getTime() <= Date.now()) {
      validationMessage.value = '有效期必须晚于当前时间。'
      return
    }
    const conditions = parseConditions(form.conditions)
    if (conditions.length > 20) {
      validationMessage.value = '补偿条件最多填写 20 项。'
      return
    }
    if (conditions.some((item) => item.length > 500)) {
      validationMessage.value = '单项补偿条件不能超过 500 个字符。'
      return
    }
    emit('confirm', {
      action: props.action,
      waiverReason: reason,
      waiverScope: scope,
      waiverExpiresAt: expiry.toISOString(),
      waiverConditions: conditions
    })
    return
  }
  const comment = form.decisionReason.trim()
  if (!comment) {
    validationMessage.value = isRejection.value ? '请填写拒绝理由。' : '请填写批准理由。'
    return
  }
  emit('confirm', { action: props.action, comment })
}

function parseConditions(value) {
  return [...new Set(
    String(value || '')
      .split(/\r?\n/)
      .map((item) => item.trim())
      .filter(Boolean)
  )]
}

function toLocalDateTime(value) {
  const date = value instanceof Date ? value : new Date(value)
  if (Number.isNaN(date.getTime())) return ''
  const offset = date.getTimezoneOffset() * 60 * 1000
  return new Date(date.getTime() - offset).toISOString().slice(0, 16)
}

function formatDateTime(value) {
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return '未记录'
  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    hour12: false
  }).format(date)
}
</script>

<style scoped src="../../assets/styles/components/risk-waiver-action-dialog.css"></style>
