'use client';

import { useEffect, useState } from 'react';
import { useAuth } from '@/contexts/AuthContext';

// Push opt-in banner. Same gating as InstallPrompt: only after 2 Reads.
// We treat the result tri-state:
//   granted  → POST the PushSubscription to /api/push/subscribe
//   denied   → remember it; never ask again
//   default  → user dismissed; ask again next session

const READS_KEY = 'vyndr_reads_completed';
const ASKED_KEY = 'vyndr_push_asked';
const DENIED_KEY = 'vyndr_push_denied';
const REQUIRED_READS = 2;

function readsCompleted(): number {
  if (typeof window === 'undefined') return 0;
  const raw = window.localStorage.getItem(READS_KEY);
  return raw ? parseInt(raw, 10) || 0 : 0;
}

function base64UrlToArrayBuffer(base64Url: string): ArrayBuffer {
  const padding = '='.repeat((4 - (base64Url.length % 4)) % 4);
  const base64 = (base64Url + padding).replace(/-/g, '+').replace(/_/g, '/');
  const raw = window.atob(base64);
  const buffer = new ArrayBuffer(raw.length);
  const view = new Uint8Array(buffer);
  for (let i = 0; i < raw.length; i += 1) view[i] = raw.charCodeAt(i);
  return buffer;
}

export default function PushPrompt() {
  const { user } = useAuth();
  const [visible, setVisible] = useState(false);
  const [busy, setBusy] = useState(false);

  useEffect(() => {
    if (!user) return;
    if (typeof window === 'undefined') return;
    if (!('serviceWorker' in navigator) || !('PushManager' in window)) return;
    if (Notification.permission === 'granted' || Notification.permission === 'denied') return;
    if (window.localStorage.getItem(DENIED_KEY)) return;
    if (window.sessionStorage.getItem(ASKED_KEY)) return;
    if (readsCompleted() < REQUIRED_READS) return;
    setVisible(true);
  }, [user]);

  const handleEnable = async () => {
    setBusy(true);
    window.sessionStorage.setItem(ASKED_KEY, '1');
    try {
      const permission = await Notification.requestPermission();
      if (permission === 'denied') {
        window.localStorage.setItem(DENIED_KEY, '1');
        setVisible(false);
        return;
      }
      if (permission !== 'granted') {
        setVisible(false);
        return;
      }
      const registration = await navigator.serviceWorker.ready;
      const vapidKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY;
      if (!vapidKey) {
        console.warn('[push] NEXT_PUBLIC_VAPID_PUBLIC_KEY not set');
        setVisible(false);
        return;
      }
      const subscription = await registration.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: base64UrlToArrayBuffer(vapidKey),
      });
      await fetch('/api/push/subscribe', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ subscription }),
      });
      setVisible(false);
    } catch (err) {
      console.warn('[push] subscribe failed:', err);
      setVisible(false);
    } finally {
      setBusy(false);
    }
  };

  const handleDismiss = () => {
    window.sessionStorage.setItem(ASKED_KEY, '1');
    setVisible(false);
  };

  if (!visible) return null;

  return (
    <div
      role="dialog"
      aria-label="Enable notifications"
      className="fixed bottom-24 left-4 right-4 z-50 mx-auto max-w-md rounded-lg border p-4 shadow-lg"
      style={{
        background: 'var(--bg-surface)',
        borderColor: 'var(--border-light)',
        color: 'var(--text-primary)',
      }}
    >
      <div className="flex items-start justify-between gap-3">
        <div className="flex-1">
          <div className="text-sm font-semibold">Get notified on cascades + A+ alerts</div>
          <div className="mt-1 text-xs" style={{ color: 'var(--text-secondary)' }}>
            We&apos;ll ping you when a prop drops to A+, a cascade triggers, or your reads resolve.
          </div>
        </div>
        <button
          type="button"
          onClick={handleDismiss}
          aria-label="Dismiss notification prompt"
          className="rounded p-1 text-xs"
          style={{ color: 'var(--text-tertiary)' }}
        >
          ✕
        </button>
      </div>
      <button
        type="button"
        onClick={handleEnable}
        disabled={busy}
        className="mt-3 w-full rounded px-3 py-2 text-sm font-semibold disabled:opacity-50"
        style={{ background: 'var(--grade-a)', color: 'var(--bg-0)' }}
      >
        {busy ? 'Enabling…' : 'Enable notifications'}
      </button>
    </div>
  );
}
