import { useEffect, useState } from "react";
import { Download, Check, ExternalLink } from "lucide-react";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog";
import { NativePlayer, isNativeApp } from "@/native/nativePlayer";
import { apiPublicPlaybackMode } from "@/lib/nadiAuth";

type PlayerApp = {
  key: "exoplayer" | "vlc";
  label: string;
  packageName: string;
  playStoreUrl: string;
  iconUrl: string;
  description: string;
};

const APPS: PlayerApp[] = [
  {
    key: "exoplayer",
    label: "Just Player (ExoPlayer)",
    packageName: "com.brouken.player",
    playStoreUrl: "https://play.google.com/store/apps/details?id=com.brouken.player",
    iconUrl:
      "data:image/svg+xml;utf8," +
      encodeURIComponent(
        `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><rect width='64' height='64' rx='14' fill='#c89a4a'/><polygon points='24,18 48,32 24,46' fill='#ffffff'/></svg>`
      ),
    description: "ExoPlayer-powered player — best for IPTV & HLS streams.",
  },
  {
    key: "vlc",
    label: "VLC Media Player",
    packageName: "org.videolan.vlc",
    playStoreUrl: "https://play.google.com/store/apps/details?id=org.videolan.vlc",
    iconUrl:
      "data:image/svg+xml;utf8," +
      encodeURIComponent(
        `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><rect width='64' height='64' rx='14' fill='#ff8800'/><polygon points='20,46 32,14 44,46' fill='#ffffff'/><rect x='18' y='44' width='28' height='4' fill='#ffffff'/></svg>`
      ),
    description: "Universal player — handles any codec or format.",
  },
];

const DISMISS_KEY = "nadiplay.playerNotice.dismissed.v1";
// Caches the last-known admin choice so we never have to wait for the API
// before deciding whether to show. If the admin disables the popup on the
// server, the very next app launch picks it up — even before the API
// answers, even offline. Survives across launches.
const ENABLED_CACHE_KEY = "nadiplay.playerNotice.enabledCache.v1";
// Bumped when we flipped the popup semantics from opt-OUT (show unless
// disabled) → opt-IN (hidden unless admin explicitly enables). Any old
// cached "1" from the previous semantics is wiped on first read so a
// user who launched the app with the old build never sees the popup
// again after installing the new build — regardless of the admin toggle.
const SEMANTICS_VERSION_KEY = "nadiplay.playerNotice.semantics";
const CURRENT_SEMANTICS_VERSION = "opt-in-v2";

const ExternalPlayerNotice = () => {
  // Popup is now OPT-IN: default hidden; only shown if the server
  // explicitly returns player_notice_enabled === true AND the user
  // hasn't dismissed it.
  const [open, setOpen] = useState<boolean>(false);

  useEffect(() => {
    let cancelled = false;

    // ── 0. One-time migration: wipe legacy cache from opt-OUT semantics ──
    try {
      const prevSemantics = localStorage.getItem(SEMANTICS_VERSION_KEY);
      if (prevSemantics !== CURRENT_SEMANTICS_VERSION) {
        localStorage.removeItem(ENABLED_CACHE_KEY);
        localStorage.setItem(SEMANTICS_VERSION_KEY, CURRENT_SEMANTICS_VERSION);
      }
    } catch { /* noop */ }

    // ── 1. SYNCHRONOUS read of cached admin choice ──
    let cached: boolean | null = null;
    try {
      const raw = localStorage.getItem(ENABLED_CACHE_KEY);
      if (raw === "0") cached = false;
      else if (raw === "1") cached = true;
    } catch { /* noop */ }
    const dismissed = (() => {
      try { return localStorage.getItem(DISMISS_KEY) === "1"; }
      catch { return false; }
    })();

    // If admin previously said "disabled" OR we have no cache at all →
    // start hidden. Ping the API in the background and only reveal if
    // the server explicitly says enabled === true.
    if (cached !== true) {
      void apiPublicPlaybackMode()
        .then((cfg) => {
          if (cancelled) return;
          const enabled = cfg.player_notice_enabled === true;
          try { localStorage.setItem(ENABLED_CACHE_KEY, enabled ? "1" : "0"); } catch { /* noop */ }
          if (enabled && !dismissed) setOpen(true);
        })
        .catch(() => { /* offline → stay hidden */ });
      return () => { cancelled = true; };
    }

    // Otherwise (cached === true) revalidate with API and only keep
    // showing if the server still says enabled.
    void (async () => {
      let enabled = true;
      try {
        const cfg = await apiPublicPlaybackMode();
        enabled = cfg.player_notice_enabled === true;
        try { localStorage.setItem(ENABLED_CACHE_KEY, enabled ? "1" : "0"); } catch { /* noop */ }
      } catch {
        // API unreachable — honour the cached "true" once, but don't
        // keep showing forever if admin has since disabled. We trust
        // the cache only until the next successful fetch.
      }
      if (cancelled) return;
      if (!enabled) { setOpen(false); return; }
      if (!dismissed) setOpen(true);
    })();

    return () => { cancelled = true; };
  }, []);

  const openStore = (app: PlayerApp) => {
    if (isNativeApp()) {
      NativePlayer.openPlayStore({ package: app.packageName }).catch(() => {
        window.open(app.playStoreUrl, "_blank", "noopener,noreferrer");
      });
    } else {
      window.open(app.playStoreUrl, "_blank", "noopener,noreferrer");
    }
  };

  const dismiss = () => {
    try {
      localStorage.setItem(DISMISS_KEY, "1");
    } catch {
      /* ignore */
    }
    setOpen(false);
  };

  return (
    <Dialog open={open} onOpenChange={(o) => !o && dismiss()}>
      <DialogContent
        data-testid="player-notice-dialog"
        className="max-w-md border-primary/30 bg-background/95 backdrop-blur-xl"
      >
        <DialogHeader>
          <div className="mx-auto mb-2 flex h-12 w-12 items-center justify-center rounded-full bg-primary/15">
            <Download className="h-6 w-6 text-primary" strokeWidth={1.8} />
          </div>
          <DialogTitle className="text-center text-lg tracking-wide gold-text">
            Install a video player
          </DialogTitle>
          <DialogDescription className="text-center text-sm text-muted-foreground">
            You must download <span className="text-primary font-medium">ExoPlayer</span> or{" "}
            <span className="text-primary font-medium">VLC</span> from Google Play to let this app work.
            If you already have one installed, just tap “I already have it”.
          </DialogDescription>
        </DialogHeader>

        <div className="mt-2 flex flex-col gap-2.5">
          {APPS.map((app) => (
            <button
              key={app.key}
              data-testid={`install-${app.key}`}
              onClick={() => openStore(app)}
              className="group flex items-center gap-3 rounded-xl border border-border/70 bg-card/60 px-3 py-2.5 text-left transition hover:border-primary/50 hover:bg-primary/5 active:scale-[0.99]"
            >
              <img
                src={app.iconUrl}
                alt={app.label}
                className="h-11 w-11 flex-none rounded-lg bg-muted object-cover"
                loading="lazy"
                referrerPolicy="no-referrer"
              />
              <div className="min-w-0 flex-1">
                <div className="flex items-center gap-1.5 text-sm font-medium text-foreground">
                  <span className="truncate">{app.label}</span>
                  <ExternalLink className="h-3 w-3 text-muted-foreground opacity-0 transition group-hover:opacity-100" />
                </div>
                <div className="truncate text-[11px] text-muted-foreground">
                  {app.description}
                </div>
              </div>
              <div className="text-[10px] font-medium uppercase tracking-widest text-primary/80">
                Install
              </div>
            </button>
          ))}
        </div>

        <button
          data-testid="player-notice-dismiss"
          onClick={dismiss}
          className="mt-3 flex items-center justify-center gap-2 rounded-xl border border-border/70 bg-muted/40 py-2.5 text-sm text-foreground/90 transition hover:bg-muted"
        >
          <Check className="h-4 w-4 text-primary" />
          I already have it
        </button>
      </DialogContent>
    </Dialog>
  );
};

export default ExternalPlayerNotice;
