"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { useSettings } from "@/app/lib/settings";
import {
  ApiError,
  fetchAuditLogEvents,
  type AuditLogEvent,
} from "@/app/lib/api";
import { Input } from "./ui/input";
import { Button } from "./ui/button";
import { Badge } from "./ui/badge";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "./ui/dialog";
import {
  Activity,
  AlertCircle,
  Loader2,
  RefreshCw,
  Search,
  Copy,
  X,
} from "lucide-react";
import { cn } from "@/app/lib/utils";
import { toast } from "sonner";

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

const EVENT_COLORS: Record<string, string> = {
  ui_request: "bg-info-subtle text-info border-info-border",
  feedback: "bg-warning-subtle text-warning border-warning-border",
  organization_request: "bg-success-subtle text-success border-success-border",
  project_request: "bg-highlight-subtle text-highlight border-highlight-border",
};

function formatDateTime(input?: string | null): string {
  if (!input) return "-";
  const date = new Date(input);
  if (Number.isNaN(date.getTime())) return String(input);
  return date.toLocaleString();
}

export default function AuditLogPage({ clientName }: Props) {
  const { baseUrl, apiKey } = useSettings();
  const ctx = useMemo(() => ({ baseUrl, apiKey }), [baseUrl, apiKey]);

  const [events, setEvents] = useState<AuditLogEvent[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [search, setSearch] = useState("");
  const [limit, setLimit] = useState(150);
  const [selectedType, setSelectedType] = useState("all");
  const [selectedStatus, setSelectedStatus] = useState("all");
  const [autoRefreshEnabled, setAutoRefreshEnabled] = useState(true);
  const [refreshSeconds, setRefreshSeconds] = useState(15);
  const [selectedEvent, setSelectedEvent] = useState<AuditLogEvent | null>(
    null,
  );

  const loadAuditEvents = useCallback(async () => {
    if (!clientName) return;
    setLoading(true);
    setError(null);
    try {
      const rows = await fetchAuditLogEvents(ctx, clientName, limit);
      setEvents(rows);
    } catch (err) {
      const msg =
        err instanceof ApiError ? err.message : "Failed to load audit log";
      setError(msg);
      toast.error("Failed to load audit log", { description: msg });
    } finally {
      setLoading(false);
    }
  }, [clientName, ctx, limit]);

  useEffect(() => {
    void loadAuditEvents();
  }, [loadAuditEvents]);

  useEffect(() => {
    if (!clientName || !autoRefreshEnabled) return;
    const timer = window.setInterval(() => {
      void loadAuditEvents();
    }, refreshSeconds * 1000);
    return () => window.clearInterval(timer);
  }, [autoRefreshEnabled, clientName, loadAuditEvents, refreshSeconds]);

  const eventTypes = useMemo(() => {
    return [
      "all",
      ...Array.from(new Set(events.map((event) => event.event_type))).sort(),
    ];
  }, [events]);

  const statusValues = useMemo(() => {
    return [
      "all",
      ...Array.from(
        new Set(
          events
            .map((event) => (event.status ?? "").trim())
            .filter((status) => status.length > 0),
        ),
      ).sort(),
    ];
  }, [events]);

  const filtered = useMemo(() => {
    const term = search.trim().toLowerCase();
    return events.filter((event) => {
      const typeOk =
        selectedType === "all" || event.event_type === selectedType;
      const statusOk =
        selectedStatus === "all" ||
        (event.status ?? "").trim() === selectedStatus;
      if (!typeOk || !statusOk) return false;

      if (!term) return true;
      return (
        event.event_type.toLowerCase().includes(term) ||
        event.title.toLowerCase().includes(term) ||
        (event.summary ?? "").toLowerCase().includes(term) ||
        (event.status ?? "").toLowerCase().includes(term)
      );
    });
  }, [events, search, selectedStatus, selectedType]);

  return (
    <div className="flex flex-1 min-h-0 flex-col overflow-hidden">
      <div className="flex flex-wrap items-center gap-2 sm:gap-3 border-b border-border px-3 sm:px-6 py-3">
        <Activity className="h-4 w-4 text-primary shrink-0" />
        <h2 className="text-sm font-semibold text-foreground">Audit Log</h2>
        <Badge
          variant="secondary"
          className="text-caption hidden sm:inline-flex"
        >
          {filtered.length} events
        </Badge>

        <div className="relative w-full sm:w-auto sm:ml-2 order-last sm:order-none">
          <Search className="absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
          <Input
            placeholder="Search updates..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="h-8 w-full sm:w-64 pl-7 text-xs"
          />
        </div>

        <div className="flex-1 hidden sm:block" />

        <select
          value={limit}
          onChange={(e) => setLimit(Number(e.target.value))}
          className="h-8 rounded border border-border bg-background px-2 text-xs text-foreground hidden sm:block"
        >
          <option value={50}>50 rows</option>
          <option value={150}>150 rows</option>
          <option value={300}>300 rows</option>
        </select>

        <Button
          variant="outline"
          size="sm"
          onClick={() => void loadAuditEvents()}
          disabled={loading}
        >
          {loading ? (
            <Loader2 className="h-3.5 w-3.5 animate-spin" />
          ) : (
            <RefreshCw className="h-3.5 w-3.5" />
          )}
          <span className="hidden sm:inline">Refresh</span>
        </Button>

        <Button
          variant={autoRefreshEnabled ? "default" : "outline"}
          size="sm"
          onClick={() => setAutoRefreshEnabled((v) => !v)}
        >
          Live {autoRefreshEnabled ? "On" : "Off"}
        </Button>

        <select
          value={refreshSeconds}
          onChange={(e) => setRefreshSeconds(Number(e.target.value))}
          className="h-8 rounded border border-border bg-background px-2 text-xs text-foreground hidden sm:block"
          disabled={!autoRefreshEnabled}
        >
          <option value={10}>10s</option>
          <option value={15}>15s</option>
          <option value={30}>30s</option>
        </select>
      </div>

      <div className="flex flex-wrap items-center gap-1.5 sm:gap-2 border-b border-border px-3 sm:px-6 py-2.5 overflow-x-auto">
        <span className="text-body-sm font-medium text-muted-foreground">
          Type:
        </span>
        {eventTypes.map((type) => {
          const selected = selectedType === type;
          return (
            <button
              key={type}
              type="button"
              onClick={() => setSelectedType(type)}
              className={cn(
                "rounded-full border px-2.5 py-0.5 text-caption font-semibold uppercase tracking-wide transition-colors",
                selected
                  ? "border-primary-border bg-primary-panel text-primary"
                  : "border-border text-muted-foreground hover:text-foreground",
              )}
            >
              {type.replace("_", " ")}
            </button>
          );
        })}

        <span className="ml-2 text-body-sm font-medium text-muted-foreground">
          Status:
        </span>
        {statusValues.map((status) => {
          const selected = selectedStatus === status;
          return (
            <button
              key={status}
              type="button"
              onClick={() => setSelectedStatus(status)}
              className={cn(
                "rounded-full border px-2.5 py-0.5 text-caption font-semibold uppercase tracking-wide transition-colors",
                selected
                  ? "border-primary-border bg-primary-panel text-primary"
                  : "border-border text-muted-foreground hover:text-foreground",
              )}
            >
              {status || "all"}
            </button>
          );
        })}
      </div>

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

      {!clientName && (
        <div className="flex flex-1 items-center justify-center text-sm text-muted-foreground">
          Select a client to view audit events.
        </div>
      )}

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

      {clientName && !loading && filtered.length === 0 && !error && (
        <div className="flex flex-1 items-center justify-center text-sm text-muted-foreground">
          No audit events found yet.
        </div>
      )}

      {clientName && filtered.length > 0 && (
        <div className="flex-1 overflow-auto px-5 py-4">
          <div className="space-y-3">
            {filtered.map((event, index) => (
              <article
                key={`${event.event_type}-${event.created_at}-${index}`}
                className="rounded-lg border border-border bg-card p-4 shadow-sm transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md cursor-pointer"
                onClick={() => setSelectedEvent(event)}
              >
                <div className="flex items-start justify-between gap-3">
                  <div className="space-y-1 min-w-0">
                    <div className="flex items-center gap-2 flex-wrap">
                      <span
                        className={cn(
                          "inline-flex rounded-full border px-2 py-0.5 text-caption font-semibold uppercase tracking-wide",
                          EVENT_COLORS[event.event_type] ??
                            "bg-muted text-foreground border-border",
                        )}
                      >
                        {event.event_type.replace("_", " ")}
                      </span>
                      {event.status && (
                        <span className="text-body-sm text-muted-foreground">
                          {event.status}
                        </span>
                      )}
                    </div>
                    <h3 className="text-sm font-semibold text-foreground truncate">
                      {event.title}
                    </h3>
                    {event.summary && (
                      <p className="text-xs text-muted-foreground/85 line-clamp-2">
                        {event.summary}
                      </p>
                    )}
                  </div>
                  <div className="text-right shrink-0">
                    <p className="text-xs font-medium text-foreground-subtle">
                      {formatDateTime(event.created_at)}
                    </p>
                    {event.client_name && (
                      <p className="text-body-sm text-muted-foreground">
                        {event.client_name}
                      </p>
                    )}
                  </div>
                </div>
              </article>
            ))}
          </div>
        </div>
      )}

      <Dialog
        open={!!selectedEvent}
        onOpenChange={(v) => !v && setSelectedEvent(null)}
      >
        <DialogContent className="max-w-lg max-h-[85vh] overflow-hidden flex flex-col p-0">
          {selectedEvent && (
            <>
              <div className="px-6 pt-6 pb-3 border-b border-border">
                <DialogHeader>
                  <div className="flex items-center gap-2 mb-2">
                    <span
                      className={cn(
                        "inline-flex rounded-full border px-2.5 py-0.5 text-caption font-semibold uppercase tracking-wide",
                        EVENT_COLORS[selectedEvent.event_type] ??
                          "bg-muted text-foreground border-border",
                      )}
                    >
                      {selectedEvent.event_type.replace("_", " ")}
                    </span>
                    {selectedEvent.status && (
                      <Badge variant="secondary" className="text-caption">
                        {selectedEvent.status}
                      </Badge>
                    )}
                  </div>
                  <DialogTitle className="text-base">
                    {selectedEvent.title}
                  </DialogTitle>
                  <DialogDescription>
                    {formatDateTime(selectedEvent.created_at)}
                  </DialogDescription>
                </DialogHeader>
              </div>
              <div className="flex-1 overflow-y-auto min-h-0 px-6 py-4">
                <div className="space-y-4">
                  {selectedEvent.summary && (
                    <div>
                      <h4 className="text-body-sm font-medium text-muted-foreground uppercase tracking-wider mb-1">
                        Summary
                      </h4>
                      <p className="text-sm text-foreground whitespace-pre-wrap">
                        {selectedEvent.summary}
                      </p>
                    </div>
                  )}

                  <div className="grid grid-cols-2 gap-4">
                    <div>
                      <h4 className="text-body-sm font-medium text-muted-foreground uppercase tracking-wider mb-1">
                        Event type
                      </h4>
                      <p className="text-sm text-foreground font-mono">
                        {selectedEvent.event_type}
                      </p>
                    </div>
                    <div>
                      <h4 className="text-body-sm font-medium text-muted-foreground uppercase tracking-wider mb-1">
                        Timestamp
                      </h4>
                      <p className="text-sm text-foreground font-mono">
                        {selectedEvent.created_at}
                      </p>
                    </div>
                    {selectedEvent.client_name && (
                      <div>
                        <h4 className="text-body-sm font-medium text-muted-foreground uppercase tracking-wider mb-1">
                          Client
                        </h4>
                        <p className="text-sm text-foreground font-mono">
                          {selectedEvent.client_name}
                        </p>
                      </div>
                    )}
                    {selectedEvent.status && (
                      <div>
                        <h4 className="text-body-sm font-medium text-muted-foreground uppercase tracking-wider mb-1">
                          Status
                        </h4>
                        <p className="text-sm text-foreground">
                          {selectedEvent.status}
                        </p>
                      </div>
                    )}
                  </div>

                  {selectedEvent.metadata &&
                    Object.keys(selectedEvent.metadata).length > 0 && (
                      <div>
                        <h4 className="text-body-sm font-medium text-muted-foreground uppercase tracking-wider mb-2">
                          Metadata
                        </h4>
                        <div className="rounded-lg border border-border bg-muted-panel divide-y divide-border-muted">
                          {Object.entries(selectedEvent.metadata).map(
                            ([key, value]) => (
                              <div
                                key={key}
                                className="flex items-start gap-3 px-3 py-2 group"
                              >
                                <span className="text-body-sm font-mono font-medium text-foreground shrink-0 min-w-[100px]">
                                  {key}
                                </span>
                                <span className="text-body-sm font-mono text-muted-foreground break-all flex-1">
                                  {typeof value === "object"
                                    ? JSON.stringify(value, null, 2)
                                    : String(value ?? "")}
                                </span>
                                <button
                                  onClick={() => {
                                    navigator.clipboard.writeText(
                                      typeof value === "object"
                                        ? JSON.stringify(value)
                                        : String(value ?? ""),
                                    );
                                    toast.success("Copied");
                                  }}
                                  className="opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-foreground shrink-0"
                                >
                                  <Copy className="h-3 w-3" />
                                </button>
                              </div>
                            ),
                          )}
                        </div>
                      </div>
                    )}
                </div>
              </div>
              <div className="border-t border-border px-6 py-3 flex justify-end gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => {
                    navigator.clipboard.writeText(
                      JSON.stringify(selectedEvent, null, 2),
                    );
                    toast.success("Copied event JSON");
                  }}
                  className="h-8 text-body-sm"
                >
                  <Copy className="h-3 w-3" /> Copy JSON
                </Button>
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => setSelectedEvent(null)}
                  className="h-8 text-body-sm"
                >
                  Close
                </Button>
              </div>
            </>
          )}
        </DialogContent>
      </Dialog>
    </div>
  );
}
