"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];

// "" means "all sources"; otherwise a specific source prefix (avito / cian / yandex)
const RUN_SOURCE_FILTERS = ["", "avito", "cian", "yandex"] as const;
type RunSourceFilter = (typeof RUN_SOURCE_FILTERS)[number];

const SOURCE_FILTER_LABELS: Record<RunSourceFilter, string> = {
  "": "Все",
  avito: "Avito",
  cian: "Cian",
  yandex: "Yandex",
};

function useScraperRuns(
  source: ScraperSource,
  status: RunStatusFilter,
  sourceFilter: RunSourceFilter,
  limit = 20,
) {
  return useQuery<RunsListResp>({
    queryKey: ["scrape-runs", source, status, sourceFilter, limit],
    queryFn: () => {
      const qs = new URLSearchParams({ limit: String(limit) });
      // When a specific sourceFilter is chosen, ignore the tab-level source
      // and pass it verbatim as the ?source= param
      if (sourceFilter) {
        qs.set("source", sourceFilter);
      } else {
        // fallback: filter by the current tab provider
        qs.set("source", source);
      }
      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 [sourceFilter, setSourceFilter] = useState<RunSourceFilter>("");
  const qc = useQueryClient();
  const runsQ = useScraperRuns(source, statusFilter, sourceFilter);
  const cancelMut = useCancelCitySweep(source);

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

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

      {/* Source filter */}
      <div style={{ marginBottom: 8, display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
        <label
          htmlFor="runs-source-filter"
          style={{ fontSize: "0.8rem", color: "var(--fg-secondary, #5b6066)", whiteSpace: "nowrap" }}
        >
          Источник:
        </label>
        <select
          id="runs-source-filter"
          value={sourceFilter}
          onChange={(e) => setSourceFilter(e.target.value as RunSourceFilter)}
          style={{
            fontSize: "0.8rem",
            padding: "3px 8px",
            borderRadius: 6,
            border: "1px solid var(--border-card, #e6e8ec)",
            background: "var(--bg-card, #fff)",
            color: "var(--fg-primary, #1f2937)",
            cursor: "pointer",
          }}
          aria-label="Фильтр по источнику"
        >
          {RUN_SOURCE_FILTERS.map((sf) => (
            <option key={sf || "_all"} value={sf}>
              {SOURCE_FILTER_LABELS[sf]}
            </option>
          ))}
        </select>
      </div>

      {/* 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 scope="col">#</th>
                <th scope="col">Тип</th>
                <th scope="col">Статус</th>
                <th scope="col">Старт</th>
                <th scope="col">Финиш</th>
                <th scope="col">Лоты / Ошибки</th>
                <th scope="col">Действие</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>
  );
}
