"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import {
  Loader2,
  LogOut,
  CreditCard,
} from "lucide-react";
import { Button } from "@/shared/components/ui/button";
import { Badge } from "@/shared/components/ui/badge";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/shared/components/ui/tooltip";
import { cn } from "@/shared/lib/utils";

/* ------------------------------------------------------------------ */
/*  Types                                                              */
/* ------------------------------------------------------------------ */

export type EpaySessionStatus = {
  connected: boolean;
  username?: string;
  connectedAt?: string;
  credits?: number;
  creditsCheckedAt?: string;
};

/* ------------------------------------------------------------------ */
/*  Component                                                          */
/* ------------------------------------------------------------------ */

export function EpayConnect({
  onStatusChange,
  triggerConnect,
}: {
  onStatusChange?: (status: EpaySessionStatus) => void;
  /** When set to true, triggers auto-connect (e.g. when user types UAT) */
  triggerConnect?: boolean;
}) {
  const [status, setStatus] = useState<EpaySessionStatus>({ connected: false });
  const [connecting, setConnecting] = useState(false);
  const [error, setError] = useState("");
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const cbRef = useRef(onStatusChange);
  cbRef.current = onStatusChange;
  const autoConnectAttempted = useRef(false);
  const autoConnectTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const fetchStatus = useCallback(async () => {
    try {
      const res = await fetch("/api/ancpi/session");
      const data = (await res.json()) as EpaySessionStatus;
      setStatus(data);
      cbRef.current?.(data);
      if (data.connected) setError("");
      return data;
    } catch {
      /* silent */
      return null;
    }
  }, []);

  // Poll every 30s — detect disconnection and allow re-connect
  useEffect(() => {
    void fetchStatus();
    pollRef.current = setInterval(() => {
      void fetchStatus().then((data) => {
        if (data && !data.connected && autoConnectAttempted.current) {
          autoConnectAttempted.current = false;
        }
      });
    }, 30_000);
    return () => {
      if (pollRef.current) clearInterval(pollRef.current);
    };
  }, [fetchStatus]);

  const connect = useCallback(async () => {
    if (connecting || status.connected) return;
    setConnecting(true);
    setError("");
    try {
      const res = await fetch("/api/ancpi/session", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({}),
      });
      const data = (await res.json()) as { success?: boolean; credits?: number; error?: string };
      if (!res.ok || data.error) {
        setError(data.error ?? "Eroare conectare ePay");
      } else {
        await fetchStatus();
      }
    } catch {
      setError("Eroare retea");
    } finally {
      setConnecting(false);
    }
  }, [connecting, status.connected, fetchStatus]);

  // Auto-connect when triggerConnect becomes true, with retry on failure
  useEffect(() => {
    if (!triggerConnect || status.connected || connecting || autoConnectAttempted.current) return;
    autoConnectAttempted.current = true;

    let cancelled = false;
    const maxRetries = 2;

    const attemptConnect = async (attempt: number) => {
      if (cancelled) return;

      // On first attempt, check session to avoid unnecessary connect
      if (attempt === 0) {
        const current = await fetchStatus();
        if (cancelled) return;
        if (current?.connected) return;
      }

      setConnecting(true);
      setError("");
      let shouldRetry = false;
      try {
        const res = await fetch("/api/ancpi/session", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({}),
        });
        const data = (await res.json()) as { success?: boolean; credits?: number; error?: string };
        if (cancelled) return;

        if (!res.ok || data.error) {
          setError(data.error ?? "Eroare conectare ePay");
          shouldRetry = attempt < maxRetries;
        } else {
          await fetchStatus();
        }
      } catch {
        if (cancelled) return;
        setError("Eroare retea");
        shouldRetry = attempt < maxRetries;
      }

      if (cancelled) return;

      if (shouldRetry) {
        // Keep connecting state true during retry wait
        autoConnectTimerRef.current = setTimeout(() => {
          void attemptConnect(attempt + 1);
        }, 3000);
      } else {
        setConnecting(false);
      }
    };

    void attemptConnect(0);

    return () => {
      cancelled = true;
      if (autoConnectTimerRef.current) {
        clearTimeout(autoConnectTimerRef.current);
        autoConnectTimerRef.current = null;
      }
    };
  }, [triggerConnect, status.connected, connecting, fetchStatus]);

  const disconnect = async () => {
    try {
      await fetch("/api/ancpi/session", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: "disconnect" }),
      });
      autoConnectAttempted.current = false;
      if (autoConnectTimerRef.current) {
        clearTimeout(autoConnectTimerRef.current);
        autoConnectTimerRef.current = null;
      }
      await fetchStatus();
    } catch {
      /* silent */
    }
  };

  return (
    <div className="flex items-center gap-1">
      {/* Status pill */}
      <TooltipProvider>
        <Tooltip>
          <TooltipTrigger asChild>
            <div
              className={cn(
                "flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium",
                status.connected
                  ? "border-emerald-200 bg-emerald-50/80 text-emerald-700 dark:border-emerald-800 dark:bg-emerald-950/40 dark:text-emerald-400"
                  : error
                    ? "border-rose-200 bg-rose-50/80 text-rose-600 dark:border-rose-800 dark:bg-rose-950/40 dark:text-rose-400"
                    : connecting
                      ? "border-muted-foreground/20 bg-muted/50 text-muted-foreground"
                      : "border-muted-foreground/20 bg-muted/50 text-muted-foreground",
              )}
            >
              {connecting ? (
                <Loader2 className="h-3 w-3 animate-spin" />
              ) : status.connected ? (
                <span className="inline-flex h-2 w-2 rounded-full bg-emerald-500" />
              ) : null}

              <span className="hidden sm:inline">ePay</span>

              {status.connected && status.credits != null && (
                <Badge
                  variant="secondary"
                  className="ml-0.5 h-4 px-1.5 text-[10px] font-semibold"
                >
                  <CreditCard className="mr-0.5 h-2.5 w-2.5" />
                  {status.credits}
                </Badge>
              )}
            </div>
          </TooltipTrigger>
          <TooltipContent side="bottom" className="text-xs">
            {status.connected
              ? `${status.credits ?? "?"} credite ePay disponibile`
              : error
                ? error
                : connecting
                  ? "Se conecteaza..."
                  : "Se conecteaza automat la selectia UAT"}
          </TooltipContent>
        </Tooltip>
      </TooltipProvider>

      {/* Logout button — only when connected */}
      {status.connected && (
        <Button
          variant="ghost"
          size="sm"
          className="h-6 px-1.5 text-[10px]"
          onClick={() => void disconnect()}
          title="Deconectare ePay"
        >
          <LogOut className="h-3 w-3" />
        </Button>
      )}
    </div>
  );
}
