"use client";

import { useCallback, useEffect, useState } from "react";
import { Bell, BellRing, BellOff } from "lucide-react";
import Swal from "sweetalert2";

// VAPID 공개키(base64url) → Uint8Array
function urlBase64ToUint8Array(base64String: string): Uint8Array {
  const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
  const raw = atob(base64);
  const arr = new Uint8Array(raw.length);
  for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);
  return arr;
}

type Perm = "unsupported" | "default" | "granted" | "denied";

// PWA 설치 사용자에게 '새 품목 출고요청 가능' 알림을 받게 해주는 구독 버튼.
export function PushOptIn() {
  const [perm, setPerm] = useState<Perm>("unsupported");
  const [busy, setBusy] = useState(false);

  const supported =
    typeof window !== "undefined" &&
    "serviceWorker" in navigator &&
    "PushManager" in window &&
    "Notification" in window;

  // 실제 구독 + 서버 저장
  const subscribe = useCallback(async (): Promise<boolean> => {
    try {
      const reg = await navigator.serviceWorker.ready;
      const res = await fetch("/api/m/push/vapid");
      if (!res.ok) return false;
      const { publicKey } = await res.json();
      if (!publicKey) return false;

      let sub = await reg.pushManager.getSubscription();
      if (!sub) {
        sub = await reg.pushManager.subscribe({
          userVisibleOnly: true,
          applicationServerKey: urlBase64ToUint8Array(publicKey) as BufferSource,
        });
      }
      const save = await fetch("/api/m/push/subscribe", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ subscription: sub.toJSON(), userAgent: navigator.userAgent }),
      });
      return save.ok;
    } catch {
      return false;
    }
  }, []);

  useEffect(() => {
    if (!supported) { setPerm("unsupported"); return; }
    const p = Notification.permission as "default" | "granted" | "denied";
    setPerm(p);
    // 이미 허용된 경우 — 구독 정보가 서버에 없을 수 있으니 조용히 저장 갱신
    if (p === "granted") void subscribe();
  }, [supported, subscribe]);

  const enable = async () => {
    setBusy(true);
    try {
      const p = await Notification.requestPermission();
      setPerm(p as Perm);
      if (p === "granted") {
        const ok = await subscribe();
        Swal.fire({
          icon: ok ? "success" : "error",
          title: ok ? "알림이 켜졌어요" : "알림 등록 실패",
          text: ok ? "테스트 알림이 곧 도착합니다." : "잠시 후 다시 시도해주세요.",
          timer: ok ? 1800 : undefined,
          showConfirmButton: !ok,
        });
      } else {
        Swal.fire({ icon: "warning", title: "알림이 허용되지 않았습니다", text: "기기/브라우저 설정에서 알림을 허용해주세요." });
      }
    } finally {
      setBusy(false);
    }
  };

  const sendTest = async () => {
    setBusy(true);
    try {
      const res = await fetch("/api/m/push/test", { method: "POST" });
      const j = await res.json().catch(() => ({}));
      Swal.fire({
        icon: j?.sent > 0 ? "success" : "warning",
        title: j?.sent > 0 ? "테스트 알림 발송됨" : "발송된 알림이 없습니다",
        text: j?.sent > 0 ? "잠시 후 알림을 확인하세요." : "구독 정보가 없거나 기기가 알림을 차단했을 수 있습니다.",
      });
    } finally { setBusy(false); }
  };

  if (!supported || perm === "unsupported") return null;

  if (perm === "granted") {
    return (
      <span className="inline-flex items-center gap-1.5 text-xs text-emerald-700 font-semibold">
        <BellRing size={14} /> 알림 켜짐
        <button type="button" onClick={sendTest} disabled={busy}
          className="ml-1 px-2 py-0.5 rounded bg-emerald-50 text-emerald-700 hover:bg-emerald-100 disabled:opacity-50 text-[11px] font-bold">
          테스트
        </button>
      </span>
    );
  }
  if (perm === "denied") {
    return (
      <span className="inline-flex items-center gap-1 text-xs text-slate-400" title="브라우저/앱 설정에서 알림을 허용해주세요.">
        <BellOff size={14} /> 알림 차단됨
      </span>
    );
  }
  return (
    <button
      type="button"
      onClick={enable}
      disabled={busy}
      className="inline-flex items-center gap-1 h-8 px-3 rounded-lg bg-amber-100 text-amber-800 text-xs font-bold hover:bg-amber-200 disabled:opacity-50"
      title="새 품목이 출고요청 가능해지면 푸시 알림을 받습니다."
    >
      <Bell size={14} /> {busy ? "설정 중…" : "새 품목 알림 받기"}
    </button>
  );
}
