"use client";

import { useState, useEffect, useMemo, useCallback } from "react";
import { useSettings } from "@/app/lib/settings";
import { fetchGatewayLogs, type RowValues, ApiError } from "@/app/lib/api";
import { Button } from "./ui/button";
import { Badge } from "./ui/badge";
import { Input } from "./ui/input";
import { ScrollArea } from "./ui/scroll-area";
import {
  FileText,
  RefreshCw,
  Loader2,
  AlertCircle,
  Search,
  Clock,
  ArrowUpDown,
} from "lucide-react";
import { cn } from "@/app/lib/utils";
import { toast } from "sonner";

type Props = {
  clientName: string | null;
};

export default function LogsPage({ clientName }: Props) {
  const { baseUrl, apiKey } = useSettings();
  const ctx = useMemo(() => ({ baseUrl, apiKey }), [baseUrl, apiKey]);
  const [logs, setLogs] = useState<RowValues[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [search, setSearch] = useState("");
  const [limit, setLimit] = useState(100);

  const loadLogs = useCallback(async () => {
    if (!clientName) return;
    setLoading(true);
    setError(null);
    try {
      const result = await fetchGatewayLogs(ctx, clientName, limit);
      setLogs(result);
    } catch (err) {
      const msg = err instanceof ApiError ? err.message : "Failed to load logs";
      setError(msg);
      toast.error("Failed to load logs", { description: msg });
    } finally {
      setLoading(false);
    }
  }, [ctx, clientName, limit]);

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

  const filteredLogs = useMemo(() => {
    if (!search.trim()) return logs;
    const q = search.toLowerCase();
    return logs.filter((log) =>
      Object.values(log).some((v) =>
        String(v ?? "")
          .toLowerCase()
          .includes(q),
      ),
    );
  }, [logs, search]);

  const columns = useMemo(() => {
    if (logs.length === 0) return [];
    return Object.keys(logs[0]);
  }, [logs]);

  return (
    <div className="flex flex-1 flex-col min-h-0">
      <div className="flex items-center gap-3 border-b border-border px-6 py-3">
        <FileText className="h-4 w-4 text-primary" />
        <h2 className="text-sm font-semibold text-foreground">Logs</h2>
        <Badge variant="secondary" className="text-caption">
          {filteredLogs.length} entries
        </Badge>
        <div className="relative ml-4">
          <Search className="absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
          <Input
            placeholder="Search logs..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="h-7 w-[200px] pl-7 text-xs"
          />
        </div>
        <div className="flex-1" />
        <select
          value={limit}
          onChange={(e) => setLimit(Number(e.target.value))}
          className="h-7 rounded border border-border bg-background px-2 text-xs text-foreground"
        >
          <option value={50}>50 rows</option>
          <option value={100}>100 rows</option>
          <option value={500}>500 rows</option>
        </select>
        <Button
          variant="outline"
          size="sm"
          onClick={loadLogs}
          disabled={loading}
        >
          {loading ? (
            <Loader2 className="h-3 w-3 animate-spin" />
          ) : (
            <RefreshCw className="h-3 w-3" />
          )}
          Refresh
        </Button>
      </div>

      {error && (
        <div className="flex items-center gap-2 border-b border-destructive-border bg-destructive-subtle px-6 py-3 text-xs text-destructive">
          <AlertCircle className="h-3.5 w-3.5" />
          {error}
        </div>
      )}

      {loading && logs.length === 0 && (
        <div className="flex flex-1 items-center justify-center">
          <Loader2 className="h-6 w-6 animate-spin text-primary" />
        </div>
      )}

      {!loading && logs.length === 0 && !error && (
        <div className="flex flex-1 flex-col items-center justify-center gap-3 text-muted-foreground">
          <FileText className="h-10 w-10 opacity-20" />
          <p className="text-sm">No logs found</p>
          <p className="text-xs text-muted-foreground-subtle">
            Gateway request logs will appear here when available
          </p>
        </div>
      )}

      {logs.length > 0 && (
        <div className="flex-1 overflow-auto">
          <table className="w-full border-collapse text-xs">
            <thead className="sticky top-0 z-[5]">
              <tr>
                {columns.map((col) => (
                  <th
                    key={col}
                    className="border-b border-r border-border/50 bg-grid-header px-3 py-2 text-left text-caption font-medium text-muted-foreground whitespace-nowrap"
                  >
                    <span className="flex items-center gap-1">
                      {col}
                      <ArrowUpDown className="h-2.5 w-2.5 opacity-30" />
                    </span>
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {filteredLogs.map((log, i) => (
                <tr
                  key={i}
                  className="border-b border-border/50 hover:bg-accent-muted transition-colors"
                >
                  {columns.map((col) => {
                    const val = log[col];
                    const isTime = col.includes("at") || col.includes("time");
                    return (
                      <td
                        key={col}
                        className={cn(
                          "border-r border-border-faint px-3 py-1.5 font-mono text-xs whitespace-nowrap max-w-[300px] truncate",
                          val === null && "text-muted-foreground italic",
                        )}
                      >
                        {val === null
                          ? "NULL"
                          : isTime && typeof val === "string"
                            ? new Date(val).toLocaleString()
                            : typeof val === "object"
                              ? JSON.stringify(val)
                              : String(val)}
                      </td>
                    );
                  })}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}
