<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import {
  claimAirdrop,
  fetchAirdropEligibility,
  fetchAirdropRecords,
  type AirdropEligibility,
  type AirdropRecordItem,
} from '@/api/staking'
import {
  resolveAirdropRecordStatusClass,
  resolveAirdropRecordStatusLabel,
} from '@/constants/airdropRecordStatus'
import { useToast } from '@/composables/useToast'
import { AUTH_ENABLED } from '@/utils/featureFlags'
import airdropHero from '@/assets/finance/airdrop-hero.png'
import airdropHero2x from '@/assets/finance/airdrop-hero@2x.png'

const { t, te } = useI18n()
const router = useRouter()
const toast = useToast()

const PAGE_SIZE = 10

const loading = ref(true)
const claiming = ref(false)
const error = ref<string | null>(null)
const eligibility = ref<AirdropEligibility | null>(null)
const showSuccessModal = ref(false)

const records = ref<AirdropRecordItem[]>([])
const recordsLoading = ref(false)
const recordsPage = ref(1)
const recordsHasMore = ref(false)

const requiredInvite = computed(() => eligibility.value?.requiredInviteCount ?? 3)
const inviteCount = computed(() => eligibility.value?.inviteCount ?? 0)
const task1Done = computed(() => eligibility.value?.inviteTaskCompleted ?? false)

const inviteProgressText = computed(() => {
  if (task1Done.value) {
    return t('finance.inviteDone')
  }
  return t('finance.inviteProgress', {
    current: inviteCount.value,
    required: requiredInvite.value,
  })
})

const canClaim = computed(() => {
  if (!AUTH_ENABLED) return false
  return eligibility.value?.eligible === true
})

function formatClaimableAmount(amount: number | string | undefined): string {
  const n = Number(amount ?? 0)
  if (Number.isNaN(n)) return '0'
  if (n === 0) return '0'
  return n.toLocaleString(undefined, { maximumFractionDigits: 8 })
}

const claimableDisplay = computed(() => {
  const amt = formatClaimableAmount(eligibility.value?.claimableAmount)
  const unit = eligibility.value?.claimableCoinUnit
  return unit ? `${amt} ${unit}` : amt
})

const claimDisabledReason = computed(() => {
  if (!eligibility.value) return ''
  if (!AUTH_ENABLED) return t('finance.loginToClaim')
  if (!eligibility.value.inviteTaskCompleted) {
    return eligibility.value.message ?? ''
  }
  if (!eligibility.value.hasActiveStaking) {
    return t('finance.needActiveStaking')
  }
  if (!eligibility.value.hasPendingAirdrop) {
    return t('finance.noPendingAirdrop')
  }
  return ''
})

function formatRecordAmount(item: AirdropRecordItem) {
  const amt = formatClaimableAmount(item.amount)
  return item.coinUnit ? `${amt} ${item.coinUnit}` : amt
}

function recordTimeMeta(item: AirdropRecordItem) {
  if (item.status === 1 || item.status === 3) {
    return {
      label: t('finance.airdropRecordTimeAudit'),
      time: item.auditTime || item.claimTime || item.createTime || '—',
    }
  }
  if (item.status === 2) {
    return {
      label: t('finance.airdropRecordTimeSubmit'),
      time: item.claimTime || item.createTime || '—',
    }
  }
  return {
    label: t('finance.airdropRecordTimeCreate'),
    time: item.createTime || '—',
  }
}

function fmtDateTime(s: string) {
  return s.replace('T', ' ').slice(0, 19)
}

async function loadRecords(reset = false) {
  if (!AUTH_ENABLED) {
    records.value = []
    recordsHasMore.value = false
    return
  }
  if (reset) {
    recordsPage.value = 1
    records.value = []
  }
  recordsLoading.value = true
  try {
    const page = await fetchAirdropRecords(recordsPage.value, PAGE_SIZE)
    const content = page.content ?? []
    records.value = reset ? content : [...records.value, ...content]
    recordsHasMore.value = (page.totalPages ?? 0) > recordsPage.value
  } catch {
    if (reset) records.value = []
  } finally {
    recordsLoading.value = false
  }
}

async function loadMoreRecords() {
  if (!recordsHasMore.value || recordsLoading.value) return
  recordsPage.value += 1
  await loadRecords(false)
}

async function load() {
  loading.value = true
  error.value = null
  try {
    if (!AUTH_ENABLED) {
      eligibility.value = {
        inviteCount: 0,
        requiredInviteCount: 3,
        inviteTaskCompleted: false,
        hasActiveStaking: false,
        hasPendingAirdrop: false,
        claimableAmount: 0,
        claimableCoinUnit: null,
        eligible: false,
      }
      records.value = []
      return
    }
    const [elig] = await Promise.all([
      fetchAirdropEligibility(),
      loadRecords(true),
    ])
    eligibility.value = elig
  } catch (e) {
    error.value = e instanceof Error ? e.message : t('common.loadFailed')
    eligibility.value = null
  } finally {
    loading.value = false
  }
}

function goInvite() {
  if (task1Done.value) return
  if (!AUTH_ENABLED) {
    router.push({ name: 'login', query: { redirect: '/finance/airdrop' } })
    return
  }
  router.push('/invite')
}

async function onClaim() {
  if (!AUTH_ENABLED) {
    router.push({ name: 'login', query: { redirect: '/finance/airdrop' } })
    return
  }
  if (!canClaim.value) {
    if (claimDisabledReason.value) {
      toast.error(claimDisabledReason.value)
    }
    return
  }
  claiming.value = true
  try {
    await claimAirdrop()
    showSuccessModal.value = true
    await load()
  } catch (e) {
    toast.error(e instanceof Error ? e.message : t('finance.claimFailed'))
  } finally {
    claiming.value = false
  }
}

function closeSuccessModal() {
  showSuccessModal.value = false
}

onMounted(load)
</script>

<template>
  <main class="airdrop-page page-main">
    <div v-if="loading" class="loading-state page-container">
      <div class="spinner" />
    </div>

    <template v-else>
      <section class="airdrop-hero">
        <div class="page-container hero-inner">
          <div class="hero-copy">
            <h1 class="hero-title">{{ t('finance.airdropTitle') }}</h1>
            <p class="hero-rule">{{ t('finance.airdropRule') }}</p>
          </div>
          <div class="hero-art">
            <img
              :src="airdropHero"
              :srcset="`${airdropHero} 1x, ${airdropHero2x} 2x`"
              alt=""
              class="hero-img"
            />
          </div>
        </div>
      </section>

      <section class="airdrop-form-section page-container">
        <h2 class="section-title">{{ t('finance.airdropApplyTitle') }}</h2>

        <div v-if="error && !eligibility" class="panel-error">
          <p>{{ error }}</p>
          <button type="button" class="retry-btn" @click="load">{{ t('common.retry') }}</button>
        </div>

        <template v-else>
          <div class="task-panel dark-card">
            <div class="task-row">
              <div class="task-main">
                <p class="task-label">{{ t('finance.task1Label') }}</p>
                <p class="task-title">{{ t('finance.task1Title') }}</p>
                <p class="task-status" :class="{ 'task-status--done': task1Done }">
                  <span v-if="task1Done" class="task-check" aria-hidden="true">✓</span>
                  {{ inviteProgressText }}
                </p>
              </div>
              <button
                type="button"
                class="task-action-btn"
                :disabled="task1Done"
                @click="goInvite"
              >
                {{ t('finance.goInvite') }}
              </button>
            </div>
          </div>

          <div class="claimable-panel dark-card">
            <span class="claimable-label">{{ t('finance.claimableAmountLabel') }}</span>
            <span class="claimable-value">{{ claimableDisplay }}</span>
          </div>

          <button
            type="button"
            class="claim-btn"
            :disabled="claiming || !canClaim"
            @click="onClaim"
          >
            {{ claiming ? t('common.loading') : t('finance.claimAirdropBtn') }}
          </button>

          <p v-if="claimDisabledReason && AUTH_ENABLED" class="hint-tip">
            {{ claimDisabledReason }}
          </p>
          <p v-else-if="!AUTH_ENABLED" class="hint-tip">
            {{ t('finance.loginToClaim') }}
            <RouterLink to="/login" class="login-link">{{ t('header.login') }}</RouterLink>
          </p>
        </template>
      </section>

      <section v-if="AUTH_ENABLED" class="airdrop-records-section page-container">
        <h2 class="section-title">{{ t('finance.airdropRecordsTitle') }}</h2>

        <div v-if="recordsLoading && records.length === 0" class="records-loading">
          <div class="spinner spinner--sm" />
        </div>

        <div v-else-if="records.length === 0" class="records-empty dark-card">
          {{ t('finance.airdropRecordsEmpty') }}
        </div>

        <ul v-else class="records-list">
          <li v-for="item in records" :key="item.id" class="record-item dark-card">
            <div class="record-main">
              <p class="record-amount">{{ formatRecordAmount(item) }}</p>
              <p class="record-time">
                <span class="record-time-label">{{ recordTimeMeta(item).label }}：</span>
                {{ fmtDateTime(recordTimeMeta(item).time) }}
              </p>
              <p v-if="item.status === 3 && item.auditRemark" class="record-remark">
                {{ t('finance.airdropRecordRejectReason') }}：{{ item.auditRemark }}
              </p>
            </div>
            <span
              class="record-status"
              :class="resolveAirdropRecordStatusClass(item.status)"
            >
              {{ resolveAirdropRecordStatusLabel(item.status, t, te) }}
            </span>
          </li>
        </ul>

        <div v-if="recordsHasMore" class="records-more">
          <button
            type="button"
            class="load-more-btn"
            :disabled="recordsLoading"
            @click="loadMoreRecords"
          >
            {{ recordsLoading ? t('common.loading') : t('finance.airdropRecordsLoadMore') }}
          </button>
        </div>
      </section>
    </template>

    <Teleport to="body">
      <div v-if="showSuccessModal" class="success-overlay" @click.self="closeSuccessModal">
        <div class="success-dialog" role="dialog" aria-modal="true">
          <h3 class="success-title">{{ t('finance.claimSuccessTitle') }}</h3>
          <p class="success-body">{{ t('finance.claimSuccess') }}</p>
          <button type="button" class="success-confirm-btn" @click="closeSuccessModal">
            {{ t('common.confirm') }}
          </button>
        </div>
      </div>
    </Teleport>
  </main>
</template>

<style scoped>
.airdrop-page {
  padding-bottom: var(--space-16);
}

.loading-state {
  padding-top: calc(var(--header-height) + var(--space-16));
  text-align: center;
}

.spinner {
  width: 36px;
  height: 36px;
  margin: 0 auto;
  border-radius: 50%;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-primary);
  animation: spin 0.8s linear infinite;
}

.spinner--sm {
  width: 28px;
  height: 28px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.airdrop-hero {
  padding-top: calc(var(--header-height) + var(--space-10));
  padding-bottom: var(--space-8);
  background: linear-gradient(180deg, rgba(240, 185, 11, 0.04) 0%, transparent 70%);
}

.hero-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  min-height: 280px;
  max-width: 960px;
}

.hero-copy {
  flex: 1;
  min-width: 0;
  max-width: 560px;
}

.hero-title {
  font-size: clamp(40px, 6vw, 64px);
  font-weight: 700;
  color: #fff;
  line-height: 1.1;
  margin: 0 0 var(--space-6);
  letter-spacing: 0.02em;
}

.hero-rule {
  font-size: 15px;
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.75);
  margin: 0;
}

.hero-art {
  flex-shrink: 0;
  width: min(420px, 42vw);
  display: flex;
  justify-content: flex-end;
}

.hero-img {
  width: 100%;
  height: auto;
  max-height: 320px;
  object-fit: contain;
  display: block;
}

.airdrop-form-section,
.airdrop-records-section {
  max-width: 960px;
}

.airdrop-records-section {
  margin-top: var(--space-12);
}

.section-title {
  font-size: 22px;
  font-weight: 600;
  color: #fff;
  text-align: left;
  margin: 0 0 var(--space-6);
}

.task-panel {
  padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-5);
  border-radius: 16px;
}

.claimable-panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-8);
  border-radius: 16px;
}

.claimable-label {
  font-size: 15px;
  color: rgba(255, 255, 255, 0.75);
}

.claimable-value {
  font-size: 18px;
  font-weight: 600;
  color: var(--color-primary);
  word-break: break-all;
  text-align: right;
}

.task-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-6);
}

.task-label {
  margin: 0 0 6px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.45);
}

.task-title {
  margin: 0 0 10px;
  font-size: 16px;
  font-weight: 500;
  color: #fff;
}

.task-status {
  margin: 0;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.45);
}

.task-status--done {
  color: var(--color-primary);
}

.task-check {
  margin-right: 4px;
}

.task-action-btn {
  flex-shrink: 0;
  padding: 10px 22px;
  border: none;
  border-radius: 999px;
  background: var(--color-primary);
  color: #000;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.2s;
}

.task-action-btn:hover:not(:disabled) {
  opacity: 0.9;
}

.task-action-btn:disabled {
  background: rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.35);
  cursor: not-allowed;
  opacity: 1;
}

.claim-btn {
  display: block;
  width: 100%;
  max-width: 360px;
  margin: 0 auto;
  padding: 14px var(--space-8);
  background: var(--color-primary);
  color: #000;
  font-size: 16px;
  font-weight: 600;
  border: none;
  border-radius: 999px;
  cursor: pointer;
  transition: opacity 0.2s;
}

.claim-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.hint-tip {
  margin-top: var(--space-5);
  text-align: center;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.45);
  line-height: 1.5;
}

.login-link {
  color: var(--color-primary);
  margin-left: 4px;
}

.panel-error {
  text-align: center;
  padding: var(--space-8);
  color: var(--color-text-secondary);
}

.retry-btn {
  margin-top: var(--space-4);
  padding: var(--space-2) var(--space-4);
  background: var(--color-primary);
  color: #000;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
}

.records-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.record-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-radius: 16px;
}

.record-amount {
  margin: 0 0 8px;
  font-size: 17px;
  font-weight: 600;
  color: #fff;
}

.record-time {
  margin: 0;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.45);
}

.record-time-label {
  color: rgba(255, 255, 255, 0.35);
}

.record-remark {
  margin: 8px 0 0;
  font-size: 12px;
  color: #f56c6c;
  line-height: 1.5;
}

.record-status {
  flex-shrink: 0;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
}

.status--default {
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.65);
}

.status--pending {
  background: rgba(240, 185, 11, 0.15);
  color: var(--color-primary);
}

.status--success {
  background: rgba(82, 196, 26, 0.15);
  color: #52c41a;
}

.status--reject {
  background: rgba(245, 108, 108, 0.15);
  color: #f56c6c;
}

.records-empty {
  padding: var(--space-10);
  text-align: center;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.45);
  border-radius: 16px;
}

.records-loading {
  padding: var(--space-10);
  text-align: center;
}

.records-more {
  margin-top: var(--space-6);
  text-align: center;
}

.load-more-btn {
  padding: 10px 28px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: transparent;
  color: rgba(255, 255, 255, 0.75);
  font-size: 14px;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}

.load-more-btn:hover:not(:disabled) {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.load-more-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.success-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
  background: rgba(0, 0, 0, 0.65);
}

.success-dialog {
  width: 100%;
  max-width: 400px;
  padding: var(--space-8) var(--space-6);
  border-radius: 16px;
  background: #1a1a1a;
  text-align: center;
}

.success-title {
  margin: 0 0 var(--space-4);
  font-size: 20px;
  font-weight: 600;
  color: #fff;
}

.success-body {
  margin: 0 0 var(--space-8);
  font-size: 14px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.65);
}

.success-confirm-btn {
  min-width: 160px;
  padding: 12px var(--space-8);
  border: none;
  border-radius: 999px;
  background: var(--color-primary);
  color: #000;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}

@media (max-width: 768px) {
  .hero-inner {
    flex-direction: column;
    align-items: flex-start;
    min-height: 0;
  }

  .hero-art {
    width: 100%;
    max-width: 280px;
    margin: 0 auto;
  }

  .task-row {
    flex-direction: column;
    align-items: stretch;
  }

  .task-action-btn {
    width: 100%;
  }

  .record-item {
    flex-direction: column;
    align-items: stretch;
  }

  .record-status {
    align-self: flex-start;
  }
}
</style>
