import { useQuery } from "@tanstack/react-query";
import { apiRequest } from "@/lib/queryClient";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Activity,
  AlertTriangle,
  CheckCircle2,
  Clock,
  RefreshCw,
  ServerCrash,
  SkipForward,
  Wifi,
  WifiOff,
} from "lucide-react";
import { formatDistanceToNow, format } from "date-fns";

// ─── Types ────────────────────────────────────────────────────────────────────

interface CronJobLog {
  id: number;
  jobName: string;
  status: string;
  startedAt: string;
  completedAt: string | null;
  durationMs: number | null;
  errorMessage: string | null;
}

interface CronSummary {
  lastRuns: CronJobLog[];
  recentLogs: CronJobLog[];
}

interface SeleniumStatus {
  online: boolean;
  active_jobs: number;
  queued_jobs: number;
  status: string;
}

// ─── Helpers ──────────────────────────────────────────────────────────────────

const JOB_LABELS: Record<string, string> = {
  "local-backup": "Local Backup (8 PM)",
  "usb-backup": "USB Backup (9 PM)",
};

function jobLabel(name: string) {
  return JOB_LABELS[name] ?? name;
}

function StatusBadge({ status }: { status: string }) {
  if (status === "success")
    return (
      <Badge className="bg-green-100 text-green-700 border-green-200 gap-1">
        <CheckCircle2 className="h-3 w-3" /> Success
      </Badge>
    );
  if (status === "failed")
    return (
      <Badge className="bg-red-100 text-red-700 border-red-200 gap-1">
        <ServerCrash className="h-3 w-3" /> Failed
      </Badge>
    );
  if (status === "skipped")
    return (
      <Badge className="bg-gray-100 text-gray-600 border-gray-200 gap-1">
        <SkipForward className="h-3 w-3" /> Skipped
      </Badge>
    );
  return (
    <Badge className="bg-blue-100 text-blue-700 border-blue-200 gap-1">
      <Activity className="h-3 w-3 animate-pulse" /> Running
    </Badge>
  );
}

function formatDuration(ms: number | null) {
  if (ms === null) return "—";
  if (ms < 1000) return `${ms}ms`;
  return `${(ms / 1000).toFixed(1)}s`;
}

function formatDate(iso: string | null) {
  if (!iso) return "—";
  return format(new Date(iso), "MMM d, yyyy HH:mm:ss");
}

function timeAgo(iso: string | null) {
  if (!iso) return "—";
  return formatDistanceToNow(new Date(iso), { addSuffix: true });
}

// ─── Page ─────────────────────────────────────────────────────────────────────

export default function JobMonitorPage() {
  const {
    data: summary,
    isLoading: loadingSummary,
    refetch: refetchSummary,
    dataUpdatedAt: summaryUpdated,
  } = useQuery<CronSummary>({
    queryKey: ["/job-monitor/summary"],
    queryFn: async () => {
      const res = await apiRequest("GET", "/api/job-monitor/summary");
      return res.json();
    },
    refetchInterval: 30_000,
  });

  const {
    data: failed,
    isLoading: loadingFailed,
    refetch: refetchFailed,
  } = useQuery<CronJobLog[]>({
    queryKey: ["/job-monitor/failed"],
    queryFn: async () => {
      const res = await apiRequest("GET", "/api/job-monitor/failed");
      return res.json();
    },
    refetchInterval: 30_000,
  });

  const {
    data: seleniumStatus,
    isLoading: loadingSelenium,
    refetch: refetchSelenium,
  } = useQuery<SeleniumStatus>({
    queryKey: ["/job-monitor/selenium-status"],
    queryFn: async () => {
      const res = await apiRequest("GET", "/api/job-monitor/selenium-status");
      return res.json();
    },
    refetchInterval: 10_000,
  });

  function refreshAll() {
    refetchSummary();
    refetchFailed();
    refetchSelenium();
  }

  const lastUpdated = summaryUpdated
    ? format(new Date(summaryUpdated), "HH:mm:ss")
    : null;

  return (
    <div className="p-6 max-w-5xl mx-auto space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-semibold text-gray-900">Job Monitor</h1>
          <p className="text-sm text-gray-500 mt-0.5">
            Background job health and queue status
            {lastUpdated && (
              <span className="ml-2 text-gray-400">· last updated {lastUpdated}</span>
            )}
          </p>
        </div>
        <Button
          variant="outline"
          size="sm"
          onClick={refreshAll}
          className="gap-1.5"
        >
          <RefreshCw className="h-4 w-4" />
          Refresh
        </Button>
      </div>

      {/* ── Cron Jobs ── */}
      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-base flex items-center gap-2">
            <Clock className="h-4 w-4 text-gray-500" />
            Scheduled Cron Jobs
          </CardTitle>
        </CardHeader>
        <CardContent>
          {loadingSummary ? (
            <p className="text-sm text-gray-400">Loading…</p>
          ) : !summary?.lastRuns.length ? (
            <p className="text-sm text-gray-500">
              No job runs recorded yet. Jobs are scheduled at 8 PM (local backup) and 9 PM (USB backup).
            </p>
          ) : (
            <div className="space-y-3">
              {summary.lastRuns.map((log) => (
                <div
                  key={log.id}
                  className="flex items-start justify-between rounded-lg border border-gray-100 bg-gray-50 px-4 py-3"
                >
                  <div className="space-y-0.5">
                    <p className="text-sm font-medium text-gray-800">
                      {jobLabel(log.jobName)}
                    </p>
                    <p className="text-xs text-gray-500">
                      Last run: {formatDate(log.startedAt)}{" "}
                      <span className="text-gray-400">({timeAgo(log.startedAt)})</span>
                    </p>
                    {log.status === "failed" && log.errorMessage && (
                      <p className="text-xs text-red-600 mt-1 flex items-center gap-1">
                        <AlertTriangle className="h-3 w-3 shrink-0" />
                        {log.errorMessage}
                      </p>
                    )}
                  </div>
                  <div className="flex flex-col items-end gap-1">
                    <StatusBadge status={log.status} />
                    <span className="text-xs text-gray-400">
                      {formatDuration(log.durationMs)}
                    </span>
                  </div>
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      {/* ── Selenium Queue ── */}
      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-base flex items-center gap-2">
            {seleniumStatus?.online ? (
              <Wifi className="h-4 w-4 text-green-500" />
            ) : (
              <WifiOff className="h-4 w-4 text-gray-400" />
            )}
            Selenium Job Queue
          </CardTitle>
        </CardHeader>
        <CardContent>
          {loadingSelenium ? (
            <p className="text-sm text-gray-400">Loading…</p>
          ) : (
            <div className="grid grid-cols-3 gap-4">
              {/* Online status */}
              <div className="rounded-lg border border-gray-100 bg-gray-50 px-4 py-3 text-center">
                <p className="text-xs text-gray-500 mb-1">Service</p>
                {seleniumStatus?.online ? (
                  <span className="inline-flex items-center gap-1 text-sm font-medium text-green-700">
                    <CheckCircle2 className="h-4 w-4" /> Online
                  </span>
                ) : (
                  <span className="inline-flex items-center gap-1 text-sm font-medium text-gray-500">
                    <WifiOff className="h-4 w-4" /> Offline
                  </span>
                )}
              </div>

              {/* Active jobs */}
              <div className="rounded-lg border border-gray-100 bg-gray-50 px-4 py-3 text-center">
                <p className="text-xs text-gray-500 mb-1">Active Jobs</p>
                <p
                  className={`text-2xl font-bold ${
                    (seleniumStatus?.active_jobs ?? 0) > 0
                      ? "text-blue-600"
                      : "text-gray-700"
                  }`}
                >
                  {seleniumStatus?.active_jobs ?? 0}
                </p>
              </div>

              {/* Queued jobs */}
              <div className="rounded-lg border border-gray-100 bg-gray-50 px-4 py-3 text-center">
                <p className="text-xs text-gray-500 mb-1">Queued</p>
                <p
                  className={`text-2xl font-bold ${
                    (seleniumStatus?.queued_jobs ?? 0) > 0
                      ? "text-amber-600"
                      : "text-gray-700"
                  }`}
                >
                  {seleniumStatus?.queued_jobs ?? 0}
                </p>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {/* ── Failed Alerts ── */}
      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-base flex items-center gap-2">
            <AlertTriangle className="h-4 w-4 text-red-500" />
            Failed Job Alerts
            {!loadingFailed && failed && failed.length > 0 && (
              <Badge className="bg-red-100 text-red-700 border-red-200 ml-1">
                {failed.length}
              </Badge>
            )}
          </CardTitle>
        </CardHeader>
        <CardContent>
          {loadingFailed ? (
            <p className="text-sm text-gray-400">Loading…</p>
          ) : !failed?.length ? (
            <div className="flex items-center gap-2 text-sm text-green-700">
              <CheckCircle2 className="h-4 w-4" />
              No failed jobs — everything looks healthy.
            </div>
          ) : (
            <div className="space-y-2">
              {failed.map((log) => (
                <div
                  key={log.id}
                  className="rounded-lg border border-red-100 bg-red-50 px-4 py-3"
                >
                  <div className="flex items-center justify-between mb-1">
                    <span className="text-sm font-medium text-red-800">
                      {jobLabel(log.jobName)}
                    </span>
                    <span className="text-xs text-gray-500">
                      {formatDate(log.startedAt)}
                    </span>
                  </div>
                  {log.errorMessage && (
                    <p className="text-xs text-red-600">{log.errorMessage}</p>
                  )}
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      {/* ── Recent History ── */}
      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-base flex items-center gap-2">
            <Activity className="h-4 w-4 text-gray-500" />
            Recent Run History
          </CardTitle>
        </CardHeader>
        <CardContent>
          {loadingSummary ? (
            <p className="text-sm text-gray-400">Loading…</p>
          ) : !summary?.recentLogs.length ? (
            <p className="text-sm text-gray-500">No history yet.</p>
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b text-xs text-gray-500 uppercase tracking-wide">
                    <th className="text-left py-2 pr-4 font-medium">Job</th>
                    <th className="text-left py-2 pr-4 font-medium">Started</th>
                    <th className="text-left py-2 pr-4 font-medium">Duration</th>
                    <th className="text-left py-2 font-medium">Status</th>
                  </tr>
                </thead>
                <tbody>
                  {summary.recentLogs.map((log) => (
                    <tr
                      key={log.id}
                      className="border-b border-gray-50 last:border-0 hover:bg-gray-50 transition-colors"
                    >
                      <td className="py-2 pr-4 font-medium text-gray-700">
                        {jobLabel(log.jobName)}
                      </td>
                      <td className="py-2 pr-4 text-gray-500">
                        {formatDate(log.startedAt)}
                      </td>
                      <td className="py-2 pr-4 text-gray-500">
                        {formatDuration(log.durationMs)}
                      </td>
                      <td className="py-2">
                        <StatusBadge status={log.status} />
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
