{% extends "base.html" %}
{% block title %}{{ _("qr_login.page_title") }}{% endblock %}

{% block content %}
<div
  x-data="qrLoginPage()"
  x-init="generateChallenge()"
  class="container mx-auto px-4 py-8 max-w-xl"
>

  <!-- ── Header ─────────────────────────────────────────────────────────── -->
  <header class="mb-8 text-center">
    <h1 class="text-2xl font-bold text-gray-900 dark:text-white flex items-center justify-center gap-2">
      <i class="fas fa-qrcode text-blue-500" aria-hidden="true"></i>
      {{ _("qr_login.heading") }}
    </h1>
    <p class="mt-2 text-sm text-gray-500 dark:text-gray-400">
      {{ _("qr_login.subtitle") }}
    </p>
  </header>

  <!-- ── QR Code Card ───────────────────────────────────────────────────── -->
  <section
    class="bg-white dark:bg-gray-800 shadow rounded-lg p-8 mb-6 text-center"
    aria-labelledby="qr-heading"
  >
    <!-- Pending state: show QR code -->
    <template x-if="status === 'pending'">
      <div>
        <div
          class="mx-auto mb-4 bg-white p-4 inline-block rounded-lg shadow-inner"
          id="qr-container"
          aria-label="{{ _('qr_login.description') }}"
        >
          <img
            :src="qrCodeSvg"
            width="256"
            height="256"
            alt="{{ _('qr_login.description') }}"
            id="qr-image"
          />
        </div>
        <p class="text-sm text-gray-500 dark:text-gray-400 mb-2">
          {{ _("qr_login.description") }}
        </p>
        <div class="flex items-center justify-center gap-2 text-xs text-gray-400 dark:text-gray-500">
          <i class="fas fa-hourglass-half animate-pulse" aria-hidden="true"></i>
          <span x-text="'{{ _("qr_login.time_remaining") }}'.replace('{seconds}', countdown)"></span>
        </div>
        <p class="mt-3 text-sm text-blue-600 dark:text-blue-400">
          <i class="fas fa-spinner fa-spin mr-1" aria-hidden="true"></i>
          {{ _("qr_login.pending_message") }}
        </p>
      </div>
    </template>

    <!-- Claimed state: success -->
    <template x-if="status === 'claimed'">
      <div class="py-8">
        <i class="fas fa-check-circle text-green-500 text-5xl mb-4" aria-hidden="true"></i>
        <p class="text-lg font-semibold text-green-700 dark:text-green-400 mb-2">
          {{ _("qr_login.claimed_message") }}
        </p>
        <p x-show="deviceName" class="text-sm text-gray-500 dark:text-gray-400"
           x-text="'{{ _("qr_login.claimed_device") }}'.replace('{device_name}', deviceName)">
        </p>
      </div>
    </template>

    <!-- Expired state -->
    <template x-if="status === 'expired'">
      <div class="py-8">
        <i class="fas fa-clock text-yellow-500 text-5xl mb-4" aria-hidden="true"></i>
        <p class="text-base text-gray-700 dark:text-gray-300 mb-4">
          {{ _("qr_login.expired_message") }}
        </p>
        <button
          @click="generateChallenge()"
          class="inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition"
          style="min-height:44px;"
        >
          <i class="fas fa-redo mr-2" aria-hidden="true"></i>
          {{ _("qr_login.generate_new") }}
        </button>
      </div>
    </template>

    <!-- Error state -->
    <template x-if="status === 'error'">
      <div class="py-8">
        <i class="fas fa-exclamation-triangle text-red-500 text-5xl mb-4" aria-hidden="true"></i>
        <p class="text-base text-gray-700 dark:text-gray-300 mb-4" x-text="errorMsg"></p>
        <button
          @click="generateChallenge()"
          class="inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition"
          style="min-height:44px;"
        >
          <i class="fas fa-redo mr-2" aria-hidden="true"></i>
          {{ _("qr_login.generate_new") }}
        </button>
      </div>
    </template>
  </section>

  <!-- ── How it works ───────────────────────────────────────────────────── -->
  <section class="bg-white dark:bg-gray-800 shadow rounded-lg p-6">
    <h2 class="text-base font-semibold text-gray-900 dark:text-white mb-3">
      <i class="fas fa-info-circle text-gray-400 mr-2" aria-hidden="true"></i>
      {{ _("qr_login.how_it_works") }}
    </h2>
    <ol class="list-decimal list-inside space-y-2 text-sm text-gray-600 dark:text-gray-400">
      <li>{{ _("qr_login.step_1") }}</li>
      <li>{{ _("qr_login.step_2") }}</li>
      <li>{{ _("qr_login.step_3") }}</li>
    </ol>
  </section>
</div>

<!-- QR code is rendered server-side; no external QR library needed -->

<script>
function qrLoginPage() {
  return {
    status: 'loading',      // loading | pending | claimed | expired | error
    challengeId: null,
    challengeToken: '',
    qrPayload: '',
    qrCodeSvg: '',
    expiresAt: null,
    countdown: 0,
    deviceName: '',
    errorMsg: '',
    _pollTimer: null,
    _countdownTimer: null,
    _ttlSeconds: 0,
    _receivedAt: null,

    _csrfToken() {
      return document.cookie
        .split('; ')
        .find(row => row.startsWith('csrf_token='))
        ?.split('=')[1];
    },

    async generateChallenge() {
      this.status = 'loading';
      this._stopTimers();
      const csrf = this._csrfToken();
      try {
        const res = await fetch('/api/qr-auth/challenge', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            ...(csrf ? { 'X-CSRF-Token': csrf } : {}),
          },
        });
        if (!res.ok) {
          this.status = 'error';
          this.errorMsg = 'Failed to generate QR code. Please try again.';
          return;
        }
        const data = await res.json();
        this.challengeId = data.challenge_id;
        this.challengeToken = data.challenge_token;
        this.qrPayload = data.qr_payload;
        this.qrCodeSvg = data.qr_code_svg;
        this.expiresAt = new Date(data.expires_at);
        this._ttlSeconds = data.ttl_seconds || 120;
        this._receivedAt = Date.now();
        this.status = 'pending';
        this.deviceName = '';

        // Start polling and countdown
        this._startPolling();
        this._startCountdown();
      } catch (_e) {
        this.status = 'error';
        this.errorMsg = 'Network error — please check your connection and try again.';
      }
    },

    _startPolling() {
      this._pollTimer = setInterval(async () => {
        if (this.status !== 'pending') { this._stopTimers(); return; }
        try {
          const res = await fetch(`/api/qr-auth/challenge/${this.challengeId}/status`);
          if (!res.ok) return;
          const data = await res.json();
          if (data.status === 'claimed') {
            this.status = 'claimed';
            this.deviceName = data.device_name || '';
            this._stopTimers();
          } else if (data.status === 'expired') {
            this.status = 'expired';
            this._stopTimers();
          } else if (data.status === 'cancelled') {
            this.status = 'expired';
            this._stopTimers();
          }
        } catch (_e) { /* ignore transient errors */ }
      }, 2000);
    },

    _startCountdown() {
      this._updateCountdown();
      this._countdownTimer = setInterval(() => {
        this._updateCountdown();
        if (this.countdown <= 0 && this.status === 'pending') {
          this.status = 'expired';
          this._stopTimers();
        }
      }, 1000);
    },

    _updateCountdown() {
      if (!this._receivedAt) { this.countdown = 0; return; }
      const elapsed = (Date.now() - this._receivedAt) / 1000;
      const remaining = Math.max(0, Math.floor(this._ttlSeconds - elapsed));
      this.countdown = remaining;
    },

    _stopTimers() {
      if (this._pollTimer) { clearInterval(this._pollTimer); this._pollTimer = null; }
      if (this._countdownTimer) { clearInterval(this._countdownTimer); this._countdownTimer = null; }
    },
  };
}
</script>
{% endblock %}
