import { memo, useState, useEffect } from "react";
import { Handle, Position, type NodeProps } from "@xyflow/react";
import { useNodeStats } from "../hooks/useStatsStore";
import {
  Database,
  Zap,
  Globe,
  Server,
  Container,
  Shield,
  Cog,
  Timer,
  Radar,
  MonitorDot,
  KeyRound,
  FileCode,
  Boxes,
  Gem,
  Coffee,
  Bug,
  Rabbit,
  Mail,
  BarChart3,
  AlertTriangle,
  type LucideIcon,
} from "lucide-react";

interface ServiceNodeData {
  label: string;
  image: string;
  state: string;
  ports: { host: number; container: number }[];
  project: string;
  flash?: string;
  id?: string;
  activeHandles?: string[];
  highlighted?: boolean;
  [key: string]: unknown;
}

const stateStyles: Record<string, { ring: string; dot: string; bg: string; border: string }> = {
  running: { ring: "ring-emerald-500/50", dot: "bg-emerald-500", bg: "bg-emerald-500/10", border: "border-slate-700/80" },
  exited: { ring: "ring-red-500/50", dot: "bg-red-500", bg: "bg-red-500/10", border: "border-red-500/60" },
  paused: { ring: "ring-amber-500/50", dot: "bg-amber-500", bg: "bg-amber-500/10", border: "border-amber-500/60" },
  restarting: { ring: "ring-amber-500/50", dot: "bg-amber-500", bg: "bg-amber-500/10", border: "border-amber-500/60" },
  dead: { ring: "ring-red-500/50", dot: "bg-red-500", bg: "bg-red-500/10", border: "border-red-500/60" },
  crashed: { ring: "ring-orange-500/50", dot: "bg-orange-500", bg: "bg-orange-500/10", border: "border-orange-500/60" },
  processing: { ring: "ring-yellow-500/50", dot: "bg-yellow-500 animate-pulse", bg: "bg-yellow-500/10", border: "border-yellow-500/60" },
};

// Map image/name patterns to Lucide icons and colors
const iconMap: { pattern: string; icon: LucideIcon; color: string }[] = [
  { pattern: "postgres", icon: Database, color: "#336791" },
  { pattern: "mysql", icon: Database, color: "#4479A1" },
  { pattern: "mariadb", icon: Database, color: "#003545" },
  { pattern: "mongo", icon: Database, color: "#47A248" },
  { pattern: "redis", icon: Zap, color: "#DC382D" },
  { pattern: "memcached", icon: Zap, color: "#3B9C60" },
  { pattern: "nginx", icon: Globe, color: "#009639" },
  { pattern: "traefik", icon: Globe, color: "#24A1C1" },
  { pattern: "haproxy", icon: Globe, color: "#2E86C1" },
  { pattern: "caddy", icon: Globe, color: "#1F88E5" },
  { pattern: "node", icon: MonitorDot, color: "#339933" },
  { pattern: "python", icon: FileCode, color: "#3776AB" },
  { pattern: "golang", icon: Boxes, color: "#00ADD8" },
  { pattern: "ruby", icon: Gem, color: "#CC342D" },
  { pattern: "java", icon: Coffee, color: "#ED8B00" },
  { pattern: "rabbitmq", icon: Rabbit, color: "#FF6600" },
  { pattern: "kafka", icon: Mail, color: "#231F20" },
  { pattern: "grafana", icon: BarChart3, color: "#F46800" },
  { pattern: "prometheus", icon: BarChart3, color: "#E6522C" },
  { pattern: "certbot", icon: Shield, color: "#003A70" },
];

// Name-based patterns (for custom-built images)
const nameIconMap: { pattern: string; icon: LucideIcon; color: string }[] = [
  { pattern: "collector", icon: Radar, color: "#f59e0b" },
  { pattern: "celery", icon: Cog, color: "#97C95F" },
  { pattern: "worker", icon: Cog, color: "#97C95F" },
  { pattern: "beat", icon: Timer, color: "#97C95F" },
  { pattern: "auth", icon: KeyRound, color: "#8b5cf6" },
  { pattern: "backend", icon: Server, color: "#3b82f6" },
  { pattern: "frontend", icon: MonitorDot, color: "#06b6d4" },
  { pattern: "api", icon: Server, color: "#3b82f6" },
];

function guessIcon(image: string, name: string): { Icon: LucideIcon; color: string } {
  const lowerImage = image.toLowerCase();
  const lowerName = name.toLowerCase();

  // Check image first
  for (const { pattern, icon, color } of iconMap) {
    if (lowerImage.includes(pattern)) return { Icon: icon, color };
  }

  // Then check name
  for (const { pattern, icon, color } of nameIconMap) {
    if (lowerName.includes(pattern)) return { Icon: icon, color };
  }

  return { Icon: Container, color: "#64748b" };
}

function ProcessingTimer({ startedAt }: { startedAt: number }) {
  const [elapsed, setElapsed] = useState(Math.floor((Date.now() - startedAt) / 1000));
  useEffect(() => {
    const interval = setInterval(() => {
      setElapsed(Math.floor((Date.now() - startedAt) / 1000));
    }, 1000);
    return () => clearInterval(interval);
  }, [startedAt]);
  return <span className="text-[10px] font-mono text-yellow-400 ml-1">{elapsed}s</span>;
}

export const ServiceNode = memo(function ServiceNode({ data, id }: NodeProps) {
  const d = data as unknown as ServiceNodeData;
  const nodeStats = useNodeStats(id);
  const s = stateStyles[d.state] || stateStyles.exited;
  const { Icon, color: iconColor } = guessIcon(d.image, d.label);
  const flashClass = d.flash || "";
  const activeHandles = new Set<string>(d.activeHandles || []);
  const highlighted = d.highlighted;
  const hdot = (id: string) => {
    if (activeHandles.has(id)) {
      return highlighted
        ? "!bg-cyan-400 !w-2 !h-2 !border-0 !opacity-100"
        : "!bg-slate-500 !w-1.5 !h-1.5 !border-0 !opacity-80";
    }
    return "!bg-transparent !w-1.5 !h-1.5 !border-0 !opacity-0";
  };

  // 3 slots per side at 25%, 50%, 75%
  const offsets = ["25%", "50%", "75%"];

  return (
    <div
      title={`${d.label} (${d.state})\nImage: ${d.image}\nID: ${d.id || ""}\nPorts: ${d.ports?.map((p) => `${p.host}:${p.container}`).join(", ") || "none"}`}
      className={`relative rounded-xl border ${s.border} ${s.bg} backdrop-blur-sm
                  shadow-lg shadow-black/30 p-4 min-w-[220px] ring-2 ${s.ring}
                  transition-[opacity,box-shadow] duration-300 ${flashClass}`}
    >
      {/* Top handles — left offset, transform centered horizontally */}
      {offsets.map((o, i) => (
        <Handle key={`t${i}`} type="source" position={Position.Top} id={`top-${i}`} className={hdot(`top-${i}`)} style={{ left: o, transform: "translate(-50%, -50%)" }} />
      ))}
      {offsets.map((o, i) => (
        <Handle key={`tt${i}`} type="target" position={Position.Top} id={`top-${i}-target`} className={hdot(`top-${i}`)} style={{ left: o, transform: "translate(-50%, -50%)" }} />
      ))}
      {/* Left handles — top offset, transform centered vertically */}
      {offsets.map((o, i) => (
        <Handle key={`l${i}`} type="source" position={Position.Left} id={`left-${i}`} className={hdot(`left-${i}`)} style={{ top: o, transform: "translate(-50%, -50%)" }} />
      ))}
      {offsets.map((o, i) => (
        <Handle key={`lt${i}`} type="target" position={Position.Left} id={`left-${i}-target`} className={hdot(`left-${i}`)} style={{ top: o, transform: "translate(-50%, -50%)" }} />
      ))}
      {/* Right handles — top offset, transform centered */}
      {offsets.map((o, i) => (
        <Handle key={`r${i}`} type="source" position={Position.Right} id={`right-${i}`} className={hdot(`right-${i}`)} style={{ top: o, transform: "translate(50%, -50%)" }} />
      ))}
      {offsets.map((o, i) => (
        <Handle key={`rt${i}`} type="target" position={Position.Right} id={`right-${i}-target`} className={hdot(`right-${i}`)} style={{ top: o, transform: "translate(50%, -50%)" }} />
      ))}

      {/* Top section: icon left, name + image right */}
      <div className="flex gap-3 mb-2">
        <div
          className="flex items-center justify-center w-9 h-9 rounded-lg shrink-0 self-center"
          style={{ backgroundColor: `${iconColor}22` }}
        >
          <Icon size={20} style={{ color: iconColor }} />
        </div>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <span className="font-bold text-white text-sm truncate">{d.label}</span>
            {d.state === "processing" ? (
              <div className="flex items-center gap-0.5 shrink-0">
                <div className="w-2 h-2 rounded-full bg-yellow-500 animate-pulse" />
                {(d as any)._processingStartedAt && <ProcessingTimer startedAt={(d as any)._processingStartedAt} />}
              </div>
            ) : d.state === "crashed" ? (
              <AlertTriangle size={12} className="text-orange-500 shrink-0" />
            ) : (
              <div className={`w-2 h-2 rounded-full shrink-0 ${s.dot}`} />
            )}
          </div>
          <div className="text-xs text-slate-500 truncate mt-0.5">
            {d.image.startsWith("sha256:") ? `Sin Tag (${d.image.slice(7, 19)})` : d.image}
          </div>
        </div>
      </div>

      {/* Ports */}
      {d.ports?.length > 0 && (
        <div className="flex gap-1.5 flex-wrap mb-2">
          {d.ports.map((p) => (
            <span
              key={`${p.host}:${p.container}`}
              className="text-[11px] bg-slate-800/80 text-cyan-400 px-2 py-0.5 rounded font-mono"
            >
              :{p.host}
            </span>
          ))}
        </div>
      )}

      {/* Stats */}
      {nodeStats && (
        <div className="mt-2 space-y-1.5">
          <div className="flex justify-between text-[11px] text-slate-400">
            <span>CPU {nodeStats.cpu.toFixed(1)}%</span>
            <span>MEM {nodeStats.mem_mb.toFixed(0)}MB</span>
          </div>
          <div className="flex gap-1.5">
            <div className="flex-1 h-1.5 bg-slate-800 rounded-full overflow-hidden">
              <div
                className="h-full bg-cyan-500/60 rounded-full transition-all duration-700"
                style={{ width: `${Math.min(nodeStats.cpu, 100)}%` }}
              />
            </div>
            <div className="flex-1 h-1.5 bg-slate-800 rounded-full overflow-hidden">
              <div
                className="h-full bg-violet-500/60 rounded-full transition-all duration-700"
                style={{ width: `${Math.min(nodeStats.mem_percent, 100)}%` }}
              />
            </div>
          </div>
        </div>
      )}

      {/* Bottom handles — left offset, transform centered */}
      {offsets.map((o, i) => (
        <Handle key={`b${i}`} type="source" position={Position.Bottom} id={`bottom-${i}`} className={hdot(`bottom-${i}`)} style={{ left: o, transform: "translate(-50%, 50%)" }} />
      ))}
      {offsets.map((o, i) => (
        <Handle key={`bt${i}`} type="target" position={Position.Bottom} id={`bottom-${i}-target`} className={hdot(`bottom-${i}`)} style={{ left: o, transform: "translate(-50%, 50%)" }} />
      ))}
    </div>
  );
});
