// =============================================================================
// HeadlineSift.com — Fetch Log Table
// =============================================================================
"use client";

import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useTransition, useState } from "react";
import Link from "next/link";
import { cn } from "@/lib/utils";

// ============================================================================
// Types
// ============================================================================

export interface FetchLogRow {
  id: string;
  sourceId: string;
  sourceName: string;
  startedAt: Date;
  endedAt: Date | null;
  status: string;
  articlesFound: number;
  articlesSaved: number;
  duplicatesFound: number;
  errorMessage: string | null;
  createdAt: Date;
}

interface SourceOption {
  id: string;
  name: string;
}

interface FetchLogTableProps {
  logs: FetchLogRow[];
  sourceFilter: string | null;
  statusFilter: string | null;
  startDateFilter: string | null;
  endDateFilter: string | null;
  page: number;
  totalPages: number;
  totalCount: number;
  sourceOptions: SourceOption[];
}

// ============================================================================
// Sub-components
// ============================================================================

function StatusBadge({ status }: { status: string }) {
  switch (status) {
    case "SUCCESS":
      return (
        <span className="inline-flex items-center rounded-full bg-green-50 px-2 py-0.5 text-2xs font-semibold uppercase tracking-wider text-green-700">
          Success
        </span>
      );
    case "PARTIAL":
      return (
        <span className="inline-flex items-center rounded-full bg-amber-50 px-2 py-0.5 text-2xs font-semibold uppercase tracking-wider text-amber-700">
          Partial
        </span>
      );
    case "FAILED":
      return (
        <span className="inline-flex items-center rounded-full bg-red-50 px-2 py-0.5 text-2xs font-semibold uppercase tracking-wider text-red-700">
          Failed
        </span>
      );
    case "STARTED":
      return (
        <span className="inline-flex items-center gap-1 rounded-full bg-blue-50 px-2 py-0.5 text-2xs font-semibold uppercase tracking-wider text-blue-700">
          <span className="inline-block h-1.5 w-1.5 rounded-full bg-blue-500 animate-pulse" />
          Started
        </span>
      );
    default:
      return (
        <span className="inline-flex items-center rounded-full bg-slate-100 px-2 py-0.5 text-2xs font-semibold uppercase tracking-wider text-slate-600">
          {status}
        </span>
      );
  }
}

function RelativeTime({ date }: { date: Date | null }) {
  if (!date) return <span className="text-body-muted/50">—</span>;

  const now = Date.now();
  const diffMs = now - date.getTime();
  const diffSec = Math.floor(diffMs / 1000);
  const diffMin = Math.floor(diffSec / 60);
  const diffHr = Math.floor(diffMin / 60);
  const diffDay = Math.floor(diffHr / 24);

  let text: string;
  if (diffSec < 60) text = "just now";
  else if (diffMin < 60) text = `${diffMin}m ago`;
  else if (diffHr < 24) text = `${diffHr}h ago`;
  else if (diffDay < 7) text = `${diffDay}d ago`;
  else text = date.toLocaleDateString();

  return (
    <span className="text-2xs text-body-muted" title={date.toISOString()}>
      {text}
    </span>
  );
}

function Duration({
  startedAt,
  endedAt,
}: {
  startedAt: Date;
  endedAt: Date | null;
}) {
  if (!endedAt) {
    // Still running — show elapsed
    const ms = Date.now() - startedAt.getTime();
    if (ms < 60_000) return <span className="text-2xs text-blue-600">{(ms / 1000).toFixed(0)}s…</span>;
    const min = Math.floor(ms / 60_000);
    return <span className="text-2xs text-blue-600">{min}m…</span>;
  }

  const ms = endedAt.getTime() - startedAt.getTime();
  if (ms < 1000) return <span className="text-2xs text-body-muted tabular-nums">{ms}ms</span>;
  if (ms < 60_000) return <span className="text-2xs text-body-muted tabular-nums">{(ms / 1000).toFixed(1)}s</span>;
  const min = Math.floor(ms / 60_000);
  const sec = Math.floor((ms % 60_000) / 1000);
  return <span className="text-2xs text-body-muted tabular-nums">{min}m {sec}s</span>;
}

function EmptyState({ hasFilters }: { hasFilters: boolean }) {
  return (
    <div className="flex flex-col items-center justify-center py-16 text-center">
      <span className="text-5xl" aria-hidden="true">
        {hasFilters ? "🔍" : "📋"}
      </span>
      <h3 className="mt-4 text-lg font-semibold text-heading">
        {hasFilters ? "No fetch logs match your filters" : "No fetch logs yet"}
      </h3>
      <p className="mt-2 max-w-md text-sm text-body-muted">
        {hasFilters
          ? "Try adjusting your filters or date range."
          : "Fetch logs are created automatically when sources are fetched. Use \"npm run fetch:all\" or click \"Fetch\" on a source to create your first log."}
      </p>
    </div>
  );
}

// ============================================================================
// Table Component
// ============================================================================

export default function FetchLogTable({
  logs,
  sourceFilter,
  statusFilter,
  startDateFilter,
  endDateFilter,
  page,
  totalPages,
  totalCount,
  sourceOptions,
}: FetchLogTableProps) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [isPending, startTransition] = useTransition();
  const [expandedId, setExpandedId] = useState<string | null>(null);

  const navigate = useCallback(
    (overrides: Record<string, string | null>) => {
      const params = new URLSearchParams(searchParams.toString());
      for (const [key, value] of Object.entries(overrides)) {
        if (value === null) {
          params.delete(key);
        } else {
          params.set(key, value);
        }
      }
      startTransition(() => {
        router.push(`/admin/fetch-logs?${params.toString()}`);
      });
    },
    [router, searchParams, startTransition],
  );

  const toggleExpand = useCallback((id: string) => {
    setExpandedId((prev) => (prev === id ? null : id));
  }, []);

  const hasFilters =
    sourceFilter !== null ||
    statusFilter !== null ||
    startDateFilter !== null ||
    endDateFilter !== null;

  return (
    <div className="space-y-4">
      {/* ── Filter Toolbar ── */}
      <div className="flex flex-wrap items-end gap-3">
        {/* Source Filter */}
        <div>
          <label className="block text-2xs font-medium text-body-muted mb-1">
            Source
          </label>
          <select
            value={sourceFilter ?? ""}
            onChange={(e) =>
              navigate({ source: e.target.value || null, page: null })
            }
            className="input text-xs"
            style={{ maxWidth: "14rem" }}
          >
            <option value="">All sources</option>
            {sourceOptions.map((s) => (
              <option key={s.id} value={s.id}>
                {s.name}
              </option>
            ))}
          </select>
        </div>

        {/* Status Filter */}
        <div>
          <label className="block text-2xs font-medium text-body-muted mb-1">
            Status
          </label>
          <select
            value={statusFilter ?? ""}
            onChange={(e) =>
              navigate({ status: e.target.value || null, page: null })
            }
            className="input text-xs"
            style={{ maxWidth: "8rem" }}
          >
            <option value="">All statuses</option>
            <option value="SUCCESS">Success</option>
            <option value="PARTIAL">Partial</option>
            <option value="FAILED">Failed</option>
            <option value="STARTED">Started</option>
          </select>
        </div>

        {/* Date Range */}
        <div>
          <label className="block text-2xs font-medium text-body-muted mb-1">
            From
          </label>
          <input
            type="date"
            value={startDateFilter ?? ""}
            onChange={(e) =>
              navigate({ startDate: e.target.value || null, page: null })
            }
            className="input text-xs"
            style={{ maxWidth: "10rem" }}
          />
        </div>
        <div>
          <label className="block text-2xs font-medium text-body-muted mb-1">
            To
          </label>
          <input
            type="date"
            value={endDateFilter ?? ""}
            onChange={(e) =>
              navigate({ endDate: e.target.value || null, page: null })
            }
            className="input text-xs"
            style={{ maxWidth: "10rem" }}
          />
        </div>

        {/* Result count */}
        {hasFilters && (
          <span className="text-2xs text-body-muted self-end pb-1.5">
            {totalCount} result{totalCount !== 1 ? "s" : ""}
          </span>
        )}
      </div>

      {/* ── Table or Empty State ── */}
      {logs.length === 0 ? (
        <div className="card">
          <EmptyState hasFilters={hasFilters} />
        </div>
      ) : (
        <div className="card overflow-x-auto p-0">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-border bg-surface-secondary text-left">
                <th className="px-4 py-3 text-xs font-semibold uppercase tracking-wide text-body-muted">
                  Source
                </th>
                <th className="px-4 py-3 text-xs font-semibold uppercase tracking-wide text-body-muted hidden sm:table-cell">
                  Started
                </th>
                <th className="px-4 py-3 text-xs font-semibold uppercase tracking-wide text-body-muted hidden md:table-cell w-16">
                  Time
                </th>
                <th className="px-4 py-3 text-xs font-semibold uppercase tracking-wide text-body-muted">
                  Status
                </th>
                <th className="px-4 py-3 text-xs font-semibold uppercase tracking-wide text-body-muted hidden lg:table-cell w-12">
                  Found
                </th>
                <th className="px-4 py-3 text-xs font-semibold uppercase tracking-wide text-body-muted hidden lg:table-cell w-12">
                  New
                </th>
                <th className="px-4 py-3 text-xs font-semibold uppercase tracking-wide text-body-muted hidden lg:table-cell w-12">
                  Dupes
                </th>
                <th className="px-4 py-3 text-xs font-semibold uppercase tracking-wide text-body-muted hidden xl:table-cell max-w-[250px]">
                  Error
                </th>
              </tr>
            </thead>
            <tbody className="divide-y divide-border">
              {logs.map((log) => {
                const isExpanded = expandedId === log.id;
                return (
                  <tr
                    key={log.id}
                    className={cn(
                      "transition-colors hover:bg-surface-secondary",
                      log.status === "FAILED" && "bg-red-50/30",
                    )}
                  >
                    {/* Source */}
                    <td className="px-4 py-3">
                      <Link
                        href={`/admin/sources?edit=${log.sourceId}`}
                        className="font-medium text-brand-600 hover:text-brand-700 hover:underline"
                      >
                        {log.sourceName}
                      </Link>
                    </td>

                    {/* Started */}
                    <td className="px-4 py-3 hidden sm:table-cell">
                      <RelativeTime date={log.startedAt} />
                    </td>

                    {/* Duration */}
                    <td className="px-4 py-3 hidden md:table-cell">
                      <Duration
                        startedAt={log.startedAt}
                        endedAt={log.endedAt}
                      />
                    </td>

                    {/* Status */}
                    <td className="px-4 py-3">
                      <StatusBadge status={log.status} />
                    </td>

                    {/* Articles Found */}
                    <td className="px-4 py-3 hidden lg:table-cell tabular-nums text-body-muted text-xs">
                      {log.articlesFound}
                    </td>

                    {/* Articles Saved */}
                    <td className="px-4 py-3 hidden lg:table-cell tabular-nums text-xs">
                      <span
                        className={cn(
                          log.articlesSaved > 0
                            ? "font-semibold text-green-700"
                            : "text-body-muted",
                        )}
                      >
                        {log.articlesSaved}
                      </span>
                    </td>

                    {/* Duplicates Found */}
                    <td className="px-4 py-3 hidden lg:table-cell tabular-nums text-xs">
                      <span
                        className={
                          log.duplicatesFound > 0
                            ? "text-amber-600"
                            : "text-body-muted"
                        }
                      >
                        {log.duplicatesFound}
                      </span>
                    </td>

                    {/* Error Message */}
                    <td className="px-4 py-3 hidden xl:table-cell max-w-[250px]">
                      {log.errorMessage ? (
                        <button
                          type="button"
                          onClick={() => toggleExpand(log.id)}
                          className="block max-w-full text-left"
                        >
                          <span
                            className={cn(
                              "block truncate text-2xs",
                              log.status === "FAILED"
                                ? "text-red-600 font-medium"
                                : "text-amber-600",
                            )}
                            title={
                              isExpanded ? undefined : log.errorMessage
                            }
                          >
                            {isExpanded
                              ? log.errorMessage
                              : log.errorMessage.slice(0, 80) +
                                (log.errorMessage.length > 80 ? "…" : "")}
                          </span>
                          {!isExpanded &&
                            log.errorMessage.length > 80 && (
                              <span className="text-2xs text-brand-600 mt-0.5">
                                Click to expand
                              </span>
                            )}
                        </button>
                      ) : (
                        <span className="text-body-muted/50">—</span>
                      )}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>

          {/* Footer: count + pagination */}
          <div className="flex items-center justify-between border-t border-border px-4 py-3">
            <span className="text-xs text-body-muted">
              {totalCount} {totalCount === 1 ? "log" : "logs"}
            </span>

            {totalPages > 1 && (
              <div className="flex items-center gap-2">
                <button
                  type="button"
                  disabled={page <= 1}
                  onClick={() => navigate({ page: String(page - 1) })}
                  className="rounded px-2 py-1 text-xs text-brand-600 hover:bg-brand-50 disabled:text-body-muted/30 disabled:cursor-not-allowed transition-colors"
                >
                  Previous
                </button>
                <span className="text-xs text-body-muted">
                  {page} / {totalPages}
                </span>
                <button
                  type="button"
                  disabled={page >= totalPages}
                  onClick={() => navigate({ page: String(page + 1) })}
                  className="rounded px-2 py-1 text-xs text-brand-600 hover:bg-brand-50 disabled:text-body-muted/30 disabled:cursor-not-allowed transition-colors"
                >
                  Next
                </button>
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}
