<template>
  <Teleport to="body">
    <div
      v-if="open"
      class="commercial-dialog-mask"
      role="presentation"
      @click.self="closeDialog"
      @keydown.esc="closeDialog"
      @keydown.tab="keepFocusInside"
    >
      <section ref="dialogCard" class="commercial-dialog" role="alertdialog" aria-modal="true" :aria-labelledby="titleId">
        <header>
          <div>
            <span>{{ meta?.family === 'metering' ? 'Append-only ledger' : 'Versioned configuration' }}</span>
            <h3 :id="titleId">{{ meta?.label || '商业管理操作' }}</h3>
            <p>{{ description }}</p>
          </div>
          <button type="button" class="commercial-icon-button" aria-label="关闭对话框" :disabled="busy" @click="closeDialog">
            <i class="mdi mdi-close" aria-hidden="true"></i>
          </button>
        </header>

        <form v-if="step === 'edit'" class="commercial-dialog-form" @submit.prevent="reviewMutation">
          <div v-if="kind === 'createPlan'" class="commercial-form-grid">
            <label><span>套餐编码 *</span><input ref="firstInput" v-model.trim="draft.planCode" maxlength="80" autocomplete="off" required /></label>
            <label><span>套餐名称 *</span><input v-model.trim="draft.name" maxlength="160" autocomplete="off" required /></label>
            <label><span>计价模式 *</span><select v-model="draft.pricingModel"><option value="subscription">订阅制</option><option value="usage">按量</option><option value="hybrid">订阅 + 按量</option><option value="pilot">试点</option><option value="custom">定制</option></select></label>
            <label><span>计费周期 *</span><select v-model="draft.billingInterval"><option value="monthly">月</option><option value="quarterly">季度</option><option value="annual">年</option><option value="contract">合同周期</option></select></label>
            <label><span>币种 *</span><input v-model.trim="draft.currency" maxlength="3" autocapitalize="characters" required /><small>ISO 4217 三位币种，不执行隐式换算。</small></label>
            <label><span>基础费用 *</span><input v-model="draft.baseFee" type="number" min="0" step="0.0001" required /></label>
            <label><span>包含席位 *</span><input v-model="draft.includedSeats" type="number" min="0" step="1" required /></label>
            <label class="commercial-check-label"><input v-model="draft.overageEnabled" type="checkbox" /><span>允许超额计费</span></label>
            <label><span>生效时间 *</span><input v-model="draft.effectiveFrom" type="datetime-local" required /></label>
            <label><span>失效时间</span><input v-model="draft.effectiveTo" type="datetime-local" /></label>
            <label class="commercial-form-wide"><span>版本化合同条款 JSON</span><textarea v-model="draft.contractTermsJson" rows="4" spellcheck="false"></textarea><small>客户工时价值仅接受包含批准人和核验时间的完整基线。</small></label>
          </div>

          <div v-else-if="kind === 'createSubscription'" class="commercial-form-grid">
            <label><span>订阅键 *</span><input ref="firstInput" v-model.trim="draft.subscriptionKey" maxlength="120" autocomplete="off" required /></label>
            <label><span>套餐 ID *</span><input v-model.trim="draft.planId" maxlength="36" required /></label>
            <label><span>初始状态 *</span><select v-model="draft.status"><option value="active">生效</option><option value="trialing">试用</option></select></label>
            <label><span>席位数 *</span><input v-model="draft.seats" type="number" min="1" step="1" required /></label>
            <label><span>订阅开始 *</span><input v-model="draft.startsAt" type="datetime-local" required /></label>
            <label><span>订阅结束</span><input v-model="draft.endsAt" type="datetime-local" /></label>
            <label><span>当前周期开始 *</span><input v-model="draft.currentPeriodStart" type="datetime-local" required /></label>
            <label><span>当前周期结束 *</span><input v-model="draft.currentPeriodEnd" type="datetime-local" required /></label>
            <label class="commercial-check-label"><input v-model="draft.autoRenew" type="checkbox" /><span>自动续费</span></label>
            <label><span>外部提供商</span><input v-model.trim="draft.externalProvider" maxlength="60" /></label>
            <label><span>外部订阅编号</span><input v-model.trim="draft.externalSubscriptionId" maxlength="160" /></label>
            <label class="commercial-form-wide"><span>订阅元数据 JSON</span><textarea v-model="draft.metadataJson" rows="3" spellcheck="false"></textarea></label>
          </div>

          <div v-else-if="kind === 'upsertEntitlement'" class="commercial-form-grid">
            <label><span>订阅 ID *</span><input ref="firstInput" v-model.trim="draft.subscriptionId" maxlength="36" required /></label>
            <label><span>权益键 *</span><input v-model.trim="draft.entitlementKey" maxlength="120" required /></label>
            <label><span>指标键 *</span><input v-model.trim="draft.metricKey" maxlength="120" required /></label>
            <label><span>权益类型 *</span><select v-model="draft.entitlementType"><option value="metered">计量权益</option><option value="feature">功能开关</option><option value="unlimited">不限量</option></select></label>
            <label><span>单位 *</span><input v-model.trim="draft.unit" maxlength="40" required /></label>
            <label><span>包含量</span><input v-model="draft.includedQuantity" type="number" min="0" step="0.000001" :disabled="draft.entitlementType === 'unlimited'" /></label>
            <label><span>硬配额</span><input v-model="draft.hardLimitQuantity" type="number" min="0" step="0.000001" :disabled="draft.entitlementType === 'unlimited'" /></label>
            <label><span>重置周期 *</span><select v-model="draft.resetInterval"><option value="none">不重置</option><option value="monthly">月</option><option value="quarterly">季度</option><option value="annual">年</option><option value="contract">合同周期</option></select></label>
            <label><span>超额策略 *</span><select v-model="draft.overagePolicy"><option value="block">阻断</option><option value="alert">告警</option><option value="allow">允许</option></select></label>
            <label><span>状态 *</span><select v-model="draft.status"><option value="active">生效</option><option value="suspended">暂停</option><option value="expired">过期</option></select></label>
            <label><span>生效时间 *</span><input v-model="draft.effectiveFrom" type="datetime-local" required /></label>
            <label><span>失效时间</span><input v-model="draft.effectiveTo" type="datetime-local" /></label>
            <label class="commercial-form-wide"><span>权益配置 JSON</span><textarea v-model="draft.configJson" rows="4" spellcheck="false"></textarea><small>按量计价需显式提供 billable_unit_price、billing_currency 和 billing_mode。</small></label>
          </div>

          <div v-else-if="kind?.startsWith('activate')" class="commercial-form-grid">
            <label><span>资源 ID *</span><input ref="firstInput" v-model.trim="draft.resourceId" maxlength="36" required /></label>
            <label><span>期望版本 *</span><input v-model="draft.expectedVersion" type="number" min="1" step="1" required /></label>
            <label class="commercial-form-wide"><span>激活原因 *</span><textarea v-model.trim="draft.reason" rows="3" maxlength="500" required></textarea><small>原因与请求编号会进入不可变商业审计。</small></label>
            <p class="commercial-form-wide commercial-form-note"><i class="mdi mdi-source-branch" aria-hidden="true"></i>乐观锁会阻止使用旧版本覆盖其他管理员的最新变更。</p>
          </div>

          <div v-else-if="kind === 'transitionSubscription'" class="commercial-form-grid">
            <label><span>订阅 ID *</span><input ref="firstInput" v-model.trim="draft.resourceId" maxlength="36" required /></label>
            <label><span>期望版本 *</span><input v-model="draft.expectedVersion" type="number" min="1" step="1" required /></label>
            <label><span>目标状态 *</span><select v-model="draft.targetStatus" required><option v-for="option in transitionOptions" :key="option.value" :value="option.value">{{ option.label }}</option></select></label>
            <label class="commercial-form-wide"><span>变更原因 *</span><textarea v-model.trim="draft.reason" rows="3" maxlength="500" required></textarea><small>原因会进入订阅状态历史；取消和过期后只能创建新订阅恢复服务。</small></label>
          </div>

          <div v-else-if="kind === 'recordUsage'" class="commercial-form-grid">
            <label><span>订阅 ID *</span><input ref="firstInput" v-model.trim="draft.subscriptionId" maxlength="36" required /></label>
            <label><span>权益 ID *</span><input v-model.trim="draft.entitlementId" maxlength="36" required /></label>
            <label><span>事件类型 *</span><select v-model="draft.eventType"><option value="usage">用量</option><option value="credit">抵扣</option><option value="adjustment">调整</option><option value="reversal">冲回</option></select></label>
            <label><span>数量 *</span><input v-model="draft.quantity" type="number" step="0.000001" required /></label>
            <label><span>发生时间 *</span><input v-model="draft.occurredAt" type="datetime-local" required /></label>
            <label><span>来源系统 *</span><input v-model.trim="draft.sourceSystem" maxlength="80" required /></label>
            <label class="commercial-form-wide"><span>幂等键 *</span><input v-model.trim="draft.idempotencyKey" maxlength="160" required /><small>重试必须复用同一幂等键；同键不同载荷会被服务器拒绝。</small></label>
            <label v-if="draft.eventType === 'reversal'" class="commercial-form-wide"><span>被冲回事件 ID *</span><input v-model.trim="draft.reversalOfEventId" maxlength="36" required /></label>
            <label><span>主体类型</span><input v-model.trim="draft.subjectType" maxlength="60" /></label>
            <label><span>主体 ID</span><input v-model.trim="draft.subjectId" maxlength="160" /></label>
            <label><span>关联 ID</span><input v-model.trim="draft.correlationId" maxlength="120" /></label>
            <label class="commercial-form-wide"><span>用量元数据 JSON</span><textarea v-model="draft.metadataJson" rows="3" spellcheck="false"></textarea></label>
          </div>

          <div v-else-if="kind === 'recordCost'" class="commercial-form-grid">
            <label><span>订阅 ID</span><input ref="firstInput" v-model.trim="draft.subscriptionId" maxlength="36" /></label>
            <label><span>关联用量事件 ID</span><input v-model.trim="draft.usageEventId" maxlength="36" /></label>
            <label><span>事件类型 *</span><select v-model="draft.eventType"><option value="incurred">发生</option><option value="credit">抵扣</option><option value="adjustment">调整</option><option value="reversal">冲回</option></select></label>
            <label><span>成本类别 *</span><select v-model="draft.costCategory"><option value="ai_inference">AI 推理</option><option value="ocr">OCR</option><option value="storage">存储</option><option value="connector">连接器</option><option value="support">支持</option><option value="implementation">实施</option><option value="infrastructure">基础设施</option><option value="payment">支付</option><option value="other">其他</option></select></label>
            <label><span>数量 *</span><input v-model="draft.quantity" type="number" min="0.000001" step="0.000001" required /></label>
            <label><span>单位 *</span><input v-model.trim="draft.unit" maxlength="40" required /></label>
            <label><span>单位成本 *</span><input v-model="draft.unitCost" type="number" min="0" step="0.00000001" required /></label>
            <label><span>原始币种 *</span><input v-model.trim="draft.originalCurrency" maxlength="3" required /></label>
            <label><span>报告币种 *</span><input v-model.trim="draft.reportingCurrency" maxlength="3" required /></label>
            <label><span>显式汇率 *</span><input v-model="draft.fxRate" type="number" min="0.00000001" step="0.00000001" required /></label>
            <label><span>归集键 *</span><input v-model.trim="draft.allocationKey" maxlength="160" required /></label>
            <label><span>发生时间 *</span><input v-model="draft.occurredAt" type="datetime-local" required /></label>
            <label><span>来源系统 *</span><input v-model.trim="draft.sourceSystem" maxlength="80" required /></label>
            <label><span>提供商</span><input v-model.trim="draft.provider" maxlength="120" /></label>
            <label><span>SKU</span><input v-model.trim="draft.sku" maxlength="120" /></label>
            <label><span>模型</span><input v-model.trim="draft.modelName" maxlength="120" /></label>
            <label class="commercial-form-wide"><span>幂等键 *</span><input v-model.trim="draft.idempotencyKey" maxlength="160" required /></label>
            <label v-if="draft.eventType === 'reversal'" class="commercial-form-wide"><span>被冲回成本事件 ID *</span><input v-model.trim="draft.reversalOfCostEventId" maxlength="36" required /></label>
            <label class="commercial-form-wide"><span>成本元数据 JSON</span><textarea v-model="draft.metadataJson" rows="3" spellcheck="false"></textarea></label>
          </div>

          <p v-if="localError" class="commercial-form-error" role="alert">{{ localError }}</p>
          <footer>
            <button type="button" class="commercial-button ghost" @click="closeDialog">取消</button>
            <button type="submit" class="commercial-button primary">核对并继续</button>
          </footer>
        </form>

        <div v-else class="commercial-confirmation">
          <div class="commercial-confirmation-icon"><i class="mdi mdi-shield-check-outline" aria-hidden="true"></i></div>
          <strong>{{ meta?.confirm }}</strong>
          <p>请核对以下服务器写入内容。本操作不会在客户端补造缺失事实。</p>
          <ul><li v-for="item in confirmationRows" :key="item">{{ item }}</li></ul>
          <p v-if="localError" class="commercial-form-error" role="alert">{{ localError }}</p>
          <footer>
            <button type="button" class="commercial-button ghost" :disabled="busy" @click="step = 'edit'">返回修改</button>
            <button type="button" class="commercial-button primary" :disabled="busy" @click="submitMutation">
              <i :class="busy ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-check-bold'" aria-hidden="true"></i>
              {{ busy ? '正在写入' : '确认写入' }}
            </button>
          </footer>
        </div>
      </section>
    </div>
  </Teleport>
</template>

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

import {
  buildCommercialConfirmationRows,
  commercialActionMeta,
  createCommercialForm,
  resolveSubscriptionTransitionTargets
} from './commercialFormModel.js'
import { buildCommercialMutation } from './commercialWorkspaceModel.js'

const props = defineProps({
  open: { type: Boolean, default: false },
  kind: { type: String, default: '' },
  account: { type: Object, default: null },
  preset: { type: Object, default: () => ({}) },
  busy: { type: Boolean, default: false }
})
const emit = defineEmits(['close', 'submit'])
const instance = getCurrentInstance()
const draft = reactive({})
const step = ref('edit')
const localError = ref('')
const normalizedPayload = ref(null)
const firstInput = ref(null)
const dialogCard = ref(null)
let previousFocus = null

const meta = computed(() => commercialActionMeta(props.kind))
const titleId = computed(() => `commercial-mutation-title-${instance?.uid || 'dialog'}`)
const confirmationRows = computed(() => buildCommercialConfirmationRows(props.kind, normalizedPayload.value || {}))
const transitionOptions = computed(() => {
  const labels = { past_due: '标记逾期', suspended: '暂停', canceled: '取消（终态）', expired: '过期（终态）' }
  return resolveSubscriptionTransitionTargets(draft.currentStatus)
    .map((value) => ({ value, label: labels[value] }))
})
const description = computed(() => {
  if (meta.value?.family === 'metering') return '事件写入后不可编辑，纠错必须通过追加调整或冲回事件完成。'
  if (meta.value?.family === 'activation') return '激活使用乐观锁版本校验，避免并发覆盖。'
  return '配置采用版本化快照，历史计费事实不会被静默改写。'
})

watch(
  () => [props.open, props.kind, props.preset],
  ([open]) => {
    if (!open) {
      if (previousFocus && typeof previousFocus.focus === 'function') {
        void nextTick(() => previousFocus?.focus?.())
      }
      previousFocus = null
      return
    }
    previousFocus = typeof document !== 'undefined' ? document.activeElement : null
    Object.keys(draft).forEach((key) => delete draft[key])
    Object.assign(draft, createCommercialForm(props.kind, props.account), props.preset)
    step.value = 'edit'
    localError.value = ''
    normalizedPayload.value = null
    void nextTick(() => firstInput.value?.focus?.())
  },
  { immediate: true }
)

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

function keepFocusInside(event) {
  const controls = Array.from(dialogCard.value?.querySelectorAll?.(
    'button:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]:not([tabindex="-1"])'
  ) || [])
  if (!controls.length) return
  const first = controls[0]
  const last = controls.at(-1)
  if (event.shiftKey && document.activeElement === first) {
    event.preventDefault()
    last.focus()
  } else if (!event.shiftKey && document.activeElement === last) {
    event.preventDefault()
    first.focus()
  }
}

function reviewMutation() {
  localError.value = ''
  try {
    normalizedPayload.value = buildCommercialMutation(props.kind, draft, props.account)
    step.value = 'confirm'
  } catch (error) {
    localError.value = error.message || '请检查输入后重试。'
  }
}

function submitMutation() {
  localError.value = ''
  emit('submit', { kind: props.kind, form: { ...draft } }, (error) => {
    localError.value = error?.message || ''
  })
}
</script>
