import * as React from 'react';
import { useNavigate } from 'react-router-dom';
import type { Agent, AgentStatus } from '@sentryagent/idp-sdk';
import { Badge } from '@/components/ui/badge';
import { getClient } from '@/lib/client';

const PAGE_LIMIT = 20;

/** Maps AgentStatus to a Badge variant. */
function statusVariant(status: AgentStatus): 'success' | 'warning' | 'danger' | 'muted' {
  switch (status) {
    case 'active':          return 'success';
    case 'suspended':       return 'warning';
    case 'decommissioned':  return 'danger';
  }
}

/** Formats an ISO timestamp to a short local date string. */
function formatDate(iso: string): string {
  return new Date(iso).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
}

/** Skeleton row shown while loading. */
function SkeletonRow(): React.JSX.Element {
  return (
    <tr>
      {Array.from({ length: 6 }).map((_, i) => (
        <td key={i} className="px-4 py-3">
          <div className="h-4 w-full animate-pulse rounded bg-slate-200" />
        </td>
      ))}
    </tr>
  );
}

/**
 * Agents list page — displays all registered agents with search, status filter, and pagination.
 * Clicking a row navigates to the Agent Detail page.
 */
export default function Agents(): React.JSX.Element {
  const navigate = useNavigate();

  const [agents, setAgents] = React.useState<Agent[]>([]);
  const [total, setTotal] = React.useState<number>(0);
  const [page, setPage] = React.useState<number>(1);
  const [loading, setLoading] = React.useState<boolean>(false);
  const [error, setError] = React.useState<string | null>(null);

  // Filters (client-side email search, server-side status)
  const [searchInput, setSearchInput] = React.useState<string>('');
  const [debouncedSearch, setDebouncedSearch] = React.useState<string>('');
  const [statusFilter, setStatusFilter] = React.useState<AgentStatus | ''>('');

  // Debounce search input 300ms
  React.useEffect(() => {
    const timer = setTimeout(() => { setDebouncedSearch(searchInput); }, 300);
    return () => { clearTimeout(timer); };
  }, [searchInput]);

  // Reset to page 1 on filter change
  React.useEffect(() => {
    setPage(1);
  }, [debouncedSearch, statusFilter]);

  React.useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setError(null);

    const fetchAgents = async (): Promise<void> => {
      try {
        const client = getClient();
        const result = await client.agents.listAgents({
          page,
          limit: PAGE_LIMIT,
          status: statusFilter !== '' ? statusFilter : undefined,
        });
        if (!cancelled) {
          setAgents(result.data);
          setTotal(result.total);
        }
      } catch (err) {
        if (!cancelled) {
          setError(err instanceof Error ? err.message : 'Failed to load agents.');
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    };

    void fetchAgents();
    return () => { cancelled = true; };
  }, [page, statusFilter]);

  // Client-side email filter applied after API results arrive
  const filteredAgents = React.useMemo(() => {
    if (!debouncedSearch.trim()) return agents;
    const lower = debouncedSearch.toLowerCase();
    return agents.filter((a) => a.email.toLowerCase().includes(lower));
  }, [agents, debouncedSearch]);

  const totalPages = Math.max(1, Math.ceil(total / PAGE_LIMIT));

  return (
    <div>
      <div className="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
        <h1 className="text-2xl font-bold text-slate-900">Agents</h1>
        <div className="flex gap-3">
          <input
            type="search"
            value={searchInput}
            onChange={(e) => { setSearchInput(e.target.value); }}
            placeholder="Search by email…"
            className="w-60 rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-brand-500 focus:outline-none focus:ring-1 focus:ring-brand-500"
          />
          <select
            value={statusFilter}
            onChange={(e) => { setStatusFilter(e.target.value as AgentStatus | ''); }}
            className="rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-brand-500 focus:outline-none focus:ring-1 focus:ring-brand-500"
          >
            <option value="">All Statuses</option>
            <option value="active">Active</option>
            <option value="suspended">Suspended</option>
            <option value="decommissioned">Decommissioned</option>
          </select>
        </div>
      </div>

      {error && (
        <div className="mb-4 rounded-md bg-red-50 px-4 py-3 text-sm text-red-700" role="alert">
          {error}
        </div>
      )}

      <div className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm">
        <table className="min-w-full divide-y divide-slate-200 text-sm">
          <thead className="bg-slate-50">
            <tr>
              {['Name (Email)', 'Type', 'Status', 'Environment', 'Owner', 'Created'].map((col) => (
                <th key={col} className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">
                  {col}
                </th>
              ))}
            </tr>
          </thead>
          <tbody className="divide-y divide-slate-100">
            {loading
              ? Array.from({ length: 5 }).map((_, i) => <SkeletonRow key={i} />)
              : filteredAgents.length === 0
              ? (
                <tr>
                  <td colSpan={6} className="px-4 py-12 text-center text-slate-400">
                    No agents found.
                  </td>
                </tr>
              )
              : filteredAgents.map((agent) => (
                <tr
                  key={agent.agentId}
                  onClick={() => { navigate(`/dashboard/agents/${agent.agentId}`); }}
                  className="cursor-pointer hover:bg-slate-50"
                >
                  <td className="px-4 py-3 font-medium text-brand-700">{agent.email}</td>
                  <td className="px-4 py-3 text-slate-600">{agent.agentType}</td>
                  <td className="px-4 py-3">
                    <Badge variant={statusVariant(agent.status)}>{agent.status}</Badge>
                  </td>
                  <td className="px-4 py-3 text-slate-600">{agent.deploymentEnv}</td>
                  <td className="px-4 py-3 text-slate-600">{agent.owner}</td>
                  <td className="px-4 py-3 text-slate-500">{formatDate(agent.createdAt)}</td>
                </tr>
              ))
            }
          </tbody>
        </table>
      </div>

      {/* Pagination */}
      {!loading && total > 0 && (
        <div className="mt-4 flex items-center justify-between text-sm text-slate-600">
          <span>
            Page {page} of {totalPages} ({total} total)
          </span>
          <div className="flex gap-2">
            <button
              onClick={() => { setPage((p) => Math.max(1, p - 1)); }}
              disabled={page <= 1}
              className="rounded-md border border-slate-300 px-3 py-1.5 hover:bg-slate-50 disabled:opacity-40"
            >
              Previous
            </button>
            <button
              onClick={() => { setPage((p) => Math.min(totalPages, p + 1)); }}
              disabled={page >= totalPages}
              className="rounded-md border border-slate-300 px-3 py-1.5 hover:bg-slate-50 disabled:opacity-40"
            >
              Next
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
