import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Bell, Share, X } from "lucide-react";
import { useAuth } from "@/contexts/AuthContext";
import {
  isIosSafariNonStandalone,
  usePushSubscription,
} from "@/hooks/use-push-subscription";
import { useToast } from "@/hooks/use-toast";

const DISMISS_KEY = "tx.pushPrompt.dismissedAt";
const IOS_INSTALL_DISMISS_KEY = "tx.pushPrompt.iosInstallDismissedAt";
// Re-prompt after 14 days if the user dismissed but never opted in.
const RE_PROMPT_AFTER_MS = 14 * 24 * 60 * 60 * 1000;

/**
 * One-tap "Enable lock-screen alerts" card surfaced after the user logs
 * in for the first time on a device. Renders one of three variants:
 *
 *   1. iOS Safari NOT installed as PWA → install-steps card explaining
 *      Share → Add to Home Screen. (Tapping "Enable" in this state
 *      would fail with `unsupported_ios_safari`, which is opaque.)
 *   2. Supported + permission still "default" → regular Enable card.
 *   3. Otherwise (already subscribed, denied, or genuinely unsupported)
 *      → render nothing.
 *
 * Both variants have independent 14-day dismiss memory so a user who
 * dismisses one doesn't suppress the other.
 */
export function PushEnablePrompt() {
  const { t } = useTranslation();
  const { user } = useAuth();
  const { toast } = useToast();
  const { status, busy, enable } = usePushSubscription();
  const [variant, setVariant] = useState<"hidden" | "ios-install" | "enable">(
    "hidden",
  );

  useEffect(() => {
    if (!user) {
      setVariant("hidden");
      return;
    }

    // iOS Safari outside Home Screen: show install steps regardless of
    // `status`, because `enable()` will fail there with
    // `unsupported_ios_safari`. The hook keeps `status === "default"`
    // since the APIs *exist*; we override here on the install path.
    if (isIosSafariNonStandalone()) {
      if (isDismissed(IOS_INSTALL_DISMISS_KEY)) {
        setVariant("hidden");
        return;
      }
      setVariant("ios-install");
      return;
    }

    if (status !== "default") {
      setVariant("hidden");
      return;
    }
    if (isDismissed(DISMISS_KEY)) {
      setVariant("hidden");
      return;
    }
    setVariant("enable");
  }, [user, status]);

  if (variant === "hidden") return null;

  const dismiss = () => {
    const key =
      variant === "ios-install" ? IOS_INSTALL_DISMISS_KEY : DISMISS_KEY;
    try {
      localStorage.setItem(key, String(Date.now()));
    } catch {
      /* ignore */
    }
    setVariant("hidden");
  };

  if (variant === "ios-install") {
    return (
      <div
        role="dialog"
        aria-live="polite"
        data-testid="push-ios-install-prompt"
        className="fixed inset-x-3 bottom-3 z-50 md:left-auto md:right-4 md:bottom-4 md:max-w-sm rounded-2xl border border-foreground/10 bg-background/95 backdrop-blur shadow-lg p-3"
      >
        <div className="flex items-start gap-3">
          <div className="shrink-0 rounded-full bg-primary/15 p-2">
            <Share size={18} className="text-primary" />
          </div>
          <div className="min-w-0 flex-1">
            <div className="text-sm font-semibold text-foreground">
              {t("notifSettings.push.iosInstall.title")}
            </div>
            <div className="text-xs text-muted-foreground mt-0.5 leading-snug">
              {t("notifSettings.push.iosInstall.desc")}
            </div>
            <ol className="mt-2 space-y-1.5 text-xs text-foreground/90 leading-snug list-decimal ms-4">
              <li className="flex items-start gap-1.5 -ms-1 ps-1">
                <span className="flex-1">
                  {t("notifSettings.push.iosInstall.step1")}
                </span>
              </li>
              <li>{t("notifSettings.push.iosInstall.step2")}</li>
              <li>{t("notifSettings.push.iosInstall.step3")}</li>
            </ol>
            <div className="mt-2 flex items-center gap-2">
              <button
                type="button"
                data-testid="push-ios-install-dismiss"
                onClick={dismiss}
                className="text-xs font-medium px-3 py-1.5 rounded-md text-muted-foreground hover:bg-foreground/5"
              >
                {t("common.later")}
              </button>
            </div>
          </div>
          <button
            type="button"
            aria-label={t("common.close")}
            onClick={dismiss}
            className="shrink-0 text-muted-foreground hover:text-foreground p-1 rounded-md hover:bg-foreground/5"
          >
            <X size={14} />
          </button>
        </div>
      </div>
    );
  }

  return (
    <div
      role="dialog"
      aria-live="polite"
      data-testid="push-enable-prompt"
      className="fixed inset-x-3 bottom-3 z-50 md:left-auto md:right-4 md:bottom-4 md:max-w-sm rounded-2xl border border-foreground/10 bg-background/95 backdrop-blur shadow-lg p-3"
    >
      <div className="flex items-start gap-3">
        <div className="shrink-0 rounded-full bg-primary/15 p-2">
          <Bell size={18} className="text-primary" />
        </div>
        <div className="min-w-0 flex-1">
          <div className="text-sm font-semibold text-foreground">
            {t("notifSettings.push.title")}
          </div>
          <div className="text-xs text-muted-foreground mt-0.5 leading-snug">
            {t("notifSettings.push.desc")}
          </div>
          <div className="mt-2 flex items-center gap-2">
            <button
              type="button"
              disabled={busy}
              data-testid="push-enable-prompt-enable"
              onClick={async () => {
                const res = await enable();
                if (res.ok) {
                  toast({ title: t("notifSettings.push.enableSuccess") });
                  dismiss();
                } else {
                  // #576: surface the SPECIFIC reason instead of a
                  // generic "could not enable" toast. Falls back to
                  // the legacy generic copy if the key is missing.
                  const key = `notifSettings.push.errors.${res.reason}`;
                  const msg = t(key);
                  toast({
                    title:
                      msg && msg !== key
                        ? msg
                        : t("notifSettings.push.enableFailed"),
                  });
                }
              }}
              className="text-xs font-semibold px-3 py-1.5 rounded-md bg-primary text-primary-foreground hover:opacity-90 disabled:opacity-50"
            >
              {t("notifSettings.push.enable")}
            </button>
            <button
              type="button"
              data-testid="push-enable-prompt-dismiss"
              onClick={dismiss}
              className="text-xs font-medium px-3 py-1.5 rounded-md text-muted-foreground hover:bg-foreground/5"
            >
              {t("common.later")}
            </button>
          </div>
        </div>
        <button
          type="button"
          aria-label={t("common.close")}
          onClick={dismiss}
          className="shrink-0 text-muted-foreground hover:text-foreground p-1 rounded-md hover:bg-foreground/5"
        >
          <X size={14} />
        </button>
      </div>
    </div>
  );
}

function isDismissed(key: string): boolean {
  try {
    const raw = localStorage.getItem(key);
    if (!raw) return false;
    const ts = Number(raw);
    return Number.isFinite(ts) && Date.now() - ts < RE_PROMPT_AFTER_MS;
  } catch {
    return false;
  }
}
