"use client";

import { useState, useMemo } from "react";
import { GitBranch, Search, Calendar, Clock } from "lucide-react";
import { Badge } from "@/shared/components/ui/badge";
import { Button } from "@/shared/components/ui/button";
import { Input } from "@/shared/components/ui/input";
import type { RegistryEntry } from "../types";
import { FlowDiagram } from "./flow-diagram";
import { cn } from "@/shared/lib/utils";

interface ThreadExplorerProps {
  entries: RegistryEntry[];
  onNavigateEntry?: (entry: RegistryEntry) => void;
}

/** A thread is a chain of entries linked by threadParentId */
interface Thread {
  id: string;
  root: RegistryEntry;
  chain: RegistryEntry[];
  totalDays: number;
  isActive: boolean;
}

function daysBetween(d1: string, d2: string): number {
  const a = new Date(d1);
  const b = new Date(d2);
  a.setHours(0, 0, 0, 0);
  b.setHours(0, 0, 0, 0);
  return Math.max(
    0,
    Math.round(Math.abs(b.getTime() - a.getTime()) / (1000 * 60 * 60 * 24)),
  );
}

function formatShortDate(iso: string): string {
  try {
    return new Date(iso).toLocaleDateString("ro-RO", {
      day: "2-digit",
      month: "short",
    });
  } catch {
    return iso;
  }
}

/** Build threads from all entries */
function buildThreads(entries: RegistryEntry[]): Thread[] {
  const byId = new Map(entries.map((e) => [e.id, e]));
  const childrenMap = new Map<string, RegistryEntry[]>();
  const rootIds = new Set<string>();

  for (const entry of entries) {
    if (entry.threadParentId) {
      const existing = childrenMap.get(entry.threadParentId) ?? [];
      existing.push(entry);
      childrenMap.set(entry.threadParentId, existing);
    }
  }

  for (const entry of entries) {
    if (!entry.threadParentId && childrenMap.has(entry.id)) {
      rootIds.add(entry.id);
    }
    if (entry.threadParentId) {
      let current = entry;
      while (current.threadParentId) {
        const parent = byId.get(current.threadParentId);
        if (!parent) break;
        current = parent;
      }
      rootIds.add(current.id);
    }
  }

  const threads: Thread[] = [];

  for (const rootId of rootIds) {
    const root = byId.get(rootId);
    if (!root) continue;

    const chain: RegistryEntry[] = [];
    const queue = [rootId];
    const visited = new Set<string>();

    while (queue.length > 0) {
      const id = queue.shift()!;
      if (visited.has(id)) continue;
      visited.add(id);
      const entry = byId.get(id);
      if (!entry) continue;
      chain.push(entry);
      const children = childrenMap.get(id) ?? [];
      for (const child of children) {
        queue.push(child.id);
      }
    }

    chain.sort(
      (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime(),
    );

    if (chain.length < 2) continue;

    const firstDate = chain[0]!.date;
    const lastDate = chain[chain.length - 1]!.date;
    const totalDays = daysBetween(firstDate, lastDate);
    const isActive = chain.some((e) => e.status === "deschis");

    threads.push({ id: rootId, root, chain, totalDays, isActive });
  }

  threads.sort((a, b) => {
    if (a.isActive !== b.isActive) return a.isActive ? -1 : 1;
    const aLast = a.chain[a.chain.length - 1]!.date;
    const bLast = b.chain[b.chain.length - 1]!.date;
    return bLast.localeCompare(aLast);
  });

  return threads;
}

export function ThreadExplorer({
  entries,
  onNavigateEntry,
}: ThreadExplorerProps) {
  const [search, setSearch] = useState("");
  const [activeOnly, setActiveOnly] = useState(false);

  const threads = useMemo(() => buildThreads(entries), [entries]);

  const filtered = useMemo(() => {
    return threads.filter((t) => {
      if (activeOnly && !t.isActive) return false;
      if (search.trim()) {
        const q = search.toLowerCase();
        return t.chain.some(
          (e) =>
            e.number.toLowerCase().includes(q) ||
            e.subject.toLowerCase().includes(q) ||
            e.sender.toLowerCase().includes(q) ||
            e.recipient.toLowerCase().includes(q),
        );
      }
      return true;
    });
  }, [threads, search, activeOnly]);

  const activeCount = threads.filter((t) => t.isActive).length;
  const closedCount = threads.length - activeCount;

  return (
    <div className="space-y-4">
      {/* Summary + filters */}
      <div className="flex items-center gap-4">
        <p className="text-sm text-muted-foreground">
          <span className="font-medium text-foreground">{activeCount}</span>{" "}
          {activeCount === 1 ? "dosar activ" : "dosare active"},{" "}
          <span className="font-medium text-foreground">{closedCount}</span>{" "}
          finalizate
        </p>

        <div className="ml-auto flex items-center gap-2">
          <div className="relative">
            <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder="Cauta..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="h-9 w-[200px] pl-9"
            />
          </div>
          <Button
            variant={activeOnly ? "default" : "outline"}
            size="sm"
            onClick={() => setActiveOnly(!activeOnly)}
          >
            Doar active
          </Button>
        </div>
      </div>

      {/* Thread list with flow diagrams */}
      {filtered.length === 0 ? (
        <div className="py-12 text-center">
          <GitBranch className="mx-auto h-10 w-10 text-muted-foreground/40" />
          <p className="mt-2 text-sm text-muted-foreground">
            {threads.length === 0
              ? "Niciun dosar. Inchideti o inregistrare cu raspuns (Inchide) pentru a forma un dosar."
              : "Niciun dosar corespunde filtrelor."}
          </p>
        </div>
      ) : (
        <div className="space-y-4">
          {filtered.map((thread) => (
            <ThreadCard
              key={thread.id}
              thread={thread}
              allEntries={entries}
              onNodeClick={onNavigateEntry}
            />
          ))}
        </div>
      )}
    </div>
  );
}

// ── Thread card with flow diagram ──

function ThreadCard({
  thread,
  allEntries,
  onNodeClick,
}: {
  thread: Thread;
  allEntries: RegistryEntry[];
  onNodeClick?: (entry: RegistryEntry) => void;
}) {
  return (
    <div
      className={cn(
        "rounded-lg border bg-card",
        thread.isActive
          ? "border-border"
          : "border-muted bg-muted/20",
      )}
    >
      {/* Header */}
      <div className="flex items-center gap-3 border-b px-4 py-3">
        <GitBranch className="h-4 w-4 shrink-0 text-primary" />
        <span className="truncate text-sm font-medium">
          {thread.root.subject}
        </span>
        <Badge
          variant={thread.isActive ? "default" : "secondary"}
          className="shrink-0 text-[10px]"
        >
          {thread.isActive ? "Activ" : "Finalizat"}
        </Badge>
        <div className="ml-auto flex items-center gap-3 text-xs text-muted-foreground">
          <span className="flex items-center gap-1">
            <Calendar className="h-3 w-3" />
            {formatShortDate(thread.chain[0]!.date)} —{" "}
            {formatShortDate(thread.chain[thread.chain.length - 1]!.date)}
          </span>
          <span className="flex items-center gap-1">
            <Clock className="h-3 w-3" />
            {thread.totalDays}z
          </span>
          <Badge variant="outline" className="text-[10px]">
            {thread.chain.length} doc.
          </Badge>
        </div>
      </div>

      {/* Flow diagram */}
      <div className="px-4 py-3">
        <FlowDiagram
          chain={thread.chain}
          allEntries={allEntries}
          onNodeClick={onNodeClick}
        />
      </div>
    </div>
  );
}
