"use client";

import { useEffect, useRef, useState } from "react";
import { WifiOff, RefreshCw, CheckCircle2 } from "lucide-react";
import { useServiceStore } from "@/store";
import { cn } from "@/lib/utils";

const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? "";
const RETRY_INTERVAL = 10_000; // 10 seconds

export function ServiceDownBanner() {
  const { isDown, downSince, setDown } = useServiceStore();
  const [recovering, setRecovering] = useState(false);
  const [justRecovered, setJustRecovered] = useState(false);
  const [countdown, setCountdown] = useState(RETRY_INTERVAL / 1000);
  const retryRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const countdownRef = useRef<ReturnType<typeof setInterval> | null>(null);

  // Format how long the service has been down
  const downDuration = downSince
    ? Math.floor((Date.now() - new Date(downSince).getTime()) / 1000)
    : 0;

  const formatDuration = (s: number) => {
    if (s < 60) return `${s}s`;
    if (s < 3600) return `${Math.floor(s / 60)}m`;
    return `${Math.floor(s / 3600)}h`;
  };

  const pingBackend = async () => {
    setRecovering(true);
    try {
      const res = await fetch(`${BASE_URL}/list-meetings?page=1&limit=1`, {
        headers: { "ngrok-skip-browser-warning": "true" },
        signal: AbortSignal.timeout(5000),
      });
      if (res.ok || res.status === 401) {
        // 401 means server is up but token expired — still counts as "up"
        setDown(false);
        setJustRecovered(true);
        setTimeout(() => setJustRecovered(false), 3000);
        clearIntervals();
      }
    } catch {
      // still down
    } finally {
      setRecovering(false);
      setCountdown(RETRY_INTERVAL / 1000);
    }
  };

  const clearIntervals = () => {
    if (retryRef.current) clearInterval(retryRef.current);
    if (countdownRef.current) clearInterval(countdownRef.current);
  };

  useEffect(() => {
    if (!isDown) {
      clearIntervals();
      return;
    }

    setCountdown(RETRY_INTERVAL / 1000);

    // Auto-retry every 10 seconds
    retryRef.current = setInterval(pingBackend, RETRY_INTERVAL);

    // Countdown ticker
    countdownRef.current = setInterval(() => {
      setCountdown((c) => (c <= 1 ? RETRY_INTERVAL / 1000 : c - 1));
    }, 1000);

    return clearIntervals;
  }, [isDown]); // eslint-disable-line react-hooks/exhaustive-deps

  // Show "recovered" flash briefly
  if (justRecovered) {
    return (
      <div className="flex items-center justify-center gap-2 bg-green-500 px-4 py-2.5 text-sm font-medium text-white animate-in fade-in-0">
        <CheckCircle2 className="h-4 w-4" />
        Service restored — you're back online
      </div>
    );
  }

  if (!isDown) return null;

  return (
    <div className="flex items-center justify-between gap-3 bg-amber-500 dark:bg-amber-600 px-4 py-2.5 text-sm text-white">
      {/* Left */}
      <div className="flex items-center gap-2.5 min-w-0">
        <WifiOff className="h-4 w-4 shrink-0" />
        <div className="min-w-0">
          <span className="font-semibold">Service unavailable</span>
          <span className="hidden sm:inline text-amber-100 ml-1.5">
            — Backend server is not responding.
            {downDuration > 5 && ` Down for ${formatDuration(downDuration)}.`}
          </span>
        </div>
      </div>

      {/* Right — retry */}
      <div className="flex items-center gap-3 shrink-0">
        <span className="text-xs text-amber-200 hidden sm:block">
          Retrying in {countdown}s
        </span>
        <button
          onClick={pingBackend}
          disabled={recovering}
          className="flex items-center gap-1.5 rounded-lg border border-white/30 bg-white/15 px-3 py-1 text-xs font-semibold hover:bg-white/25 transition-colors disabled:opacity-60"
        >
          <RefreshCw className={cn("h-3.5 w-3.5", recovering && "animate-spin")} />
          {recovering ? "Checking…" : "Retry now"}
        </button>
      </div>
    </div>
  );
}
