import { useEffect, useState, useCallback } from "react";
import { toast } from "sonner";
import { ShieldOff, Loader2, CheckCircle2, Circle } from "lucide-react";
import { useProfiles } from "@/hooks/useProfiles";

const API =
  import.meta.env.VITE_BACKEND_URL ||
  import.meta.env.REACT_APP_BACKEND_URL ||
  "";

interface StoredDevice {
  device_id: string;
  mac_address: string;
  pin: string;
}

/**
 * DeviceStatusCard — shows this device's identity (MAC + Device ID) and
 * its current pairing status. When the device is paired, exposes an
 * "Unpair this device" button that:
 *   1. calls DELETE /api/device/unpair/{device_id} so the server
 *      allocates a fresh PIN and clears the profile row,
 *   2. removes the corresponding profile from the local store so the
 *      user isn't left with stale Xtream credentials, and
 *   3. clears the cached device from localStorage so the next visit to
 *      /activate re-registers cleanly.
 */
export default function DeviceStatusCard() {
  const [device, setDevice] = useState<StoredDevice | null>(null);
  const [paired, setPaired] = useState<boolean>(false);
  const [profileName, setProfileName] = useState<string>("");
  const [loading, setLoading] = useState<boolean>(false);
  const [unpairing, setUnpairing] = useState<boolean>(false);
  // Two-step confirmation state — replaces the native window.confirm
  // dialog (forbidden on Samsung Tizen TVs). First click on the
  // "Unpair" button flips this to true and re-labels the button "Tap
  // again to confirm"; a 4s timer then resets it. Second click within
  // that window performs the actual unpair.
  const [confirmUnpair, setConfirmUnpair] = useState<boolean>(false);
  const { profiles, removeProfile } = useProfiles();

  // Load cached device from localStorage on mount.
  useEffect(() => {
    try {
      const raw = localStorage.getItem("nadiplay_device");
      if (!raw) return;
      const parsed = JSON.parse(raw) as StoredDevice;
      if (parsed && parsed.device_id) setDevice(parsed);
    } catch (e) {
      console.warn("[DeviceStatusCard] parse failed", e);
    }
  }, []);

  // Poll device status every 8s so the "paired" badge stays fresh even
  // if the user paired from another tab / browser.
  const checkStatus = useCallback(async (id: string) => {
    try {
      const r = await fetch(`${API}/api/device/status/${id}`);
      if (!r.ok) return;
      const d = await r.json();
      setPaired(!!d.paired);
      setProfileName(d.profile_name || "");
    } catch (e) {
      // swallow — offline / server hiccup is fine
    }
  }, []);

  useEffect(() => {
    if (!device) return;
    let cancelled = false;
    const run = async () => {
      if (cancelled) return;
      await checkStatus(device.device_id);
    };
    run();
    const iv = setInterval(run, 8000);
    return () => {
      cancelled = true;
      clearInterval(iv);
    };
  }, [device, checkStatus]);

  const handleUnpair = useCallback(async () => {
    if (!device) return;
    // Two-step confirmation — Samsung Tizen QA forbids native popups
    // (alert / confirm / prompt). First press arms the button; second
    // press within 4 seconds actually unpairs.
    if (!confirmUnpair) {
      setConfirmUnpair(true);
      window.setTimeout(() => setConfirmUnpair(false), 4000);
      toast.info(
        "Tap Unpair again within 4 seconds to confirm — your IPTV profile will be removed from this device.",
      );
      return;
    }
    setConfirmUnpair(false);

    setUnpairing(true);
    try {
      const r = await fetch(`${API}/api/device/unpair/${device.device_id}`, {
        method: "DELETE",
      });
      if (!r.ok) throw new Error(`Unpair failed (${r.status})`);
      const data = await r.json().catch(() => ({}));

      // ── Remove any locally-stored profile that matches this device ──
      // We match by (serverUrl + username) against every profile, since
      // that's the only stable link between the paired row and the
      // local profile created by DeviceActivation.
      try {
        const cfgRes = await fetch(`${API}/api/device/config/${device.device_id}`);
        // cfgRes will now 404 because we just unpaired — that's fine.
        if (cfgRes.ok) {
          const cfg = await cfgRes.json();
          const match = profiles.find(
            (p) =>
              p.kind === "xtream" &&
              p.serverUrl === cfg.server_url &&
              p.username === cfg.username,
          );
          if (match) removeProfile(match.id);
        }
      } catch (_e) {
        /* non-fatal — backend already cleared server-side record */
      }

      // If the unpair response included a new PIN, update the cached
      // device so the next visit to /activate picks up the fresh PIN
      // without waiting for a full re-registration round-trip.
      const updatedDevice: StoredDevice = {
        ...device,
        pin: data.new_pin || device.pin,
      };
      localStorage.setItem("nadiplay_device", JSON.stringify(updatedDevice));
      setDevice(updatedDevice);
      setPaired(false);
      setProfileName("");

      toast.success("Device unpaired. A new PIN is ready in the activation screen.");
    } catch (e: any) {
      toast.error(e?.message || "Unpair failed");
    } finally {
      setUnpairing(false);
    }
  }, [device, profiles, removeProfile]);

  if (!device) {
    // No device registered on this browser yet — nothing to unpair.
    return null;
  }

  return (
    <div
      className="mt-3 pt-3 border-t border-border/40 space-y-2"
      data-testid="device-status-card"
    >
      <div className="flex items-center justify-between gap-2">
        <div className="flex items-center gap-2">
          {paired ? (
            <CheckCircle2 className="w-3.5 h-3.5 text-primary" />
          ) : (
            <Circle className="w-3.5 h-3.5 text-muted-foreground" />
          )}
          <span className="text-[11px] text-foreground">
            {paired ? "Paired" : "Not paired"}
          </span>
          {paired && profileName ? (
            <span className="text-[10px] text-muted-foreground truncate max-w-[40%]">
              · {profileName}
            </span>
          ) : null}
        </div>
        {paired && (
          <button
            onClick={handleUnpair}
            disabled={unpairing}
            className={`text-[11px] px-3 py-1.5 rounded-lg glass flex items-center gap-1.5 transition-all disabled:opacity-50 ${
              confirmUnpair
                ? "border-destructive/60 bg-destructive/10 text-destructive animate-pulse"
                : "hover:border-destructive/40 text-destructive"
            }`}
            data-testid="unpair-device-btn"
          >
            {unpairing ? (
              <Loader2 className="w-3 h-3 animate-spin" />
            ) : (
              <ShieldOff className="w-3 h-3" />
            )}
            {confirmUnpair ? "Tap again to confirm" : "Unpair this device"}
          </button>
        )}
      </div>

      <div className="grid grid-cols-2 gap-2 text-[10px]">
        <div className="glass rounded-lg px-2.5 py-1.5">
          <p className="text-muted-foreground">MAC Address</p>
          <p className="font-mono text-foreground/90 truncate" data-testid="device-mac">
            {device.mac_address || "—"}
          </p>
        </div>
        <div className="glass rounded-lg px-2.5 py-1.5">
          <p className="text-muted-foreground">Device ID</p>
          <p className="font-mono text-foreground/90 truncate" data-testid="device-id">
            {device.device_id}
          </p>
        </div>
      </div>
    </div>
  );
}
