"use client";

import { useEffect, useState } from "react";

const VAPID_PUBLIC_KEY = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY;

function urlBase64ToUint8Array(base64String: string): Uint8Array<ArrayBuffer> {
  const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
  const raw = window.atob(base64);
  // TS5+: PushManager.subscribe wants Uint8Array<ArrayBuffer>, not the
  // generic Uint8Array<ArrayBufferLike> default. Allocate the buffer
  // explicitly so the narrow type is preserved.
  const buffer = new ArrayBuffer(raw.length);
  const arr = new Uint8Array(buffer);
  for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);
  return arr;
}

// Push permission opt-in CTA. We don't auto-prompt — Chrome ignores
// auto-prompts and Safari just throws. The user explicitly clicks Enable
// to grant + subscribe.
function PushOptIn() {
  const [supported, setSupported] = useState(false);
  const [state, setState] = useState<"unknown" | "granted" | "denied" | "default">("unknown");
  const [working, setWorking] = useState(false);

  useEffect(() => {
    if (typeof window === "undefined") return;
    const ok = "Notification" in window && "serviceWorker" in navigator && "PushManager" in window;
    setSupported(ok);
    if (ok) setState(Notification.permission);
  }, []);

  async function handleEnable() {
    setWorking(true);
    try {
      const perm = await Notification.requestPermission();
      setState(perm);
      if (perm !== "granted") return;
      const reg = await navigator.serviceWorker.ready;
      let sub = await reg.pushManager.getSubscription();
      if (!sub && VAPID_PUBLIC_KEY) {
        sub = await reg.pushManager.subscribe({
          userVisibleOnly: true,
          applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY),
        });
      }
      if (sub) {
        await fetch("/api/push/subscribe", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(sub.toJSON()),
        });
      }
    } catch (err) {
      console.error("[push] opt-in failed", err);
    } finally {
      setWorking(false);
    }
  }

  if (!supported) return null;
  return (
    <div className="bg-surface rounded-xl border border-surface-light p-5 flex items-center justify-between gap-4">
      <div className="flex-1">
        <p className="text-white font-medium">Push Notifications</p>
        <p className="text-text-muted text-sm mt-0.5">
          {state === "granted"
            ? "Enabled — you'll get push alerts on this device."
            : state === "denied"
              ? "Blocked — enable notifications for this site in your browser settings."
              : "Get instant alerts for messages, bookings, and tips on this device."}
        </p>
      </div>
      {state !== "granted" && state !== "denied" && (
        <button
          onClick={handleEnable}
          disabled={working}
          className="bg-gold hover:bg-gold-light text-black font-semibold px-4 py-2 rounded-lg transition-colors disabled:opacity-50 shrink-0"
        >
          {working ? "Enabling..." : "Enable"}
        </button>
      )}
    </div>
  );
}

interface NotificationPreference {
  key: string;
  label: string;
  description: string;
  enabled: boolean;
}

const PREF_DEFS: { key: string; label: string; description: string }[] = [
  { key: "weekly_digest", label: "Weekly Email Digest", description: "Receive a weekly email with new escorts matching your preferences" },
  { key: "favorite_online", label: "Favourite Online Alerts", description: "Get notified when your favourited escorts go online" },
  { key: "blog_posts", label: "New Blog Posts", description: "Get notified when new blog posts are published" },
  { key: "new_message", label: "New Message Received", description: "Receive an email when someone sends you a new message" },
  { key: "booking_request", label: "Booking Request Received", description: "Receive an email when a new booking request comes in" },
  { key: "review_received", label: "Review Received", description: "Receive an email when someone leaves a review on your profile" },
  { key: "credit_balance_low", label: "Credit Balance Low", description: "Receive an email when your credit balance drops below 10 credits" },
];

export default function NotificationSettingsPage() {
  const [preferences, setPreferences] = useState<NotificationPreference[]>(
    PREF_DEFS.map((p) => ({ ...p, enabled: false }))
  );
  const [saving, setSaving] = useState(false);
  const [saved, setSaved] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Load real preferences on mount. Earlier the page was a pure stub —
  // toggles flipped optimistically and a setTimeout pretended to save.
  useEffect(() => {
    fetch("/api/user/notification-preferences")
      .then((r) => (r.ok ? r.json() : Promise.reject(new Error(`HTTP ${r.status}`))))
      .then((d) => {
        const stored = d?.data ?? {};
        setPreferences(PREF_DEFS.map((p) => ({ ...p, enabled: !!stored[p.key] })));
      })
      .catch((e) => setError(e instanceof Error ? e.message : "Failed to load"));
  }, []);

  const toggle = (key: string) => {
    setPreferences((prev) =>
      prev.map((p) => (p.key === key ? { ...p, enabled: !p.enabled } : p))
    );
    setSaved(false);
  };

  const handleSave = async () => {
    setSaving(true);
    setError(null);
    try {
      const body = Object.fromEntries(preferences.map((p) => [p.key, p.enabled]));
      const res = await fetch("/api/user/notification-preferences", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });
      if (!res.ok) throw new Error(`Save failed (${res.status})`);
      setSaved(true);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Failed to save");
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="max-w-2xl mx-auto py-8 space-y-6">
      <div>
        <h1 className="text-2xl font-bold text-white">Notification Preferences</h1>
        <p className="text-text-muted mt-1">
          Choose how you want to be notified about activity on AdultWorld.
        </p>
      </div>

      <PushOptIn />

      <div className="bg-surface rounded-xl border border-surface-light divide-y divide-surface-light">
        {preferences.map((pref) => (
          <div key={pref.key} className="p-5 flex items-center justify-between gap-4">
            <div className="flex-1">
              <p className="text-white font-medium">{pref.label}</p>
              <p className="text-text-muted text-sm mt-0.5">{pref.description}</p>
            </div>
            <button
              onClick={() => toggle(pref.key)}
              className={`relative w-12 h-7 rounded-full transition-colors shrink-0 ${
                pref.enabled ? "bg-gold" : "bg-surface-light"
              }`}
            >
              <span
                className={`absolute top-1 left-1 w-5 h-5 rounded-full bg-white transition-transform shadow ${
                  pref.enabled ? "translate-x-5" : ""
                }`}
              />
            </button>
          </div>
        ))}
      </div>

      <div className="bg-surface rounded-xl border border-surface-light p-5">
        <h2 className="text-white font-medium mb-2">Email Digest Preview</h2>
        <p className="text-text-muted text-sm">
          If enabled, the weekly digest will include:
        </p>
        <ul className="text-text-muted text-sm mt-2 space-y-1">
          <li className="flex items-center gap-2">
            <span className="w-1.5 h-1.5 rounded-full bg-gold shrink-0" />
            New escorts in your area matching your previous search criteria
          </li>
          <li className="flex items-center gap-2">
            <span className="w-1.5 h-1.5 rounded-full bg-gold shrink-0" />
            Special promotions and discounts on credits
          </li>
          <li className="flex items-center gap-2">
            <span className="w-1.5 h-1.5 rounded-full bg-gold shrink-0" />
            Featured content from your favourited escorts
          </li>
        </ul>
      </div>

      {error && (
        <div className="bg-red-500/10 border border-red-500/40 text-red-300 rounded-lg p-3 text-sm">
          {error}
        </div>
      )}
      <div className="flex items-center gap-4">
        <button
          onClick={handleSave}
          disabled={saving}
          className="bg-gold hover:bg-gold-light text-black font-semibold px-8 py-3 rounded-xl transition-all disabled:opacity-50"
        >
          {saving ? "Saving..." : "Save Preferences"}
        </button>
        {saved && (
          <span className="text-green-400 text-sm flex items-center gap-1">
            <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
              <path
                fillRule="evenodd"
                d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
                clipRule="evenodd"
              />
            </svg>
            Preferences saved!
          </span>
        )}
      </div>
    </div>
  );
}
