"use client";

import { useState, useEffect, useCallback } from "react";
import Link from "next/link";
import {
  Search,
  ChevronLeft,
  ChevronRight,
  GitBranch,
  DollarSign,
  Clock,
  ArrowRight,
  Layers,
} from "lucide-react";
import { cn, formatRelativeTime } from "@/lib/utils";

type DecisionType =
  | "TOOL_SELECTION"
  | "ROUTING"
  | "RETRY"
  | "ESCALATION"
  | "MEMORY_RETRIEVAL"
  | "PLANNING"
  | "CUSTOM";

type SortOption = "newest" | "oldest" | "costliest";

interface Decision {
  id: string;
  traceId: string;
  type: DecisionType;
  reasoning: string | null;
  chosen: Record<string, unknown>;
  alternatives: Record<string, unknown>[];
  contextSnapshot: Record<string, unknown> | null;
  durationMs: number | null;
  costUsd: number | null;
  parentSpanId: string | null;
  timestamp: string;
  trace: {
    id: string;
    name: string;
  };
  span: {
    id: string;
    name: string;
  } | null;
}

interface DecisionsResponse {
  decisions: Decision[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

const typeConfig: Record<
  DecisionType,
  { label: string; bg: string; text: string }
> = {
  TOOL_SELECTION: {
    label: "Tool Selection",
    bg: "bg-blue-500/10",
    text: "text-blue-400",
  },
  ROUTING: {
    label: "Routing",
    bg: "bg-purple-500/10",
    text: "text-purple-400",
  },
  RETRY: {
    label: "Retry",
    bg: "bg-amber-500/10",
    text: "text-amber-400",
  },
  ESCALATION: {
    label: "Escalation",
    bg: "bg-red-500/10",
    text: "text-red-400",
  },
  MEMORY_RETRIEVAL: {
    label: "Memory Retrieval",
    bg: "bg-cyan-500/10",
    text: "text-cyan-400",
  },
  PLANNING: {
    label: "Planning",
    bg: "bg-emerald-500/10",
    text: "text-emerald-400",
  },
  CUSTOM: {
    label: "Custom",
    bg: "bg-neutral-500/10",
    text: "text-neutral-400",
  },
};

const sortOptions: { value: SortOption; label: string }[] = [
  { value: "newest", label: "Newest" },
  { value: "oldest", label: "Oldest" },
  { value: "costliest", label: "Most Expensive" },
];

const allTypes: DecisionType[] = [
  "TOOL_SELECTION",
  "ROUTING",
  "RETRY",
  "ESCALATION",
  "MEMORY_RETRIEVAL",
  "PLANNING",
  "CUSTOM",
];

function extractChosenName(chosen: Record<string, unknown>): string {
  if (chosen && typeof chosen === "object") {
    if (typeof chosen.name === "string") return chosen.name;
    if (typeof chosen.action === "string") return chosen.action;
    if (typeof chosen.tool === "string") return chosen.tool;
    // Fallback: first string value
    for (const val of Object.values(chosen)) {
      if (typeof val === "string") return val;
    }
  }
  return "Unknown";
}

function truncate(text: string, max: number): string {
  if (text.length <= max) return text;
  return text.slice(0, max) + "...";
}

export default function DecisionsPage() {
  const [decisions, setDecisions] = useState<Decision[]>([]);
  const [total, setTotal] = useState(0);
  const [totalPages, setTotalPages] = useState(0);
  const [currentPage, setCurrentPage] = useState(1);
  const [isLoading, setIsLoading] = useState(true);

  const [searchQuery, setSearchQuery] = useState("");
  const [typeFilter, setTypeFilter] = useState<DecisionType | "ALL">("ALL");
  const [sortFilter, setSortFilter] = useState<SortOption>("newest");

  const fetchDecisions = useCallback(async () => {
    setIsLoading(true);
    try {
      const params = new URLSearchParams();
      params.set("page", currentPage.toString());
      params.set("limit", "30");

      if (typeFilter !== "ALL") {
        params.set("type", typeFilter);
      }
      if (searchQuery) {
        params.set("search", searchQuery);
      }
      if (sortFilter !== "newest") {
        params.set("sort", sortFilter);
      }

      const res = await fetch(`/api/decisions?${params.toString()}`, {
        cache: "no-store",
      });

      if (!res.ok) {
        throw new Error(`Failed to fetch decisions: ${res.status}`);
      }

      const data: DecisionsResponse = await res.json();
      setDecisions(data.decisions);
      setTotal(data.total);
      setTotalPages(data.totalPages);
    } catch (error) {
      console.error("Error fetching decisions:", error);
    } finally {
      setIsLoading(false);
    }
  }, [currentPage, typeFilter, searchQuery, sortFilter]);

  useEffect(() => {
    fetchDecisions();
  }, [fetchDecisions]);

  useEffect(() => {
    setCurrentPage(1);
  }, [searchQuery, typeFilter, sortFilter]);

  const handlePageChange = (newPage: number) => {
    setCurrentPage(newPage);
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  return (
    <div className="space-y-6">
      {/* Header */}
      <div>
        <h1 className="text-2xl font-bold text-neutral-100">Decisions</h1>
        <p className="text-neutral-400 mt-1">
          {total} decision point{total !== 1 ? "s" : ""} across all traces
        </p>
      </div>

      {/* Search and Filters */}
      <div className="flex flex-col gap-4">
        <div className="flex flex-col sm:flex-row gap-4">
          {/* Search */}
          <div className="relative flex-1">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-neutral-500" />
            <input
              type="text"
              placeholder="Search by reasoning..."
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="w-full pl-10 pr-4 py-3 bg-neutral-900 border border-neutral-800 rounded-lg text-neutral-100 placeholder-neutral-500 focus:outline-none focus:border-emerald-500/50 focus:ring-1 focus:ring-emerald-500/50 transition-all"
            />
          </div>

          {/* Type Filter */}
          <div className="flex items-center gap-3">
            <select
              value={typeFilter}
              onChange={(e) =>
                setTypeFilter(e.target.value as DecisionType | "ALL")
              }
              className="bg-neutral-900 border border-neutral-800 rounded-lg px-3 py-3 text-sm text-neutral-100 focus:outline-none focus:border-emerald-500/50 focus:ring-1 focus:ring-emerald-500/50 transition-all"
            >
              <option value="ALL">All Types</option>
              {allTypes.map((t) => (
                <option key={t} value={t}>
                  {typeConfig[t].label}
                </option>
              ))}
            </select>

            {/* Sort */}
            <select
              value={sortFilter}
              onChange={(e) => setSortFilter(e.target.value as SortOption)}
              className="bg-neutral-900 border border-neutral-800 rounded-lg px-3 py-3 text-sm text-neutral-100 focus:outline-none focus:border-emerald-500/50 focus:ring-1 focus:ring-emerald-500/50 transition-all"
            >
              {sortOptions.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </div>
        </div>
      </div>

      {/* Loading State */}
      {isLoading && decisions.length === 0 && (
        <div className="space-y-3">
          {Array.from({ length: 5 }).map((_, i) => (
            <div
              key={i}
              className="p-5 bg-neutral-900 border border-neutral-800 rounded-xl animate-pulse"
            >
              <div className="flex items-center gap-4">
                <div className="h-6 w-24 bg-neutral-800 rounded-md" />
                <div className="flex-1">
                  <div className="h-5 w-48 bg-neutral-800 rounded-md mb-2" />
                  <div className="h-4 w-96 bg-neutral-800/60 rounded-md" />
                </div>
                <div className="h-4 w-16 bg-neutral-800 rounded-md" />
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Empty State */}
      {!isLoading && decisions.length === 0 && (
        <div className="flex flex-col items-center justify-center py-20 text-center">
          <div className="w-20 h-20 rounded-2xl bg-neutral-900 border border-neutral-800 flex items-center justify-center mb-6">
            <GitBranch className="w-10 h-10 text-neutral-600" />
          </div>
          <h2 className="text-xl font-semibold text-neutral-100 mb-2">
            No decision points yet
          </h2>
          <p className="text-neutral-400 max-w-md">
            Decision points will appear here once your agents start making
            decisions. Send traces with decision data to see them aggregated.
          </p>
        </div>
      )}

      {/* Decision List */}
      {decisions.length > 0 && (
        <div className="space-y-3">
          {decisions.map((decision) => (
            <DecisionCard key={decision.id} decision={decision} />
          ))}
        </div>
      )}

      {/* Pagination */}
      {totalPages > 1 && (
        <div className="flex items-center justify-between pt-6 border-t border-neutral-800">
          <p className="text-sm text-neutral-500">
            Page {currentPage} of {totalPages}
          </p>
          <div className="flex gap-2">
            <button
              disabled={currentPage <= 1}
              onClick={() => handlePageChange(Math.max(1, currentPage - 1))}
              className="p-2 rounded-lg border border-neutral-800 text-neutral-400 hover:text-neutral-100 hover:border-neutral-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
            >
              <ChevronLeft className="w-5 h-5" />
            </button>
            <button
              disabled={currentPage >= totalPages}
              onClick={() =>
                handlePageChange(Math.min(totalPages, currentPage + 1))
              }
              className="p-2 rounded-lg border border-neutral-800 text-neutral-400 hover:text-neutral-100 hover:border-neutral-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
            >
              <ChevronRight className="w-5 h-5" />
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function DecisionCard({ decision }: { decision: Decision }) {
  const config = typeConfig[decision.type] || typeConfig.CUSTOM;
  const chosenName = extractChosenName(
    decision.chosen as Record<string, unknown>
  );

  return (
    <div className="group p-5 bg-neutral-900 border border-neutral-800 rounded-xl hover:border-emerald-500/30 hover:bg-neutral-800/50 transition-all duration-200">
      <div className="flex flex-col lg:flex-row lg:items-center gap-4">
        {/* Left: Type badge + chosen + reasoning */}
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-3 mb-2">
            <span
              className={cn(
                "inline-flex items-center px-2.5 py-1 rounded-md text-xs font-medium uppercase tracking-wide",
                config.bg,
                config.text
              )}
            >
              {config.label}
            </span>
            <h3 className="font-semibold text-neutral-100 truncate">
              {chosenName}
            </h3>
          </div>

          {decision.reasoning && (
            <p className="text-sm text-neutral-400 leading-relaxed">
              {truncate(decision.reasoning, 120)}
            </p>
          )}

          <div className="flex items-center gap-4 mt-2 text-sm text-neutral-500">
            <span className="flex items-center gap-1.5">
              <Clock className="w-3.5 h-3.5" />
              {formatRelativeTime(decision.timestamp)}
            </span>
            {decision.alternatives.length > 0 && (
              <span className="flex items-center gap-1.5">
                <Layers className="w-3.5 h-3.5" />
                {decision.alternatives.length} alternative
                {decision.alternatives.length !== 1 ? "s" : ""}
              </span>
            )}
            {decision.costUsd !== null && decision.costUsd > 0 && (
              <span className="flex items-center gap-1.5">
                <DollarSign className="w-3.5 h-3.5" />$
                {decision.costUsd.toFixed(4)}
              </span>
            )}
            {decision.span && (
              <span className="flex items-center gap-1.5 text-neutral-500">
                <GitBranch className="w-3.5 h-3.5" />
                {decision.span.name}
              </span>
            )}
          </div>
        </div>

        {/* Right: Trace link */}
        <div className="flex items-center gap-3 shrink-0">
          <Link
            href={`/dashboard/traces/${decision.trace.id}`}
            onClick={(e) => e.stopPropagation()}
            className="flex items-center gap-2 px-3 py-2 rounded-lg bg-neutral-800/50 border border-neutral-700/50 text-sm text-neutral-300 hover:text-emerald-400 hover:border-emerald-500/30 transition-all"
          >
            <span className="truncate max-w-[180px]">
              {decision.trace.name}
            </span>
            <ArrowRight className="w-4 h-4 shrink-0" />
          </Link>
        </div>
      </div>
    </div>
  );
}
