"use client";

import { useState, useEffect, useRef } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { ShieldCheck, ShieldX, Loader2 } from "lucide-react";
import { countryCodeToEmoji } from "@/lib/utils";
import type { Dictionary } from "@/lib/dictionaries";

interface IPData {
  ip: string;
  country_name: string;
  country_code: string;
  region: string;
  city: string;
  org: string;
  asn: string;
}

interface IPInfoCardProps {
  dict: Dictionary;
}

export default function IPInfoCard({ dict }: IPInfoCardProps) {
  const [open, setOpen] = useState(false);
  const [data, setData] = useState<IPData | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(false);
  const ref = useRef<HTMLDivElement>(null);
  const [isSecure, setIsSecure] = useState(false);

  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setIsSecure(window.location.protocol === "https:");
  }, []);
  useEffect(() => {
    function handleClick(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) {
        setOpen(false);
      }
    }
    if (open) document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, [open]);

  // Fetch IP data when opened. The request is tiny, so it's allowed to finish
  // even if the popup closes — aborting it used to leave the card stuck on
  // the loading state forever. Failed lookups retry on the next open.
  const fetching = useRef(false);

  useEffect(() => {
    if (!open || data || fetching.current) return;
    fetching.current = true;
    setLoading(true);
    setError(false);

    fetch("https://ipapi.co/json/")
      .then((res) => {
        if (!res.ok) throw new Error("Failed");
        return res.json();
      })
      .then((json) => {
        setData({
          ip: json.ip,
          country_name: json.country_name,
          country_code: json.country_code,
          region: json.region,
          city: json.city,
          org: json.org || "Unknown",
          asn: json.asn || "",
        });
      })
      .catch(() => {
        setError(true);
      })
      .finally(() => {
        fetching.current = false;
        setLoading(false);
      });
  }, [open, data]);

  const flag = data ? countryCodeToEmoji(data.country_code) : "🌐";

  return (
    <div ref={ref} className="relative">
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        className="flex h-9 w-9 items-center justify-center rounded-lg border border-border/60 text-base transition-all hover:border-purple-400/40 hover:bg-purple-500/10"
        aria-label="Visitor info"
      >
        {data ? flag : "🌐"}
      </button>

      <AnimatePresence>
        {open && (
          <motion.div
            initial={{ opacity: 0, y: 8, scale: 0.96 }}
            animate={{ opacity: 1, y: 0, scale: 1 }}
            exit={{ opacity: 0, y: 8, scale: 0.96 }}
            transition={{ duration: 0.25, ease: [0.16, 1, 0.3, 1] }}
            className="absolute right-0 top-12 z-50 w-72 overflow-hidden rounded-2xl border border-border/60 bg-surface/95 shadow-2xl shadow-purple-500/10 backdrop-blur-xl"
          >
            {/* Header */}
            <div className="flex items-center gap-3 border-b border-border/40 px-4 py-3">
              <span className="font-mono text-xs uppercase tracking-widest text-text-secondary">
                {dict.ipInfo.title}
              </span>
              <span className="ml-auto rounded-full border border-purple-400/30 bg-purple-500/10 px-2 py-0.5 text-[10px] font-medium text-purple-300">
                Visitor: {flag} {data?.country_code || "??"}
              </span>
            </div>

            {/* Body */}
            <div className="px-4 py-3">
              {loading && (
                <div className="flex items-center justify-center gap-2 py-6 text-sm text-text-secondary">
                  <Loader2 className="h-4 w-4 animate-spin" />
                  {dict.ipInfo.loading}
                </div>
              )}

              {error && (
                <div className="py-6 text-center text-sm text-text-secondary">
                  {dict.ipInfo.error}
                </div>
              )}

              {data && !loading && (
                <>
                  <div className="mb-3 flex items-center gap-3">
                    <span className="text-3xl">{flag}</span>
                    <div>
                      <div className="text-sm font-medium text-text-primary">
                        {data.country_name}
                      </div>
                      <div className="font-mono text-xs text-purple-400">
                        {data.ip}
                      </div>
                    </div>
                  </div>

                  <div className="space-y-0 divide-y divide-border/30 rounded-xl border border-border/40 bg-background/50">
                    <InfoRow label={dict.ipInfo.region} value={data.region} />
                    <InfoRow label={dict.ipInfo.city} value={data.city} />
                    <InfoRow
                      label={dict.ipInfo.isp}
                      value={`${data.asn} ${data.org}`}
                      wrap
                    />
                    <div className="flex items-center justify-between px-3 py-2.5">
                      <span className="font-mono text-[11px] text-text-secondary">
                        {dict.ipInfo.connection}
                      </span>
                      <span className="inline-flex items-center gap-1.5">
                        <span
                          className={`text-xs font-medium ${
                            isSecure ? "text-emerald-400" : "text-error"
                          }`}
                        >
                          {isSecure
                            ? dict.ipInfo.secure
                            : dict.ipInfo.notSecure}
                        </span>
                        {isSecure ? (
                          <ShieldCheck
                            className="h-3.5 w-3.5 text-emerald-400"
                            strokeWidth={2}
                          />
                        ) : (
                          <ShieldX
                            className="h-3.5 w-3.5 text-error"
                            strokeWidth={2}
                          />
                        )}
                      </span>
                    </div>
                  </div>
                </>
              )}
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

function InfoRow({
  label,
  value,
  wrap,
}: {
  label: string;
  value: string;
  wrap?: boolean;
}) {
  return (
    <div
      className={`flex items-start justify-between gap-3 px-3 py-2.5 ${
        wrap ? "" : "items-center"
      }`}
    >
      <span className="shrink-0 font-mono text-[11px] text-text-secondary">
        {label}
      </span>
      <span
        className={`text-right font-mono text-xs text-text-primary ${
          wrap ? "break-all text-right" : "truncate"
        }`}
      >
        {value}
      </span>
    </div>
  );
}
