"use client";

import { useEffect, useState, useCallback } from "react";
import { useTranslations, useLocale } from "next-intl";
import { motion, AnimatePresence } from "framer-motion";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { useSSE } from "@/hooks/use-sse";

interface FeedItem {
  id: string;
  type: "task" | "online" | "offline" | "registered";
  clawName: string;
  city?: string;
  country?: string;
  summary?: string;
  durationMs?: number;
  timestamp: number;
}

export function ClawFeed() {
  const t = useTranslations("clawFeed");
  const locale = useLocale();
  const [items, setItems] = useState<FeedItem[]>([]);

  const handleEvent = useCallback((event: { type: string; data: Record<string, unknown> }) => {
    if (event.type === "task" || event.type === "online" || event.type === "offline" || event.type === "registered") {
      const newItem: FeedItem = {
        id: `${Date.now()}-${Math.random().toString(36).slice(2)}`,
        type: event.type as FeedItem["type"],
        clawName: (event.data.clawName as string) ?? "Unknown",
        city: event.data.city as string | undefined,
        country: event.data.country as string | undefined,
        summary: event.data.summary as string | undefined,
        durationMs: event.data.durationMs as number | undefined,
        timestamp: Date.now(),
      };

      setItems((prev) => [newItem, ...prev].slice(0, 50));
    }
  }, []);

  useSSE({
    url: "/api/v1/stream",
    onEvent: handleEvent,
  });

  // Load initial recent tasks + newest registrations
  useEffect(() => {
    const fetchRecent = async () => {
      try {
        const [taskRes, newestRes] = await Promise.all([
          fetch("/api/v1/claws?limit=10"),
          fetch("/api/v1/claws?sort=newest&limit=5"),
        ]);

        const feedItems: FeedItem[] = [];

        if (taskRes.ok) {
          const data = await taskRes.json();
          const taskItems: FeedItem[] = (data.claws ?? [])
            .filter((l: Record<string, unknown>) => l.lastTask)
            .map((l: Record<string, unknown>) => {
              const task = l.lastTask as Record<string, unknown>;
              return {
                id: `init-task-${l.id}`,
                type: "task" as const,
                clawName: l.name as string,
                city: l.city as string,
                country: l.country as string,
                summary: task.summary as string,
                durationMs: task.durationMs as number,
                timestamp: new Date(task.timestamp as string).getTime(),
              };
            });
          feedItems.push(...taskItems);
        }

        if (newestRes.ok) {
          const data = await newestRes.json();
          const regItems: FeedItem[] = (data.claws ?? [])
            .filter((l: Record<string, unknown>) => l.createdAt)
            .map((l: Record<string, unknown>) => ({
              id: `init-reg-${l.id}`,
              type: "registered" as const,
              clawName: l.name as string,
              city: l.city as string,
              country: l.country as string,
              timestamp: new Date(l.createdAt as string).getTime(),
            }));
          feedItems.push(...regItems);
        }

        // Deduplicate by clawName+type, sort by timestamp desc
        const seen = new Set<string>();
        const unique = feedItems.filter((item) => {
          const key = `${item.clawName}-${item.type}`;
          if (seen.has(key)) return false;
          seen.add(key);
          return true;
        });
        unique.sort((a, b) => b.timestamp - a.timestamp);

        setItems(unique);
      } catch {
        // will populate via SSE
      }
    };
    fetchRecent();
  }, []);

  const formatDuration = (ms?: number) => {
    if (!ms) return "";
    if (ms < 1000) return `${ms}ms`;
    return `${(ms / 1000).toFixed(1)}s`;
  };

  const getIcon = (type: string) => {
    switch (type) {
      case "task":
        return "⚡";
      case "online":
        return "🟢";
      case "offline":
        return "⭕";
      case "registered":
        return "🦞";
      default:
        return "🦞";
    }
  };

  const getDescription = (item: FeedItem) => {
    if (item.type === "registered" && item.city && item.country) {
      return t("joinedFrom", { city: item.city, country: item.country });
    }
    return item.summary;
  };

  return (
    <Card className="border-white/5">
      <CardHeader className="pb-2">
        <CardTitle>{t("title")}</CardTitle>
      </CardHeader>
      <CardContent className="max-h-[400px] overflow-y-auto p-4 pt-0">
        <AnimatePresence initial={false}>
          {items.length === 0 ? (
            <p className="py-8 text-center text-xs text-[var(--text-muted)]">
              {t("waiting")}
            </p>
          ) : (
            items.map((item) => (
              <motion.div
                key={item.id}
                initial={{ opacity: 0, height: 0, y: -10 }}
                animate={{ opacity: 1, height: "auto", y: 0 }}
                exit={{ opacity: 0, height: 0 }}
                transition={{ duration: 0.3 }}
                className="border-b border-white/5 py-2.5 last:border-0"
              >
                <div className="flex items-start gap-2">
                  <span className="mt-0.5 text-sm">{getIcon(item.type)}</span>
                  <div className="min-w-0 flex-1">
                    <div className="flex items-center gap-2">
                      <span className="font-mono text-xs font-medium text-[var(--accent-cyan)]">
                        {item.clawName}
                      </span>
                      {item.city && item.type !== "registered" && (
                        <span className="text-xs text-[var(--text-muted)]">
                          {item.city}, {item.country}
                        </span>
                      )}
                    </div>
                    {getDescription(item) && (
                      <p className="mt-0.5 truncate text-xs text-[var(--text-secondary)]">
                        {getDescription(item)}
                      </p>
                    )}
                    <div className="mt-1 flex items-center gap-2">
                      {item.durationMs && (
                        <Badge variant="secondary">{formatDuration(item.durationMs)}</Badge>
                      )}
                      <span className="text-[10px] text-[var(--text-muted)]">
                        {new Date(item.timestamp).toLocaleTimeString(locale)}
                      </span>
                    </div>
                  </div>
                </div>
              </motion.div>
            ))
          )}
        </AnimatePresence>
      </CardContent>
    </Card>
  );
}
