"use client";

import { useState, useEffect, useMemo, useCallback, Suspense } from "react";
import { useSearchParams, useRouter, usePathname } from "next/navigation";
import { Card } from "@/components/ui/card";
import { DataTable, type Column } from "@/components/ui/data-table";
import { Select } from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { StatCard } from "@/components/ui/stat-card";
import { Trash2, DollarSign, Calendar } from "lucide-react";
import { formatCurrency } from "@/lib/utils";

interface CostEntry {
  id: string;
  provider: string;
  amount: number;
  period: string;
  category: string;
  note: string | null;
  createdAt: string;
}

const providerLabels: Record<string, string> = {
  openai: "OpenAI",
  anthropic: "Anthropic",
  google: "Google AI",
  aws: "AWS Bedrock",
  azure: "Azure",
  manual: "Manual",
  other: "Other",
};

const providerOptions = [
  { value: "all", label: "All Providers" },
  { value: "openai", label: "OpenAI" },
  { value: "anthropic", label: "Anthropic" },
  { value: "google", label: "Google AI" },
  { value: "aws", label: "AWS Bedrock" },
  { value: "azure", label: "Azure" },
  { value: "other", label: "Other" },
];

const periodOptions = [
  { value: "all", label: "All Time" },
  { value: "this-month", label: "This Month" },
  { value: "last-month", label: "Last Month" },
  { value: "last-3-months", label: "Last 3 Months" },
  { value: "last-6-months", label: "Last 6 Months" },
  { value: "this-year", label: "This Year" },
];

function getPeriodRange(filter: string): { start: string; end: string } | null {
  const now = new Date();
  const year = now.getFullYear();
  const month = now.getMonth(); // 0-indexed

  switch (filter) {
    case "this-month":
      return {
        start: `${year}-${String(month + 1).padStart(2, "0")}`,
        end: `${year}-${String(month + 1).padStart(2, "0")}`,
      };
    case "last-month": {
      const lastMonth = month === 0 ? 11 : month - 1;
      const lastMonthYear = month === 0 ? year - 1 : year;
      return {
        start: `${lastMonthYear}-${String(lastMonth + 1).padStart(2, "0")}`,
        end: `${lastMonthYear}-${String(lastMonth + 1).padStart(2, "0")}`,
      };
    }
    case "last-3-months": {
      const threeMonthsAgo = new Date(year, month - 2, 1);
      return {
        start: `${threeMonthsAgo.getFullYear()}-${String(threeMonthsAgo.getMonth() + 1).padStart(2, "0")}`,
        end: `${year}-${String(month + 1).padStart(2, "0")}`,
      };
    }
    case "last-6-months": {
      const sixMonthsAgo = new Date(year, month - 5, 1);
      return {
        start: `${sixMonthsAgo.getFullYear()}-${String(sixMonthsAgo.getMonth() + 1).padStart(2, "0")}`,
        end: `${year}-${String(month + 1).padStart(2, "0")}`,
      };
    }
    case "this-year":
      return {
        start: `${year}-01`,
        end: `${year}-12`,
      };
    default:
      return null; // "all" or unknown
  }
}

type SortKey = "createdAt" | "amount" | "provider";
type SortDir = "asc" | "desc";

function SpendingContent() {
  const searchParams = useSearchParams();
  const router = useRouter();
  const pathname = usePathname();

  const [entries, setEntries] = useState<CostEntry[]>([]);
  const [loading, setLoading] = useState(true);
  const [providerFilter, setProviderFilter] = useState(
    searchParams.get("provider") ?? "all"
  );
  const [periodFilter, setPeriodFilter] = useState(
    searchParams.get("period") ?? "all"
  );
  const [sortKey, setSortKey] = useState<SortKey>("createdAt");
  const [sortDir, setSortDir] = useState<SortDir>("desc");

  // Update URL when filters change
  useEffect(() => {
    const params = new URLSearchParams();
    if (providerFilter !== "all") params.set("provider", providerFilter);
    if (periodFilter !== "all") params.set("period", periodFilter);
    router.replace(`${pathname}?${params.toString()}`);
  }, [providerFilter, periodFilter, pathname, router]);

  const fetchEntries = useCallback(async () => {
    try {
      const params = new URLSearchParams();
      if (providerFilter !== "all") params.set("provider", providerFilter);

      const res = await fetch(`/api/costs?${params}`);
      if (res.ok) {
        const data = await res.json();
        setEntries(data.entries);
      }
    } catch {
      // silently fail — empty state shown
    } finally {
      setLoading(false);
    }
  }, [providerFilter]);

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

  const filtered = useMemo(() => {
    const range = getPeriodRange(periodFilter);
    if (!range) return entries; // "all" - no filtering

    return entries.filter((entry) => {
      return entry.period >= range.start && entry.period <= range.end;
    });
  }, [entries, periodFilter]);

  const sorted = useMemo(() => {
    return [...filtered].sort((a, b) => {
      let cmp = 0;
      if (sortKey === "amount") cmp = a.amount - b.amount;
      else if (sortKey === "provider")
        cmp = a.provider.localeCompare(b.provider);
      else cmp = a.createdAt.localeCompare(b.createdAt);
      return sortDir === "desc" ? -cmp : cmp;
    });
  }, [filtered, sortKey, sortDir]);

  const totalFiltered = sorted.reduce((s, e) => s + e.amount, 0);
  const entryCount = sorted.length;

  async function handleDelete(id: string) {
    try {
      const res = await fetch(`/api/costs/${id}`, { method: "DELETE" });
      if (res.ok) {
        setEntries((prev) => prev.filter((e) => e.id !== id));
      }
    } catch {
      // ignore
    }
  }

  function toggleSort(key: SortKey) {
    if (sortKey === key) {
      setSortDir((d) => (d === "asc" ? "desc" : "asc"));
    } else {
      setSortKey(key);
      setSortDir("desc");
    }
  }

  const sortIndicator = (key: SortKey) =>
    sortKey === key ? (sortDir === "desc" ? " v" : " ^") : "";

  const columns: Column<CostEntry>[] = [
    {
      key: "createdAt",
      header: `Date${sortIndicator("createdAt")}`,
      render: (row) => new Date(row.createdAt).toLocaleDateString(),
    },
    {
      key: "provider",
      header: `Provider${sortIndicator("provider")}`,
      render: (row) => (
        <span className="font-medium text-gray-100">
          {providerLabels[row.provider] ?? row.provider}
        </span>
      ),
    },
    {
      key: "amount",
      header: `Amount${sortIndicator("amount")}`,
      render: (row) => (
        <span className="font-medium text-gray-100">
          {formatCurrency(row.amount)}
        </span>
      ),
    },
    { key: "category", header: "Category" },
    {
      key: "note",
      header: "Note",
      render: (row) => (
        <span className="text-gray-400">{row.note ?? "—"}</span>
      ),
    },
  ];

  return (
    <div className="space-y-8">
      <div>
        <h1 className="text-2xl font-bold text-gray-100">Spending</h1>
        <p className="mt-1 text-sm text-gray-400">
          Detailed breakdown of all your AI costs
        </p>
      </div>

      {/* Summary stats */}
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
        <StatCard
          title="Total (Filtered)"
          value={formatCurrency(totalFiltered)}
          icon={<DollarSign size={20} />}
        />
        <StatCard
          title="Entries"
          value={String(entryCount)}
          icon={<Calendar size={20} />}
        />
        <StatCard
          title="Avg per Entry"
          value={formatCurrency(
            entryCount > 0 ? totalFiltered / entryCount : 0,
          )}
          icon={<DollarSign size={20} />}
        />
      </div>

      {/* Filters */}
      <Card>
        <div className="flex flex-col gap-4 sm:flex-row sm:items-end">
          <div className="flex-1">
            <Select
              id="provider-filter"
              label="Provider"
              options={providerOptions}
              value={providerFilter}
              onChange={(e) => setProviderFilter(e.target.value)}
            />
          </div>
          <div className="flex-1">
            <Select
              id="period-filter"
              label="Time Period"
              options={periodOptions}
              value={periodFilter}
              onChange={(e) => setPeriodFilter(e.target.value)}
            />
          </div>
          <div className="flex gap-2">
            <Button
              variant="ghost"
              size="sm"
              onClick={() => toggleSort("createdAt")}
            >
              Sort by Date
            </Button>
            <Button
              variant="ghost"
              size="sm"
              onClick={() => toggleSort("amount")}
            >
              Sort by Amount
            </Button>
            <Button
              variant="ghost"
              size="sm"
              onClick={() => toggleSort("provider")}
            >
              Sort by Provider
            </Button>
          </div>
        </div>
      </Card>

      {/* Table */}
      <Card>
        {loading ? (
          <p className="py-8 text-center text-sm text-gray-500">Loading...</p>
        ) : (
          <DataTable<CostEntry>
            columns={columns}
            data={sorted}
            keyExtractor={(row) => row.id}
            emptyMessage="No entries yet. Add your first cost entry."
            actions={(row) => (
              <Button
                variant="ghost"
                size="sm"
                onClick={() => handleDelete(row.id)}
                className="text-red-400 hover:text-red-300"
              >
                <Trash2 size={16} />
              </Button>
            )}
          />
        )}
      </Card>
    </div>
  );
}

export default function SpendingPage() {
  return (
    <Suspense fallback={<div className="p-8 text-center text-gray-400">Loading...</div>}>
      <SpendingContent />
    </Suspense>
  );
}
