<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import imageCompression from 'browser-image-compression';
import api from '../api';
import GoldSpinner from '../components/GoldSpinner.vue';
import { useDepositNotifications } from '../composables/useDepositNotifications';

const router = useRouter();
const route = useRoute();
const { t } = useI18n();
const { trackPendingOrder } = useDepositNotifications();

const reapplyOrderId = computed(() => {
  const id = route.query.orderId;
  return typeof id === 'string' && id ? id : '';
});
const isReapply = computed(() => !!reapplyOrderId.value);

interface PaymentMethod {
  id: string;
  methodType: string;
  bankName: string | null;
  accountHolder: string | null;
  accountNumber: string | null;
  usdtAddress: string | null;
  qrCodeUrl: string | null;
  displayName: string | null;
}

const methodType = ref<'BANK' | 'USDT'>('BANK');
const methods = ref<PaymentMethod[]>([]);
const selectedMethod = ref<PaymentMethod | null>(null);
const amount = ref<string>('');
const screenshotFile = ref<File | null>(null);
const screenshotPreview = ref<string>('');
const loading = ref(true);
const submitting = ref(false);
const success = ref(false);
const orderNo = ref('');
const compressing = ref(false);

const bankMethods = computed(() => methods.value.filter((m) => m.methodType === 'BANK'));
const usdtMethods = computed(() => methods.value.filter((m) => m.methodType === 'USDT'));
const currentMethods = computed(() => methodType.value === 'BANK' ? bankMethods.value : usdtMethods.value);

function applyReapplyQuery() {
  const type = route.query.methodType;
  if (type === 'BANK' || type === 'USDT') {
    methodType.value = type;
  }

  const methodId = typeof route.query.methodId === 'string' ? route.query.methodId : '';
  if (methodId) {
    const match = methods.value.find((m) => m.id === methodId);
    if (match) {
      selectedMethod.value = match;
    }
  }

  if (!selectedMethod.value && currentMethods.value.length) {
    selectedMethod.value = currentMethods.value[0];
  }

  const amountQuery = typeof route.query.amount === 'string' ? route.query.amount : '';
  const parsedAmount = parseFloat(amountQuery);
  if (amountQuery && parsedAmount > 0) {
    amount.value = amountQuery;
  }
}

async function fetchMethods() {
  loading.value = true;
  try {
    const { data } = await api.get('/player/payment-methods');
    methods.value = (data.data ?? []).map((m: any) => ({ ...m, id: String(m.id) }));
    if (isReapply.value) {
      applyReapplyQuery();
    } else if (currentMethods.value.length) {
      selectedMethod.value = currentMethods.value[0];
    }
  } catch { /* */ } finally {
    loading.value = false;
  }
}

function switchType(type: 'BANK' | 'USDT') {
  methodType.value = type;
  selectedMethod.value = currentMethods.value.length ? currentMethods.value[0] : null;
}

function selectMethod(m: PaymentMethod) {
  selectedMethod.value = m;
}

const MAX_ORIGINAL_BYTES = 10 * 1024 * 1024;
const MAX_SCREENSHOT_BYTES = 300 * 1024;

async function compressScreenshot(file: File): Promise<File> {
  const baseOptions = {
    maxSizeMB: 0.3,
    maxWidthOrHeight: 1200,
    useWebWorker: true,
    maxIteration: 10,
    fileType: 'image/webp',
  } as const;

  const attempts = [
    { ...baseOptions, initialQuality: 0.8 },
    { ...baseOptions, initialQuality: 0.6, maxWidthOrHeight: 1000 },
  ];

  let compressed: File | null = null;
  for (const options of attempts) {
    try {
      compressed = (await imageCompression(file, options)) as File;
      if (compressed.size <= MAX_SCREENSHOT_BYTES) {
        break;
      }
    } catch (err) {
      console.error('Compression attempt failed:', err);
    }
  }

  if (!compressed) {
    throw new Error('COMPRESS_FAILED');
  }

  // 重命名文件后缀为 .webp
  const name = file.name.replace(/\.[^/.]+$/, "") + '.webp';
  return new File([compressed], name, {
    type: 'image/webp',
    lastModified: Date.now(),
  });
}

async function handleFileChange(event: Event) {
  const input = event.target as HTMLInputElement;
  const file = input.files?.[0];
  if (!file) return;

  if (!file.type.startsWith('image/')) {
    alert(t('recharge.file_must_be_image'));
    input.value = '';
    return;
  }

  if (file.size > MAX_ORIGINAL_BYTES) {
    alert(t('recharge.file_too_large'));
    input.value = '';
    return;
  }

  compressing.value = true;
  try {
    const compressed = await compressScreenshot(file);
    screenshotFile.value = compressed;
    screenshotPreview.value = URL.createObjectURL(compressed);
  } catch {
    alert(t('recharge.compress_failed'));
    screenshotFile.value = null;
    screenshotPreview.value = '';
    input.value = '';
  } finally {
    compressing.value = false;
  }
}

function removeScreenshot() {
  screenshotFile.value = null;
  screenshotPreview.value = '';
}

async function handleSubmit() {
  if (!selectedMethod.value) {
    alert(t('recharge.select_method'));
    return;
  }
  const amt = parseFloat(amount.value);
  if (!amt || amt <= 0) {
    alert(t('recharge.enter_amount'));
    return;
  }
  if (!screenshotFile.value) {
    alert(t('recharge.upload_screenshot'));
    return;
  }
  if (screenshotFile.value.size > MAX_SCREENSHOT_BYTES) {
    alert(t('recharge.compress_failed'));
    return;
  }

  submitting.value = true;
  try {
    const fd = new FormData();
    fd.append('amount', String(amt));
    fd.append('screenshot', screenshotFile.value);

    if (isReapply.value) {
      fd.append('paymentMethodId', selectedMethod.value.id);
      const { data } = await api.post(`/player/deposit-orders/${reapplyOrderId.value}/reapply`, fd);
      const result = data.data;
      orderNo.value = result?.orderNo ?? '';
      if (result?.id) trackPendingOrder(String(result.id));
      success.value = true;
      return;
    }

    fd.append('paymentMethodId', selectedMethod.value.id);
    const { data } = await api.post('/player/deposit-orders', fd);
    const result = data.data;
    orderNo.value = result?.orderNo ?? '';
    if (result?.id) trackPendingOrder(String(result.id));
    success.value = true;
  } catch (e: any) {
    alert(e.response?.data?.message || t('recharge.submit_failed'));
  } finally {
    submitting.value = false;
  }
}

function goHistory() {
  router.push('/wallet/recharge/history');
}

function goBack() {
  router.back();
}

function resetForm() {
  success.value = false;
  amount.value = '';
  screenshotFile.value = null;
  screenshotPreview.value = '';
  orderNo.value = '';
}

function copyText(text: string) {
  navigator.clipboard?.writeText(text);
}

function formatCardNumber(num: string | null): string {
  if (!num) return '—';
  const digits = num.replace(/\s/g, '');
  return digits.replace(/(\d{4})(?=\d)/g, '$1 ').trim();
}

onMounted(fetchMethods);
</script>

<template>
  <div class="recharge-page">
    <div class="page-header">
      <button class="back-btn" @click="goBack">‹</button>
      <h2>{{ t('recharge.title') }}</h2>
      <button class="history-btn" @click="goHistory">{{ t('recharge.history') }}</button>
    </div>

    <div v-if="loading" class="state">
      <GoldSpinner :size="36" />
    </div>

    <div v-else-if="success" class="success-state">
      <div class="success-icon">✓</div>
      <h3>{{ t('recharge.submitted') }}</h3>
      <p class="order-no">{{ orderNo }}</p>
      <p class="success-hint">{{ t('recharge.pending_review') }}</p>
      <button v-if="isReapply" class="btn-primary" @click="goHistory">{{ t('recharge.back_to_history') }}</button>
      <button v-else class="btn-primary" @click="resetForm">{{ t('recharge.new_recharge') }}</button>
    </div>

    <template v-else>
      <div v-if="isReapply" class="reapply-banner">{{ t('recharge.reapply_hint') }}</div>
      <div class="type-tabs">
        <button
          :class="['tab', methodType === 'BANK' && 'active']"
          @click="switchType('BANK')"
        >{{ t('recharge.bank_transfer') }}</button>
        <button
          :class="['tab', methodType === 'USDT' && 'active']"
          @click="switchType('USDT')"
        >USDT</button>
      </div>

      <div v-if="currentMethods.length" class="methods-list">
        <button
          v-for="m in currentMethods"
          :key="m.id"
          :class="['method-pill', selectedMethod?.id === m.id && 'selected']"
          @click="selectMethod(m)"
        >
          <span class="pill-name">{{ m.displayName || m.bankName || m.usdtAddress }}</span>
          <span v-if="m.methodType === 'BANK'" class="pill-sub">{{ m.accountHolder }}</span>
        </button>
      </div>
      <div v-else class="empty-methods">{{ t('recharge.no_methods') }}</div>

      <div v-if="selectedMethod && selectedMethod.methodType === 'BANK'" class="bank-card-wrap">
        <div class="bank-card-face">
          <div class="bank-card-shine" aria-hidden="true" />
          <div class="bank-card-deco bank-card-deco--1" aria-hidden="true" />
          <div class="bank-card-deco bank-card-deco--2" aria-hidden="true" />
          <div class="bank-card-top">
            <div class="bank-card-bank">{{ selectedMethod.bankName }}</div>
          </div>
          <div class="bank-card-number-row">
            <span class="bank-card-number">{{ formatCardNumber(selectedMethod.accountNumber) }}</span>
            <button
              type="button"
              class="bank-card-copy"
              :aria-label="t('recharge.account_number')"
              @click="copyText(selectedMethod.accountNumber || '')"
            >
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <rect x="9" y="9" width="13" height="13" rx="2" />
                <path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" />
              </svg>
            </button>
          </div>
          <div class="bank-card-bottom">
            <div class="bank-card-holder">
              <span class="bank-card-holder-label">{{ t('recharge.account_holder') }}</span>
              <span class="bank-card-holder-name">{{ selectedMethod.accountHolder }}</span>
            </div>
            <div class="bank-card-type">DEBIT</div>
          </div>
        </div>
      </div>

      <div v-else-if="selectedMethod" class="method-info">
        <template v-if="selectedMethod.methodType !== 'BANK'">
          <div class="info-row">
            <span class="info-label">{{ t('recharge.usdt_address') }}</span>
            <span class="info-value copyable" @click="copyText(selectedMethod!.usdtAddress || '')">
              {{ selectedMethod.usdtAddress }}
              <svg class="copy-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>
            </span>
          </div>
          <div v-if="selectedMethod.qrCodeUrl" class="qr-container">
            <img :src="selectedMethod.qrCodeUrl" class="qr-image" />
          </div>
        </template>
      </div>

      <div class="form-section">
        <label>{{ t('recharge.amount_label') }}</label>
        <input
          v-model="amount"
          type="number"
          inputmode="decimal"
          :placeholder="t('recharge.amount_placeholder')"
          class="amount-input"
        />
      </div>

      <div class="form-section">
        <label>{{ t('recharge.screenshot_label') }}</label>
        <div v-if="screenshotPreview" class="screenshot-preview">
          <img :src="screenshotPreview" />
          <button class="remove-btn" @click="removeScreenshot">✕</button>
        </div>
        <label v-else class="upload-area">
          <input type="file" accept="image/*" @change="handleFileChange" :disabled="compressing" />
          <div v-if="compressing" class="compress-hint">{{ t('recharge.compressing') }}...</div>
          <div v-else class="upload-hint">{{ t('recharge.upload_hint') }}</div>
        </label>
      </div>

      <button
        class="btn-submit"
        :disabled="submitting || !selectedMethod || !amount || !screenshotFile"
        @click="handleSubmit"
      >
        <span v-if="submitting">{{ t('recharge.submitting') }}...</span>
        <span v-else>{{ t('recharge.submit') }}</span>
      </button>
    </template>
  </div>
</template>

<style scoped>
.recharge-page { padding: 0 0 24px; }

.page-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 0 12px;
}
.page-header h2 { margin: 0; font-size: 16px; font-weight: 700; }
.back-btn { background: none; border: none; color: var(--primary-light); font-size: 22px; cursor: pointer; padding: 0 6px; }
.history-btn { background: none; border: none; color: var(--primary-light); font-size: 12px; cursor: pointer; font-weight: 600; }

.state { display: flex; justify-content: center; padding: 48px; }

.reapply-banner {
  margin-bottom: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 12px;
  line-height: 1.45;
  color: #ffd0d0;
  background: rgba(245, 108, 108, 0.12);
  border: 1px solid rgba(245, 108, 108, 0.25);
}

.type-tabs {
  display: flex; margin-bottom: 12px;
  border-radius: 6px; overflow: hidden;
  border: 1px solid rgba(212, 175, 55, 0.2);
}
.tab {
  flex: 1; padding: 8px; border: none;
  background: rgba(20, 20, 20, 0.8);
  color: var(--text-muted); font-weight: 700; font-size: 13px;
  cursor: pointer; transition: all 0.2s;
}
.tab.active {
  background: var(--primary-light); color: #000;
}

.methods-list {
  display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px;
}
.method-pill {
  display: flex; flex-direction: column; gap: 1px;
  background: rgba(20, 20, 20, 0.8);
  border: 1px solid var(--border);
  border-radius: 6px; padding: 6px 12px;
  text-align: left; cursor: pointer;
  transition: border-color 0.15s;
}
.method-pill.selected {
  border-color: var(--primary-light);
  background: rgba(212, 175, 55, 0.06);
}
.pill-name { font-weight: 700; font-size: 12px; color: var(--text); }
.pill-sub { font-size: 10px; color: var(--text-muted); }
.empty-methods { text-align: center; color: var(--text-muted); padding: 20px; font-size: 12px; }

.bank-card-wrap {
  margin-bottom: 16px;
  perspective: 800px;
}

.bank-card-face {
  position: relative;
  aspect-ratio: 2 / 1;
  border-radius: 14px;
  padding: 14px 18px 12px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  background:
    radial-gradient(ellipse 80% 60% at 100% 0%, rgba(212, 175, 55, 0.22), transparent 55%),
    radial-gradient(ellipse 50% 50% at 0% 100%, rgba(212, 175, 55, 0.1), transparent 50%),
    linear-gradient(135deg, #2a2218 0%, #1a1610 35%, #12100c 70%, #0a0908 100%);
  border: 1px solid rgba(212, 175, 55, 0.35);
  box-shadow:
    0 8px 24px rgba(0, 0, 0, 0.55),
    0 2px 8px rgba(212, 175, 55, 0.12),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

.bank-card-shine {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    115deg,
    transparent 30%,
    rgba(255, 255, 255, 0.04) 45%,
    rgba(255, 255, 255, 0.08) 50%,
    rgba(255, 255, 255, 0.04) 55%,
    transparent 70%
  );
  pointer-events: none;
}

.bank-card-deco {
  position: absolute;
  border-radius: 50%;
  border: 1px solid rgba(212, 175, 55, 0.12);
  pointer-events: none;
}

.bank-card-deco--1 {
  width: 180px;
  height: 180px;
  right: -60px;
  bottom: -80px;
  background: radial-gradient(circle, rgba(212, 175, 55, 0.08), transparent 70%);
}

.bank-card-deco--2 {
  width: 100px;
  height: 100px;
  right: 40px;
  bottom: 20px;
  border-color: rgba(212, 175, 55, 0.08);
}

.bank-card-top,
.bank-card-number-row,
.bank-card-bottom {
  position: relative;
  z-index: 1;
}

.bank-card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.bank-card-bank {
  font-size: 15px;
  font-weight: 800;
  color: #fff;
  text-align: right;
  letter-spacing: 0.5px;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
  line-height: 1.3;
  max-width: 58%;
  word-break: break-all;
}

.bank-card-number-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 4px 0 2px;
}

.bank-card-number {
  font-family: 'SF Mono', 'Consolas', 'Courier New', monospace;
  font-size: clamp(15px, 4.2vw, 19px);
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--primary-light);
  text-shadow: 0 0 12px rgba(240, 216, 117, 0.25);
  word-break: break-all;
  line-height: 1.3;
}

.bank-card-copy {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: 1px solid rgba(212, 175, 55, 0.35);
  background: rgba(0, 0, 0, 0.25);
  color: var(--primary-light);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
}

.bank-card-copy svg {
  width: 16px;
  height: 16px;
}

.bank-card-copy:active {
  opacity: 0.65;
  background: rgba(212, 175, 55, 0.12);
}

.bank-card-bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
}

.bank-card-holder {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.bank-card-holder-label {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
}

.bank-card-holder-name {
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.04em;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  word-break: break-all;
}

.bank-card-type {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.18em;
  color: rgba(212, 175, 55, 0.55);
  font-style: italic;
}

.method-info {
  background: rgba(17, 17, 17, 0.9);
  border-radius: 8px; padding: 10px 12px;
  margin-bottom: 12px;
  border: 1px solid var(--border);
}
.info-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 6px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.info-row:last-child { border-bottom: none; }
.info-label { font-size: 11px; color: var(--text-muted); flex-shrink: 0; }
.info-value {
  font-size: 13px; font-weight: 600;
  word-break: break-all; text-align: right;
  max-width: 60%;
}
.copyable {
  cursor: pointer; color: var(--primary-light);
  display: inline-flex; align-items: center; gap: 4px;
}
.copyable:active { opacity: 0.6; }
.copy-icon { width: 14px; height: 14px; flex-shrink: 0; }
.qr-container { display: flex; justify-content: center; padding: 8px 0 4px; }
.qr-image { width: 140px; height: 140px; object-fit: contain; border-radius: 6px; background: #fff; padding: 6px; }

.form-section { margin-bottom: 12px; }
.form-section label {
  display: block; font-size: 11px; font-weight: 700;
  color: var(--text-muted); margin-bottom: 4px;
}
.amount-input {
  width: 100%; padding: 10px; background: #111;
  border: 1px solid var(--border); border-radius: 6px;
  color: #fff; font-size: 16px; font-weight: 700;
  box-sizing: border-box;
}
.amount-input:focus { border-color: var(--primary-light); outline: none; }

.upload-area {
  border: 1px dashed rgba(212, 175, 55, 0.3);
  border-radius: 6px; padding: 16px;
  text-align: center; position: relative;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.upload-area input[type="file"] { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.upload-hint { font-size: 12px; color: var(--text-muted); }
.compress-hint { font-size: 12px; color: var(--primary-light); }
.screenshot-preview { position: relative; display: inline-block; }
.screenshot-preview img { max-width: 100%; max-height: 160px; border-radius: 6px; }
.remove-btn {
  position: absolute; top: 4px; right: 4px;
  background: rgba(0,0,0,0.7); border: none; color: #fff;
  width: 20px; height: 20px; border-radius: 50%;
  cursor: pointer; font-size: 11px;
}

.btn-submit {
  width: 100%; padding: 12px;
  background: linear-gradient(135deg, #f0d060, #d4a830);
  color: #000; border: none; border-radius: 6px;
  font-size: 14px; font-weight: 800;
  cursor: pointer; margin-top: 8px;
  box-shadow: 0 2px 8px rgba(212, 175, 55, 0.2);
}
.btn-submit:disabled { opacity: 0.4; cursor: not-allowed; }

.success-state { text-align: center; padding: 40px 16px; }
.success-icon { font-size: 40px; color: #67c23a; margin-bottom: 10px; }
.success-state h3 { margin: 0 0 6px; font-size: 16px; }
.order-no { font-family: monospace; color: var(--primary-light); font-size: 13px; margin: 4px 0; }
.success-hint { font-size: 12px; color: var(--text-muted); margin-bottom: 20px; }
.btn-primary {
  background: linear-gradient(135deg, #f0d060, #d4a830);
  color: #000; border: none; border-radius: 6px;
  padding: 10px 20px; font-weight: 700; font-size: 13px; cursor: pointer;
}
</style>
