<template>
  <ElDrawer v-model="visible" :title="drawerTitle" size="52%" direction="rtl" destroy-on-close>
    <template #header>
      <div class="flex items-center justify-between gap-2 w-full">
        <div class="flex items-center gap-2 min-w-0">
          <span class="truncate">{{ drawerTitle }}</span>
          <ElTag v-if="detail" :type="getStatusType(detail.status)">{{
            getStatusText(detail.status)
          }}</ElTag>
        </div>
        <div class="flex items-center gap-2">
          <ElButton
            size="small"
            :disabled="loading || !detail"
            @click="handleEmitExportPdf"
            v-ripple
          >
            <ArtSvgIcon icon="ri:file-pdf-2-line" />
            {{ $t('billing.action.exportPdf') }}
          </ElButton>
          <ElButton v-if="canCancel" size="small" type="warning" @click="handleEmitCancel" v-ripple>
            <ArtSvgIcon icon="ri:close-line" />
            {{ $t('billing.action.cancel') }}
          </ElButton>
          <ElButton
            v-if="canRecordPayment"
            size="small"
            type="primary"
            @click="handleEmitRecordPayment"
            v-ripple
          >
            <ArtSvgIcon icon="ri:add-line" />
            {{ $t('billing.action.recordPayment') }}
          </ElButton>
        </div>
      </div>
    </template>

    <div v-loading="loading" class="min-h-[200px]">
      <ElTabs v-if="detail" v-model="activeTab" class="mt-2">
        <ElTabPane :label="$t('billing.drawer.tabs.basic')" name="basic">
          <ElDescriptions :column="2" border>
            <ElDescriptionsItem :label="$t('billing.field.statementNo')">
              <span class="font-mono">{{ detail.statementNo }}</span>
            </ElDescriptionsItem>
            <ElDescriptionsItem :label="$t('billing.field.tenantName')">
              {{ detail.tenantName || '-' }}
            </ElDescriptionsItem>
            <ElDescriptionsItem :label="$t('billing.field.billingType')">
              <ElTag type="info">{{ getBillingTypeText(detail.billingType) }}</ElTag>
            </ElDescriptionsItem>
            <ElDescriptionsItem :label="$t('billing.field.status')">
              <ElTag :type="getStatusType(detail.status)">{{ getStatusText(detail.status) }}</ElTag>
            </ElDescriptionsItem>
            <ElDescriptionsItem :label="$t('billing.field.amountDue')">
              <span class="font-semibold">¥{{ detail.amountDue.toFixed(2) }}</span>
            </ElDescriptionsItem>
            <ElDescriptionsItem :label="$t('billing.field.amountPaid')">
              <span class="font-semibold">¥{{ detail.amountPaid.toFixed(2) }}</span>
            </ElDescriptionsItem>
            <ElDescriptionsItem :label="$t('billing.field.dueDate')">
              {{ formatDate(detail.dueDate) }}
            </ElDescriptionsItem>
            <ElDescriptionsItem :label="$t('billing.field.createdAt')">
              {{ formatDateTime(detail.createdAt) }}
            </ElDescriptionsItem>
            <ElDescriptionsItem :label="$t('billing.field.periodStart')">
              {{ formatDate(detail.periodStart) }}
            </ElDescriptionsItem>
            <ElDescriptionsItem :label="$t('billing.field.periodEnd')">
              {{ formatDate(detail.periodEnd) }}
            </ElDescriptionsItem>
            <ElDescriptionsItem :label="$t('billing.field.notes')" :span="2">
              {{ detail.notes || '-' }}
            </ElDescriptionsItem>
          </ElDescriptions>
        </ElTabPane>

        <ElTabPane :label="$t('billing.drawer.tabs.lineItems')" name="lineItems">
          <ElTable :data="detail.lineItems || []" stripe border>
            <ElTableColumn prop="itemType" :label="$t('billing.lineItem.itemType')" width="140" />
            <ElTableColumn
              prop="description"
              :label="$t('billing.lineItem.description')"
              min-width="240"
            />
            <ElTableColumn prop="quantity" :label="$t('billing.lineItem.quantity')" width="120" />
            <ElTableColumn prop="unitPrice" :label="$t('billing.lineItem.unitPrice')" width="140">
              <template #default="{ row }">¥{{ Number(row.unitPrice || 0).toFixed(2) }}</template>
            </ElTableColumn>
            <ElTableColumn prop="amount" :label="$t('billing.lineItem.amount')" width="140">
              <template #default="{ row }">¥{{ Number(row.amount || 0).toFixed(2) }}</template>
            </ElTableColumn>
          </ElTable>
        </ElTabPane>

        <ElTabPane :label="$t('billing.drawer.tabs.payments')" name="payments">
          <div class="mb-3 flex items-center justify-between gap-3">
            <div class="flex items-center gap-2">
              <ElButton
                size="small"
                :type="paymentViewMode === 'timeline' ? 'primary' : 'default'"
                @click="paymentViewMode = 'timeline'"
              >
                <ArtSvgIcon icon="ri:timeline-view" />
                {{ $t('billing.view.timeline') }}
              </ElButton>
              <ElButton
                size="small"
                :type="paymentViewMode === 'table' ? 'primary' : 'default'"
                @click="paymentViewMode = 'table'"
              >
                <ArtSvgIcon icon="ri:table-view" />
                {{ $t('billing.view.table') }}
              </ElButton>
            </div>
          </div>

          <ElTimeline v-if="paymentViewMode === 'timeline' && hasPayments">
            <ElTimelineItem
              v-for="p in detail.payments"
              :key="p.id"
              :timestamp="formatDateTime(p.paidAt || p.createdAt)"
              placement="top"
              :type="getPaymentStatusType(p.status)"
            >
              <ElCard shadow="never">
                <div class="flex items-center justify-between gap-2">
                  <span class="font-semibold">¥{{ p.amount.toFixed(2) }}</span>
                  <div class="flex items-center gap-2">
                    <ElTag :type="getPaymentStatusType(p.status)" size="small">
                      {{ getPaymentStatusText(p.status) }}
                    </ElTag>
                    <ElButton
                      v-if="p.status === TenantPaymentStatus.Pending"
                      size="small"
                      type="success"
                      :loading="verifyLoading"
                      @click="handleVerifyPayment(p.id)"
                    >
                      {{ $t('billing.action.verifyPayment') }}
                    </ElButton>
                  </div>
                </div>
                <div class="mt-2 grid grid-cols-2 gap-x-4 gap-y-2 text-sm text-gray-600">
                  <div class="flex gap-2">
                    <span class="text-gray-500">{{ $t('billing.payment.method') }}:</span>
                    <span>{{ getPaymentMethodText(p.method) }}</span>
                  </div>
                  <div class="flex gap-2">
                    <span class="text-gray-500">{{ $t('billing.payment.transactionNo') }}:</span>
                    <span class="font-mono">{{ p.transactionNo || '-' }}</span>
                  </div>
                  <div class="flex gap-2 col-span-2">
                    <span class="text-gray-500">{{ $t('billing.payment.proofUrl') }}:</span>
                    <ElLink v-if="p.proofUrl" :href="p.proofUrl" target="_blank" type="primary">
                      {{ $t('billing.drawer.openProof') }}
                    </ElLink>
                    <span v-else>-</span>
                  </div>
                  <div class="flex gap-2 col-span-2">
                    <span class="text-gray-500">{{ $t('billing.payment.notes') }}:</span>
                    <span>{{ p.notes || '-' }}</span>
                  </div>
                </div>
              </ElCard>
            </ElTimelineItem>
          </ElTimeline>

          <ElTable
            v-else-if="paymentViewMode === 'table' && hasPayments"
            :data="detail.payments"
            stripe
            border
          >
            <ElTableColumn prop="amount" :label="$t('billing.payment.amount')" width="130">
              <template #default="{ row }">¥{{ row.amount.toFixed(2) }}</template>
            </ElTableColumn>
            <ElTableColumn prop="method" :label="$t('billing.payment.method')" width="140">
              <template #default="{ row }">{{ getPaymentMethodText(row.method) }}</template>
            </ElTableColumn>
            <ElTableColumn prop="status" :label="$t('billing.payment.status')" width="120">
              <template #default="{ row }">
                <ElTag :type="getPaymentStatusType(row.status)" size="small">
                  {{ getPaymentStatusText(row.status) }}
                </ElTag>
              </template>
            </ElTableColumn>
            <ElTableColumn
              prop="transactionNo"
              :label="$t('billing.payment.transactionNo')"
              min-width="180"
            />
            <ElTableColumn prop="paidAt" :label="$t('billing.payment.paidAt')" width="180">
              <template #default="{ row }">{{
                formatDateTime(row.paidAt || row.createdAt)
              }}</template>
            </ElTableColumn>
            <ElTableColumn :label="$t('table.column.action')" width="120" fixed="right">
              <template #default="{ row }">
                <ElButton
                  v-if="row.status === TenantPaymentStatus.Pending"
                  type="success"
                  size="small"
                  :loading="verifyLoading"
                  @click="handleVerifyPayment(row.id)"
                >
                  {{ $t('billing.action.verifyPayment') }}
                </ElButton>
                <span v-else>-</span>
              </template>
            </ElTableColumn>
          </ElTable>

          <ElEmpty v-if="!hasPayments" :description="$t('billing.drawer.noPayments')" />
        </ElTabPane>

        <ElTabPane :label="$t('billing.drawer.tabs.statusFlow')" name="statusFlow">
          <ElTimeline v-if="statusFlowItems.length > 0">
            <ElTimelineItem
              v-for="item in statusFlowItems"
              :key="item.key"
              :timestamp="item.timeText"
              placement="top"
              :type="item.type"
            >
              <div class="text-sm">
                <div class="font-semibold">{{ item.title }}</div>
                <div v-if="item.desc" class="text-gray-500">{{ item.desc }}</div>
              </div>
            </ElTimelineItem>
          </ElTimeline>
          <ElEmpty v-else :description="$t('billing.drawer.noStatusFlow')" />
        </ElTabPane>
      </ElTabs>
    </div>

    <template #footer>
      <div class="flex justify-end">
        <ElButton @click="visible = false">{{ $t('common.close') }}</ElButton>
      </div>
    </template>
  </ElDrawer>
</template>

<script setup lang="ts">
  import { computed, ref } from 'vue'
  import { useI18n } from 'vue-i18n'
  import {
    ElButton,
    ElCard,
    ElDescriptions,
    ElDescriptionsItem,
    ElDrawer,
    ElEmpty,
    ElLink,
    ElMessage,
    ElMessageBox,
    ElTable,
    ElTableColumn,
    ElTabPane,
    ElTabs,
    ElTag,
    ElTimeline,
    ElTimelineItem
  } from 'element-plus'
  import ArtSvgIcon from '@/components/core/base/art-svg-icon/index.vue'
  import { fetchBillingDetail, verifyPayment } from '@/api/billing'
  import {
    BillingType,
    TenantPaymentMethod,
    TenantBillingStatus,
    TenantPaymentStatus
  } from '@/enums/Billing'

  defineOptions({ name: 'BillingDetailDrawer' })

  const { t } = useI18n()
  const emit = defineEmits<{
    recordPayment: [billingId: string, remainAmount: number]
    exportPdf: [billingId: string]
    cancel: [billingId: string]
    billingUpdated: [billing: Api.Billing.BillingDetailDto]
  }>()

  // 1. 响应式状态
  const visible = ref(false)
  const loading = ref(false)
  const detail = ref<Api.Billing.BillingDetailDto | null>(null)
  const activeTab = ref<'basic' | 'lineItems' | 'payments' | 'statusFlow'>('basic')
  const paymentViewMode = ref<'timeline' | 'table'>('timeline')

  // 2. 计算属性
  const drawerTitle = computed(() => {
    if (!detail.value) return t('billing.drawer.title')
    return `${t('billing.drawer.title')} - ${detail.value.statementNo}`
  })

  const remainAmount = computed(() => {
    if (!detail.value) return 0
    return Math.max(0, (detail.value.amountDue || 0) - (detail.value.amountPaid || 0))
  })

  const hasPayments = computed(() => (detail.value?.payments?.length ?? 0) > 0)
  const canRecordPayment = computed(() => {
    const status = detail.value?.status
    return status === TenantBillingStatus.Pending || status === TenantBillingStatus.Overdue
  })
  const canCancel = computed(() => detail.value?.status === TenantBillingStatus.Pending)

  type TagType = 'primary' | 'success' | 'warning' | 'info' | 'danger'

  // 3. 状态/类型文案映射
  const getStatusType = (status: number): TagType => {
    const map: Record<number, TagType> = {
      [TenantBillingStatus.Pending]: 'warning',
      [TenantBillingStatus.Paid]: 'success',
      [TenantBillingStatus.Overdue]: 'danger',
      [TenantBillingStatus.Cancelled]: 'info'
    }
    return map[status] || 'info'
  }

  const getStatusText = (status: number) => {
    const map: Record<number, string> = {
      [TenantBillingStatus.Pending]: t('billing.status.pending'),
      [TenantBillingStatus.Paid]: t('billing.status.paid'),
      [TenantBillingStatus.Overdue]: t('billing.status.overdue'),
      [TenantBillingStatus.Cancelled]: t('billing.status.cancelled')
    }
    return map[status] || '-'
  }

  const getBillingTypeText = (type: Api.Billing.BillingType | undefined) => {
    if (type === undefined || type === null) return '-'
    const map: Record<number, string> = {
      [BillingType.Subscription]: t('billing.billingType.subscription'),
      [BillingType.QuotaPurchase]: t('billing.billingType.quotaPurchase'),
      [BillingType.Manual]: t('billing.billingType.manual'),
      [BillingType.Renewal]: t('billing.billingType.renewal')
    }
    return map[type] || '-'
  }

  const getPaymentMethodText = (method: number) => {
    const map: Record<number, string> = {
      [TenantPaymentMethod.Online]: t('billing.paymentMethod.online'),
      [TenantPaymentMethod.BankTransfer]: t('billing.paymentMethod.bankTransfer'),
      [TenantPaymentMethod.Other]: t('billing.paymentMethod.other')
    }
    return map[method] || '-'
  }

  const getPaymentStatusType = (status: number): TagType => {
    const map: Record<number, TagType> = {
      [TenantPaymentStatus.Pending]: 'warning',
      [TenantPaymentStatus.Success]: 'success',
      [TenantPaymentStatus.Failed]: 'danger',
      [TenantPaymentStatus.Refunded]: 'info'
    }
    return map[status] || 'info'
  }

  const getPaymentStatusText = (status: number) => {
    const map: Record<number, string> = {
      [TenantPaymentStatus.Pending]: t('billing.paymentStatus.pending'),
      [TenantPaymentStatus.Success]: t('billing.paymentStatus.success'),
      [TenantPaymentStatus.Failed]: t('billing.paymentStatus.failed'),
      [TenantPaymentStatus.Refunded]: t('billing.paymentStatus.refunded')
    }
    return map[status] || '-'
  }

  // 4. 时间格式化
  const formatDate = (date: string) => {
    if (!date) return '-'
    return new Date(date).toLocaleDateString('zh-CN')
  }

  const formatDateTime = (date: string) => {
    if (!date) return '-'
    return new Date(date).toLocaleString('zh-CN')
  }

  // 5. 状态流转（前端推导）
  interface StatusFlowItem {
    key: string
    title: string
    desc?: string
    timeText: string
    type: TagType
  }

  const statusFlowItems = computed<StatusFlowItem[]>(() => {
    const d = detail.value
    if (!d) return []

    const items: StatusFlowItem[] = []

    items.push({
      key: 'created',
      title: t('billing.statusFlow.created'),
      timeText: formatDateTime(d.createdAt),
      type: 'info'
    })

    items.push({
      key: 'due',
      title: t('billing.statusFlow.due'),
      timeText: formatDateTime(d.dueDate),
      type: 'warning'
    })

    const lastPaidAt = (d.payments || [])
      .map((p) => p.paidAt || p.createdAt)
      .filter(Boolean)
      .sort()
      .slice(-1)[0]

    if (d.status === TenantBillingStatus.Paid) {
      items.push({
        key: 'paid',
        title: t('billing.statusFlow.paid'),
        timeText: lastPaidAt ? formatDateTime(lastPaidAt) : '-',
        type: 'success'
      })
    }

    if (d.status === TenantBillingStatus.Overdue) {
      items.push({
        key: 'overdue',
        title: t('billing.statusFlow.overdue'),
        timeText: formatDateTime(d.overdueNotifiedAt || d.dueDate),
        type: 'danger'
      })
    }

    if (d.status === TenantBillingStatus.Cancelled) {
      items.push({
        key: 'cancelled',
        title: t('billing.statusFlow.cancelled'),
        desc: d.cancelReason || undefined,
        timeText: formatDateTime(d.cancelledAt || d.updatedAt || d.createdAt),
        type: 'info'
      })
    }

    return items
  })

  // 6. 事件触发
  const handleEmitRecordPayment = () => {
    if (!detail.value) return
    emit('recordPayment', detail.value.id, remainAmount.value)
  }

  const handleEmitExportPdf = () => {
    if (!detail.value) return
    emit('exportPdf', detail.value.id)
  }

  const handleEmitCancel = () => {
    if (!detail.value) return
    emit('cancel', detail.value.id)
  }

  // 7.1 刷新详情（供外部调用）
  const refresh = async (targetBillingId?: string) => {
    // 1. 抽屉未打开或无详情时不刷新
    if (!visible.value || !detail.value) return

    const currentBillingId = detail.value.id

    // 2. 外部传入 ID 时，仅刷新当前展示的账单
    if (targetBillingId && targetBillingId !== currentBillingId) return

    loading.value = true
    try {
      const res = await fetchBillingDetail(currentBillingId)
      detail.value = res
    } catch (error) {
      console.error('Refresh billing detail error:', error)
      ElMessage.error(t('billing.message.loadDetailFailed'))
    } finally {
      loading.value = false
    }
  }

  // 8. 审核支付
  const verifyLoading = ref(false)

  const handleVerifyPayment = async (paymentId: string) => {
    try {
      await ElMessageBox.confirm(
        t('billing.message.verifyPaymentConfirm'),
        t('billing.action.verifyPayment'),
        {
          confirmButtonText: t('common.confirm'),
          cancelButtonText: t('common.cancel'),
          type: 'info'
        }
      )
    } catch {
      return
    }

    verifyLoading.value = true
    try {
      await verifyPayment(paymentId, { approved: true })
      ElMessage.success(t('billing.message.verifyPaymentSuccess'))

      // 1. 审核成功后刷新详情（同步账单已收金额/状态）
      await refresh()

      // 2. 通知父组件刷新列表
      if (detail.value) {
        emit('billingUpdated', detail.value)
      }
    } catch (error) {
      console.error('Verify payment error:', error)
    } finally {
      verifyLoading.value = false
    }
  }

  // 7. 打开抽屉
  const open = async (id: string) => {
    visible.value = true
    loading.value = true
    activeTab.value = 'basic'
    paymentViewMode.value = 'timeline'

    try {
      const res = await fetchBillingDetail(id)
      detail.value = res
    } catch (error) {
      console.error('Load billing detail error:', error)
      ElMessage.error(t('billing.message.loadDetailFailed'))
    } finally {
      loading.value = false
    }
  }

  defineExpose({ open, refresh })
</script>
