import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
import {
  Download,
  AlertTriangle,
  Sparkles,
  X,
  ShieldCheck,
} from "lucide-react";
import {
  useAppUpdate,
  snoozeUpdate,
  isSnoozed,
} from "@/hooks/useAppUpdate";
import { useAuth } from "@/hooks/useAuth";
import { isTizen, isWebOS } from "@/lib/platform";

/**
 * Renders nothing in normal flow. When the admin publishes a newer version,
 * shows a glass-card popup with the changelog + a single "Update" button
 * that opens the Google Play Store listing (or the configured fallback
 * URL) in the user's browser.
 *
 * IMPORTANT (Play Store compliance, v1.0.0 / versionCode 2):
 * The in-app APK downloader was removed because Google Play forbids the
 * REQUEST_INSTALL_PACKAGES permission for IPTV / media-player apps. All
 * updates now flow through the Play Store's normal auto-update mechanism.
 *
 * - If installed < min_supported_version → BLOCKING (no close, no "Later").
 * - Otherwise dismissible (X + "Later", per-session snooze).
 *
 * The popup waits `popup_delay_seconds` (admin-configurable, default 10s)
 * after the app loads before appearing — gives admins time to log in
 * before any forced overlay would otherwise lock them out.
 */
const UpdatePopup = () => {
  const { info, hasUpdate, forced: forcedRaw, installedVersion } = useAppUpdate();
  const { user } = useAuth();
  const location = useLocation();
  const { t } = useTranslation();
  const isAdmin = user?.role === "admin";
  const isAdminRoute =
    location.pathname.startsWith("/admin") ||
    location.pathname.startsWith("/login");
  const forced = forcedRaw && !isAdmin && !isAdminRoute;
  const [dismissed, setDismissed] = useState(false);
  const [delayElapsed, setDelayElapsed] = useState(false);

  // Reset "dismissed" whenever a new version is detected.
  useEffect(() => {
    if (info?.update?.latest_version) {
      setDismissed(isSnoozed(info.update.latest_version));
    }
  }, [info?.update?.latest_version]);

  // Admin-controlled delay before the popup appears. Guarantees that
  // the admin can log in & change settings even if `min_supported_version`
  // would otherwise force a blocking overlay.
  useEffect(() => {
    if (!info?.update) return;
    setDelayElapsed(false);
    const raw = info.update.popup_delay_seconds;
    const seconds = Number.isFinite(raw) ? Math.max(0, Math.min(600, Number(raw))) : 10;
    const timer = window.setTimeout(() => setDelayElapsed(true), seconds * 1000);
    return () => window.clearTimeout(timer);
  }, [info?.update?.popup_delay_seconds, info?.update?.latest_version]);

  if (!info || !hasUpdate) return null;
  // Samsung Tizen + LG webOS QA forbid in-app self-update or any link
  // out to an external app store (Play). Updates on those platforms
  // are delivered through the Samsung Apps store / LG Content Store —
  // any in-app popup pointing elsewhere is a hard reject. We suppress
  // the popup entirely; AccountAboutCard.tsx shows a static text hint
  // instead.
  if (isTizen() || isWebOS()) return null;
  if (!delayElapsed) return null;
  if (!forced && dismissed) return null;

  const u = info.update;
  // Prefer the Play Store URL configured by the admin; otherwise fall
  // back to whatever apk_url was set (opened in the browser, NOT
  // installed in-app). This keeps the popup useful for Tizen / WebOS /
  // sideload distributions while remaining Play-Store compliant on
  // Android.
  const playUrl = u.play_url || "";
  const apkUrl = u.apk_url || "";
  const primaryUrl = playUrl || apkUrl;

  const close = () => {
    if (forced) return;
    snoozeUpdate(u.latest_version);
    setDismissed(true);
  };

  const openUrl = (href: string) => {
    if (!href) return;
    window.open(href, "_blank", "noopener,noreferrer");
  };

  const handlePrimary = () => {
    openUrl(primaryUrl);
  };

  const primaryLabel = playUrl
    ? t("update.openInPlayStore")
    : t("update.downloadUpdate");

  return (
    <AnimatePresence>
      <motion.div
        key="update-backdrop"
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        transition={{ duration: 0.25 }}
        className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/80 backdrop-blur-md p-4"
        data-testid="update-popup-backdrop"
        onClick={(e) => {
          if (e.target === e.currentTarget) close();
        }}
      >
        <motion.div
          key="update-card"
          initial={{ opacity: 0, scale: 0.92, y: 20 }}
          animate={{ opacity: 1, scale: 1, y: 0 }}
          exit={{ opacity: 0, scale: 0.92, y: 20 }}
          transition={{ duration: 0.3, ease: "easeOut" }}
          className="relative w-full max-w-md overflow-hidden rounded-3xl border border-primary/30 bg-card/95 p-6 shadow-2xl backdrop-blur-xl"
          data-testid="update-popup"
        >
          {!forced && (
            <button
              onClick={close}
              data-testid="update-popup-close"
              className="absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
              aria-label={t("update.closeAria")}
            >
              <X className="h-4 w-4" />
            </button>
          )}

          {/* Header */}
          <div className="mb-4 flex items-start gap-3">
            <div
              className={`flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl border ${
                forced
                  ? "border-amber-500/50 bg-amber-500/10 text-amber-400"
                  : "border-primary/40 bg-primary/10 text-primary"
              }`}
            >
              {forced ? (
                <AlertTriangle className="h-6 w-6" />
              ) : (
                <Sparkles className="h-6 w-6" />
              )}
            </div>
            <div className="min-w-0 flex-1">
              <h2
                className="text-lg font-semibold tracking-tight text-foreground"
                data-testid="update-popup-title"
              >
                {forced ? t("update.titleForced") : t("update.titleNormal")}
              </h2>
              <p className="mt-1 text-xs text-muted-foreground">
                <span data-testid="update-popup-current">
                  v{installedVersion}
                </span>
                {"  →  "}
                <span
                  className="font-medium text-foreground"
                  data-testid="update-popup-latest"
                >
                  v{u.latest_version}
                </span>
              </p>
            </div>
          </div>

          {forced && (
            <div
              className="mb-4 rounded-xl border border-amber-500/40 bg-amber-500/5 px-3 py-2 text-[11px] leading-relaxed text-amber-300"
              data-testid="update-popup-forced-notice"
            >
              {t("update.forcedNotice")}
            </div>
          )}

          {isAdmin && forcedRaw && (
            <div
              className="mb-4 flex items-start gap-2 rounded-xl border border-primary/40 bg-primary/10 px-3 py-2 text-[11px] leading-relaxed text-primary"
              data-testid="update-popup-admin-preview"
            >
              <ShieldCheck className="mt-0.5 h-3.5 w-3.5 shrink-0" />
              <span>
                {t("update.adminPreview", {
                  installed: installedVersion,
                  min: info.update.min_supported_version,
                })}
              </span>
            </div>
          )}
          {!isAdmin && isAdminRoute && forcedRaw && (
            <div
              className="mb-4 flex items-start gap-2 rounded-xl border border-primary/40 bg-primary/10 px-3 py-2 text-[11px] leading-relaxed text-primary"
              data-testid="update-popup-login-preview"
            >
              <ShieldCheck className="mt-0.5 h-3.5 w-3.5 shrink-0" />
              <span>{t("update.loginPreview")}</span>
            </div>
          )}

          {/* Changelog */}
          {u.changelog && (
            <div className="mb-5 max-h-56 overflow-y-auto rounded-xl border border-border/60 bg-background/40 px-3 py-2.5">
              <p className="mb-1 text-[10px] font-medium uppercase tracking-[0.2em] text-muted-foreground">
                {t("update.whatsNew")}
              </p>
              <pre
                className="whitespace-pre-wrap break-words font-sans text-xs leading-relaxed text-foreground/90"
                data-testid="update-popup-changelog"
              >
                {u.changelog}
              </pre>
            </div>
          )}

          {/* Actions */}
          <div className="flex flex-col gap-2">
            {primaryUrl ? (
              <button
                onClick={handlePrimary}
                data-testid="update-popup-download-btn"
                className="flex w-full items-center justify-center gap-2 rounded-xl bg-primary px-4 py-3 text-sm font-semibold text-primary-foreground shadow-lg shadow-primary/30 transition hover:brightness-110 active:scale-[0.98]"
              >
                <Download className="h-4 w-4" />
                {primaryLabel}
              </button>
            ) : (
              <p
                className="rounded-xl border border-destructive/40 bg-destructive/10 px-3 py-2 text-center text-xs text-destructive"
                data-testid="update-popup-no-url"
              >
                {t("update.noUrl")}
              </p>
            )}

            {!forced && (
              <button
                onClick={close}
                data-testid="update-popup-later-btn"
                className="w-full rounded-xl px-4 py-2 text-xs text-muted-foreground transition-colors hover:text-foreground"
              >
                {t("update.later")}
              </button>
            )}
          </div>
        </motion.div>
      </motion.div>
    </AnimatePresence>
  );
};

export default UpdatePopup;
