"use client";

import React, { useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { apiFetch } from "@/lib/api";
import {
  formatTime,
  translateStatus,
  useCancelCitySweep,
  type ScraperSource,
} from "@/app/scrapers/_components/ScraperPage";

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

export interface ScrapeRunFull {
  run_id: number;
  source: string;
  run_type: string | null;
  status: string;
  params: Record<string, unknown> | null;
  counters: Record<string, number | string | null> | null;
  total_seen: number | null;
  new_count: number | null;
  started_at: string | null;
  finished_at: string | null;
  heartbeat_at: string | null;
  error_text: string | null;
}

interface RunsListResp {
  total: number;
  rows: ScrapeRunFull[];
}

// ── Hook ───────────────────────────────────────────────────────────────────

const RUN_STATUS_ALL = ["", "running", "done", "failed", "cancelled", "zombie", "banned"] as const;
type RunStatusFilter = (typeof RUN_STATUS_ALL)[number];

function useScraperRuns(
  source: ScraperSource,
  status: RunStatusFilter,
  limit = 20,
) {
  return useQuery<RunsListResp>({
    queryKey: ["scrape-runs", source, status, limit],
    queryFn: () => {
      const qs = new URLSearchParams({ source, limit: String(limit) });
      if (status) qs.set("status", status);
      return apiFetch<RunsListResp>(
        `/api/v1/admin/scrape/runs?${qs.toString()}`,
      );
    },
    refetchInterval: 8_000,
    staleTime: 0,
    retry: 1,
  });
}

// ── Status badge ───────────────────────────────────────────────────────────

function RunStatusBadge({ status }: { status: string }) {
  let variant: "running" | "done" | "danger" | "neutral";
  switch (status) {
    case "running":
      variant = "running";
      break;
    case "done":
      variant = "done";
      break;
    case "failed":
    case "banned":
    case "zombie":
      variant = "danger";
      break;
    default:
      variant = "neutral";
  }

  const styles: Record<typeof variant, React.CSSProperties> = {
    running: {
      background: "var(--accent-soft, #dbeafe)",
      color: "var(--accent, #1d4ed8)",
    },
    done: {
      background: "var(--success-soft, #dcfce7)",
      color: "var(--success, #0a7a3a)",
    },
    danger: {
      background: "var(--danger-soft, #fee2e2)",
      color: "var(--danger, #b3261e)",
    },
    neutral: {
      background: "var(--bg-card-alt, #fafbfc)",
      color: "var(--fg-secondary, #5b6066)",
    },
  };

  return (
    <span
      style={{
        display: "inline-block",
        padding: "2px 8px",
        borderRadius: 6,
        fontSize: "0.8rem",
        fontWeight: 600,
        ...styles[variant],
      }}
    >
      {translateStatus(status)}
    </span>
  );
}

// ── Counters cell ──────────────────────────────────────────────────────────

function CountersCell({
  row,
}: {
  row: ScrapeRunFull;
}) {
  const c = row.counters;
  if (!c) return <span style={{ color: "var(--fg-tertiary, #73767e)" }}>—</span>;

  const parts: string[] = [];
  const lots =
    c.lots_fetched != null ? `${c.lots_fetched} лотов` : null;
  const newC =
    row.new_count != null
      ? `+${row.new_count} new`
      : c.lots_inserted != null
        ? `+${c.lots_inserted} new`
        : null;
  const errs =
    c.errors_count != null && Number(c.errors_count) > 0
      ? `${c.errors_count} err`
      : null;

  if (lots) parts.push(lots);
  if (newC) parts.push(newC);
  if (errs) parts.push(errs);

  return (
    <span style={{ fontSize: "0.8rem" }}>
      {parts.length > 0 ? parts.join(" · ") : "—"}
    </span>
  );
}

// ── RunsTable ──────────────────────────────────────────────────────────────

interface RunsTableProps {
  source: ScraperSource;
}

export function RunsTable({ source }: RunsTableProps) {
  const [statusFilter, setStatusFilter] =
    useState<RunStatusFilter>("");
  const qc = useQueryClient();
  const runsQ = useScraperRuns(source, statusFilter);
  const cancelMut = useCancelCitySweep(source);

  function handleCancel(runId: number) {
    cancelMut.mutate(runId, {
      onSuccess: () => {
        void qc.invalidateQueries({
          queryKey: ["scrape-runs", source, statusFilter],
        });
      },
    });
  }

  return (
    <section className="scraper-section">
      <h2>История прогонов</h2>
      <p className="scraper-hint">
        Последние 20 прогонов. Автообновление каждые 8 сек.
      </p>

      {/* Status filter */}
      <div style={{ marginBottom: 12, display: "flex", gap: 8, flexWrap: "wrap" }}>
        {RUN_STATUS_ALL.map((s) => (
          <button
            key={s || "all"}
            type="button"
            onClick={() => setStatusFilter(s)}
            style={{
              padding: "3px 10px",
              borderRadius: 6,
              border: "1px solid",
              fontSize: "0.8rem",
              cursor: "pointer",
              background:
                statusFilter === s
                  ? "var(--accent, #1d4ed8)"
                  : "var(--bg-card, #fff)",
              color:
                statusFilter === s
                  ? "#fff"
                  : "var(--fg-secondary, #5b6066)",
              borderColor:
                statusFilter === s
                  ? "var(--accent, #1d4ed8)"
                  : "var(--border-card, #e6e8ec)",
            }}
          >
            {s === "" ? "Все" : translateStatus(s)}
          </button>
        ))}
      </div>

      {runsQ.isPending && <p className="scraper-hint">Загрузка…</p>}
      {runsQ.isError && (
        <p className="scraper-result scraper-result--error">
          Ошибка загрузки: {runsQ.error.message}
          {" — "}
          <span style={{ color: "var(--fg-secondary, #5b6066)" }}>
            API /scrape/runs ещё не задеплоен
          </span>
        </p>
      )}

      {runsQ.data && runsQ.data.rows.length === 0 && (
        <p className="scraper-hint">Прогонов не найдено.</p>
      )}

      {runsQ.data && runsQ.data.rows.length > 0 && (
        <>
          <p
            style={{
              fontSize: "0.8rem",
              color: "var(--fg-tertiary, #73767e)",
              marginBottom: 8,
            }}
          >
            Итого: {runsQ.data.total}
          </p>
          <table className="runs-table">
            <thead>
              <tr>
                <th>#</th>
                <th>Тип</th>
                <th>Статус</th>
                <th>Старт</th>
                <th>Финиш</th>
                <th>Лоты / Ошибки</th>
                <th>Действие</th>
              </tr>
            </thead>
            <tbody>
              {runsQ.data.rows.map((r) => (
                <tr
                  key={r.run_id}
                  className={`run-row run-row--${r.status}`}
                >
                  <td>{r.run_id}</td>
                  <td>
                    <span
                      style={{
                        fontSize: "0.8rem",
                        color: "var(--fg-secondary, #5b6066)",
                      }}
                    >
                      {r.run_type ?? "sweep"}
                    </span>
                  </td>
                  <td>
                    <RunStatusBadge status={r.status} />
                  </td>
                  <td
                    style={{
                      fontSize: "0.8rem",
                      whiteSpace: "nowrap",
                    }}
                  >
                    {formatTime(r.started_at)}
                  </td>
                  <td
                    style={{
                      fontSize: "0.8rem",
                      whiteSpace: "nowrap",
                    }}
                  >
                    {formatTime(r.finished_at)}
                  </td>
                  <td>
                    <CountersCell row={r} />
                    {r.error_text && (
                      <div
                        style={{
                          fontSize: "0.75rem",
                          color: "var(--danger, #b3261e)",
                          marginTop: 2,
                          maxWidth: 240,
                          overflow: "hidden",
                          textOverflow: "ellipsis",
                          whiteSpace: "nowrap",
                        }}
                        title={r.error_text}
                      >
                        {r.error_text}
                      </div>
                    )}
                  </td>
                  <td>
                    {r.status === "running" && (
                      <button
                        type="button"
                        className="cancel-btn"
                        disabled={
                          cancelMut.isPending &&
                          cancelMut.variables === r.run_id
                        }
                        onClick={() => handleCancel(r.run_id)}
                        style={{ fontSize: "0.8rem", padding: "3px 10px" }}
                      >
                        Отменить
                      </button>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </>
      )}
    </section>
  );
}
