import { useEffect, useState } from "react";
import { api } from "../api.js";

interface JobCounts {
  wait: number;
  active: number;
  delayed: number;
  completed: number;
  failed: number;
  paused?: number;
}

interface WorkerInfo {
  id: string;
  addr: string;
  concurrency: number;
  lastSeenAt: number;
}

interface SchedulerInfo {
  id: string;
  pattern?: string;
  every?: number;
}

interface HealthResponse {
  ok: boolean;
  queues: {
    jobs: JobCounts;
    deadLetter: JobCounts;
  };
  workers: WorkerInfo[];
  schedulers: SchedulerInfo[];
}

interface DlqJob {
  id: string;
  name: string;
  data: unknown;
  failedReason?: string;
  attemptsMade: number;
  timestamp: number;
}

export function WorkersPage() {
  const [health, setHealth] = useState<HealthResponse | null>(null);
  const [dlq, setDlq] = useState<DlqJob[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [actionId, setActionId] = useState<string | null>(null);

  const load = async () => {
    setLoading(true);
    try {
      const [h, d] = await Promise.all([
        api<HealthResponse>("/admin/v1/workers/health"),
        api<{ jobs: DlqJob[] }>("/admin/v1/workers/dead-letter?limit=50"),
      ]);
      setHealth(h);
      setDlq(d.jobs);
      setError(null);
    } catch (e) {
      setError(String((e as Error).message));
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    load();
    const t = setInterval(load, 10_000);
    return () => clearInterval(t);
  }, []);

  const retry = async (id: string) => {
    setActionId(id);
    try {
      await api(`/admin/v1/workers/dead-letter/${id}/retry`, { method: "POST" });
      await load();
    } catch (e) {
      setError(String((e as Error).message));
    } finally {
      setActionId(null);
    }
  };

  const discard = async (id: string) => {
    if (!confirm("Ta bort jobbet permanent?")) return;
    setActionId(id);
    try {
      await api(`/admin/v1/workers/dead-letter/${id}/discard`, { method: "POST" });
      await load();
    } catch (e) {
      setError(String((e as Error).message));
    } finally {
      setActionId(null);
    }
  };

  return (
    <div className="page">
      <h2>Workers & köer</h2>
      {error && <div className="alert err">{error}</div>}
      {loading && !health && <div>Laddar …</div>}

      {health && (
        <>
          <section className="card">
            <h3>Jobbkö</h3>
            <div className="metrics">
              <Metric label="Väntar" value={health.queues.jobs.wait} />
              <Metric label="Aktiva" value={health.queues.jobs.active} />
              <Metric label="Fördröjda" value={health.queues.jobs.delayed} />
              <Metric label="Misslyckade" value={health.queues.jobs.failed} />
              <Metric label="Klara" value={health.queues.jobs.completed} />
            </div>
          </section>

          <section className="card">
            <h3>Dead letter ({health.queues.deadLetter.wait + health.queues.deadLetter.failed})</h3>
            {dlq.length === 0 ? (
              <p>Inga jobb i dead letter.</p>
            ) : (
              <table>
                <thead>
                  <tr>
                    <th>Jobb</th>
                    <th>Fel</th>
                    <th>Försök</th>
                    <th>Tid</th>
                    <th>Åtgärder</th>
                  </tr>
                </thead>
                <tbody>
                  {dlq.map((job) => (
                    <tr key={job.id}>
                      <td>{job.name}</td>
                      <td className="ellipsis" title={job.failedReason}>
                        {job.failedReason ?? "–"}
                      </td>
                      <td>{job.attemptsMade}</td>
                      <td>{new Date(job.timestamp).toLocaleString("sv-SE")}</td>
                      <td>
                        <button
                          onClick={() => retry(job.id)}
                          disabled={actionId === job.id}
                          className="btn small"
                        >
                          Kör igen
                        </button>{" "}
                        <button
                          onClick={() => discard(job.id)}
                          disabled={actionId === job.id}
                          className="btn small danger"
                        >
                          Kasta
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </section>

          <section className="card">
            <h3>Aktiva worker-instanser</h3>
            {health.workers.length === 0 ? (
              <p className="err">Inga aktiva workers!</p>
            ) : (
              <ul>
                {health.workers.map((w) => (
                  <li key={w.id}>
                    {w.id} @ {w.addr} (concurrency {w.concurrency})
                  </li>
                ))}
              </ul>
            )}
          </section>

          <section className="card">
            <h3>Scheduler</h3>
            <ul>
              {health.schedulers.map((s) => (
                <li key={s.id}>
                  {s.id}: {s.pattern ?? `every ${s.every}ms`}
                </li>
              ))}
            </ul>
          </section>
        </>
      )}
    </div>
  );
}

function Metric({ label, value }: { label: string; value: number }) {
  return (
    <div className="metric">
      <div className="value">{value}</div>
      <div className="label">{label}</div>
    </div>
  );
}
