"use client";

import { useState } from "react";
import { useMutation } from "@tanstack/react-query";

import { apiFetch } from "@/lib/api";
import { cardStyle } from "@/lib/adminStyles";

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

interface BulkGeoJobSummary {
  thematic_id: number;
  job_ids: number[];
  targets_total: number;
  parallelism: number;
  note?: string;
}

interface BulkGeoResponse {
  jobs: BulkGeoJobSummary[];
}

interface BulkGeoRequest {
  parallelism: number;
  thematic_ids: number[];
  source: "rosreestr_pending" | "all_in_region";
  only_ddu: boolean;
}

// ── Constants ────────────────────────────────────────────────────────────────

const THEMATIC_OPTIONS = [
  { id: 1, label: "Parcels (1)" },
  { id: 2, label: "Quarters (2)" },
  { id: 5, label: "Buildings (5)" },
] as const;

// ── Component ────────────────────────────────────────────────────────────────

export function BulkGeoPanel() {
  const [parallelism, setParallelism] = useState(5);
  const [thematicIds, setThematicIds] = useState<number[]>([2]);
  const [source, setSource] = useState<"rosreestr_pending" | "all_in_region">(
    "rosreestr_pending",
  );
  const [result, setResult] = useState<BulkGeoResponse | null>(null);
  const [errorMsg, setErrorMsg] = useState<string | null>(null);

  const toggleThematic = (id: number) => {
    setThematicIds((prev) =>
      prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id],
    );
  };

  const bulkMutation = useMutation({
    mutationFn: () => {
      const body: BulkGeoRequest = {
        parallelism,
        thematic_ids: thematicIds.length > 0 ? thematicIds : [2],
        source,
        only_ddu: false,
      };
      return apiFetch<BulkGeoResponse>("/api/v1/admin/scrape/geo/bulk", {
        method: "POST",
        body: JSON.stringify(body),
      });
    },
    onSuccess: (data) => {
      setResult(data);
      setErrorMsg(null);
    },
    onError: (err: unknown) => {
      setResult(null);
      const msg = err instanceof Error ? err.message : "Неизвестная ошибка";
      setErrorMsg(msg);
    },
  });

  const parallelismValid =
    Number.isInteger(parallelism) && parallelism >= 1 && parallelism <= 10;

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!parallelismValid) return;
    bulkMutation.mutate();
  };

  const activeIds = thematicIds.length > 0 ? thematicIds : [2];

  return (
    <section style={cardStyle}>
      <h3 style={sectionTitle}>Bulk Свердловская geo backfill</h3>
      <p style={{ color: "#5b6066", fontSize: 13, marginTop: 0 }}>
        Запускает пакетное geo-обогащение участков без координат (регион 66).
        Разбивает на N параллельных job-ов через{" "}
        <code>POST /api/v1/admin/scrape/geo/bulk</code>.
      </p>

      <form
        onSubmit={handleSubmit}
        style={{ display: "flex", flexDirection: "column", gap: 14 }}
      >
        {/* Thematic checkboxes */}
        <div>
          <div style={labelStyle}>Thematic IDs</div>
          <div style={{ display: "flex", gap: 12, marginTop: 6 }}>
            {THEMATIC_OPTIONS.map(({ id, label }) => (
              <label
                key={id}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 6,
                  fontSize: 13,
                  cursor: "pointer",
                }}
              >
                <input
                  type="checkbox"
                  checked={thematicIds.includes(id)}
                  onChange={() => toggleThematic(id)}
                />
                {label}
              </label>
            ))}
          </div>
        </div>

        {/* Source radio */}
        <div>
          <div style={labelStyle}>Source</div>
          <div style={{ display: "flex", gap: 16, marginTop: 6 }}>
            {(
              [
                ["rosreestr_pending", "rosreestr_pending — только pending"],
                ["all_in_region", "all_in_region — весь регион"],
              ] as const
            ).map(([val, lbl]) => (
              <label
                key={val}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 6,
                  fontSize: 13,
                  cursor: "pointer",
                }}
              >
                <input
                  type="radio"
                  name="source"
                  value={val}
                  checked={source === val}
                  onChange={() => setSource(val)}
                />
                {lbl}
              </label>
            ))}
          </div>
        </div>

        {/* Parallelism + submit row */}
        <div
          style={{
            display: "flex",
            gap: 12,
            alignItems: "flex-end",
            flexWrap: "wrap",
          }}
        >
          <label style={{ display: "flex", flexDirection: "column", gap: 4 }}>
            <span style={labelStyle}>Parallelism (1–10)</span>
            <input
              type="number"
              value={Number.isNaN(parallelism) ? "" : parallelism}
              min={1}
              max={10}
              onChange={(e) => {
                const next = Number(e.target.value);
                setParallelism(e.target.value === "" ? NaN : next);
              }}
              style={{ ...numInput }}
            />
          </label>

          <button
            type="submit"
            disabled={bulkMutation.isPending || !parallelismValid}
            style={
              bulkMutation.isPending || !parallelismValid
                ? { ...triggerBtn, opacity: 0.6, cursor: "not-allowed" }
                : triggerBtn
            }
          >
            {bulkMutation.isPending
              ? "Запуск…"
              : `Запустить bulk-job (${activeIds.join(", ")})`}
          </button>
        </div>
      </form>

      {errorMsg && (
        <div style={errorBox}>
          <strong>Ошибка:</strong> {errorMsg}
        </div>
      )}

      {result && (
        <div style={successBox}>
          <div style={{ fontWeight: 600, marginBottom: 8 }}>
            Создано job-ов:{" "}
            {result.jobs.reduce((s, j) => s + j.job_ids.length, 0)}
          </div>
          {result.jobs.map((j) => (
            <div
              key={j.thematic_id}
              style={{
                marginBottom: 10,
                paddingBottom: 10,
                borderBottom: "1px solid #bbf7d0",
              }}
            >
              <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 4 }}>
                thematic_id={j.thematic_id}
                {j.note ? (
                  <span style={{ color: "#9ca3af", fontWeight: 400 }}>
                    {" "}
                    — {j.note}
                  </span>
                ) : null}
              </div>
              {j.targets_total > 0 && (
                <>
                  <div
                    style={{ fontSize: 13, color: "#374151", marginBottom: 4 }}
                  >
                    Targets: <strong>{j.targets_total}</strong> участков ÷{" "}
                    {j.parallelism} воркеров ={" "}
                    <strong>
                      ~{Math.ceil(j.targets_total / Math.max(j.parallelism, 1))}
                    </strong>{" "}
                    на job
                  </div>
                  <div
                    style={{
                      fontFamily: "ui-monospace,SFMono-Regular,monospace",
                      fontSize: 12,
                      color: "#5b6066",
                    }}
                  >
                    job_ids: [{j.job_ids.join(", ")}]
                  </div>
                </>
              )}
            </div>
          ))}
        </div>
      )}
    </section>
  );
}

// ── Styles ──────────────────────────────────────────────────────────────────

const sectionTitle = {
  margin: "0 0 8px",
  fontSize: 16,
  fontWeight: 600 as const,
};

const labelStyle = {
  fontSize: 12,
  color: "#5b6066",
  textTransform: "uppercase" as const,
  letterSpacing: 0.4,
};

const numInput = {
  padding: "8px 10px",
  border: "1px solid #d1d5db",
  borderRadius: 6,
  fontSize: 14,
  width: 80,
  boxSizing: "border-box" as const,
};

const triggerBtn = {
  padding: "8px 18px",
  background: "#7c3aed",
  color: "#fff",
  border: "none",
  borderRadius: 6,
  fontSize: 14,
  fontWeight: 600 as const,
  cursor: "pointer",
};

const errorBox = {
  marginTop: 16,
  padding: "12px 16px",
  background: "#fef2f2",
  border: "1px solid #fecaca",
  borderRadius: 8,
  color: "#991b1b",
  fontSize: 13,
};

const successBox = {
  marginTop: 16,
  padding: "12px 16px",
  background: "#f0fdf4",
  border: "1px solid #bbf7d0",
  borderRadius: 8,
  color: "#065f46",
};
