import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import {
  Activity,
  AlertTriangle,
  Check,
  Clock,
  Database,
  Gauge,
  Pause,
  Pencil,
  Play,
  RadioTower,
  X,
} from "lucide-react";
import { api, type SchedulerJob, type SchedulerStatus } from "../lib/api";
import { useLiveQuery } from "../lib/useLiveQuery";
import { relativeTime } from "../lib/format";
import { notify } from "../lib/notifications";
import Tooltip from "./Tooltip";

const POLL_MS = 4000;

// Seconds until an ISO instant (negative = past).
function secsUntil(iso: string | null): number | null {
  if (!iso) return null;
  return Math.round((new Date(iso).getTime() - Date.now()) / 1000);
}

function fmtCountdown(s: number): string {
  if (s <= 0) return "now";
  if (s < 60) return `${s}s`;
  const m = Math.floor(s / 60);
  if (m < 60) return `${m}m ${s % 60}s`;
  const h = Math.floor(m / 60);
  return `${h}h ${m % 60}m`;
}

const DOT_CLASS: Record<string, string> = {
  running: "bg-accent animate-pulse",
  ok: "bg-emerald-500",
  error: "bg-red-500",
  skipped: "bg-amber-500",
  idle: "bg-border",
};

function statusKey(job: SchedulerJob): keyof typeof DOT_CLASS {
  if (job.running) return "running";
  if (job.status === "ok") return "ok";
  if (job.status === "error") return "error";
  if (job.status === "skipped") return "skipped";
  return "idle";
}

function StatusDot({ k, withTooltip = true }: { k: keyof typeof DOT_CLASS; withTooltip?: boolean }) {
  const { t } = useTranslation();
  const dot = <span className={`inline-block w-2.5 h-2.5 rounded-full shrink-0 ${DOT_CLASS[k]}`} />;
  return withTooltip ? <Tooltip hint={t(`scheduler.dot.${k}`)}>{dot}</Tooltip> : dot;
}

function StatusLegend() {
  const { t } = useTranslation();
  return (
    <div className="flex items-center gap-x-3 gap-y-1 flex-wrap text-[11px] text-muted mb-2">
      {(["running", "ok", "idle", "error", "skipped"] as const).map((k) => (
        <span key={k} className="inline-flex items-center gap-1.5">
          <StatusDot k={k} withTooltip={false} />
          {t(`scheduler.dot.${k}`)}
        </span>
      ))}
    </div>
  );
}

function JobRow({
  job,
  onSave,
  saving,
}: {
  job: SchedulerJob;
  onSave: (minutes: number) => void;
  saving: boolean;
}) {
  const { t } = useTranslation();
  const [editing, setEditing] = useState(false);
  const [val, setVal] = useState(String(job.interval_minutes));
  const next = secsUntil(job.next_run);
  useEffect(() => {
    if (!editing) setVal(String(job.interval_minutes));
  }, [job.interval_minutes, editing]);

  function save() {
    const m = parseInt(val, 10);
    if (Number.isFinite(m) && m >= 1 && m <= 1440 && m !== job.interval_minutes) onSave(m);
    setEditing(false);
  }

  return (
    <div className="glass-card rounded-xl p-3 flex items-center gap-3">
      <StatusDot k={statusKey(job)} />
      <div className="min-w-0 flex-1">
        <div className="text-sm font-medium flex items-center gap-1.5 flex-wrap">
          <Tooltip hint={t(`scheduler.jobDesc.${job.id}`)}>
            <span className="underline decoration-dotted decoration-muted/40 underline-offset-4 cursor-help">
              {t(`scheduler.jobs.${job.id}`, job.id)}
            </span>
          </Tooltip>
          {editing ? (
            <span className="inline-flex items-center gap-1">
              <input
                type="number"
                min={1}
                max={1440}
                value={val}
                autoFocus
                onChange={(e) => setVal(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") save();
                  if (e.key === "Escape") setEditing(false);
                }}
                className="w-16 bg-card border border-border rounded px-1.5 py-0.5 text-xs outline-none focus:border-accent"
              />
              <span className="text-muted text-xs">{t("scheduler.minutes")}</span>
              <button onClick={save} disabled={saving} className="text-emerald-400 hover:opacity-80 disabled:opacity-50" aria-label={t("common.save")}>
                <Check className="w-3.5 h-3.5" />
              </button>
              <button onClick={() => setEditing(false)} className="text-muted hover:text-fg" aria-label={t("common.cancel")}>
                <X className="w-3.5 h-3.5" />
              </button>
            </span>
          ) : (
            <Tooltip hint={t("scheduler.editInterval")}>
              <button
                onClick={() => setEditing(true)}
                className="group text-muted font-normal hover:text-accent inline-flex items-center gap-1 transition"
              >
                · {t("scheduler.everyMin", { count: job.interval_minutes })}
                <Pencil className="w-3 h-3 opacity-0 group-hover:opacity-100 transition" />
              </button>
            </Tooltip>
          )}
        </div>
        <div className="text-[11px] text-muted truncate">
          {job.running
            ? t("scheduler.runningNow")
            : job.last_finished
              ? t("scheduler.lastRun", { time: relativeTime(job.last_finished) })
              : t("scheduler.neverRun")}
          {job.last_error ? (
            <span className="text-red-400"> · {job.last_error}</span>
          ) : job.last_result ? (
            <span> · {job.last_result}</span>
          ) : null}
        </div>
      </div>
      <div className="shrink-0 text-right text-[11px] text-muted tabular-nums">
        {job.running ? (
          <span className="text-accent">{t("scheduler.active")}</span>
        ) : next != null ? (
          <>
            <div className="uppercase tracking-wide text-[10px]">{t("scheduler.nextRun")}</div>
            <div>{fmtCountdown(next)}</div>
          </>
        ) : (
          "—"
        )}
      </div>
    </div>
  );
}

function Stat({
  icon: Icon,
  label,
  value,
  hint,
  sub,
}: {
  icon: typeof Database;
  label: string;
  value: string | number;
  hint?: string;
  sub?: string;
}) {
  return (
    <div className="glass-card rounded-xl p-3">
      <div className="flex items-center gap-2 text-muted text-xs">
        <Icon className="w-4 h-4 shrink-0" />
        <Tooltip hint={hint ?? ""}>
          <span className={hint ? "underline decoration-dotted decoration-muted/40 underline-offset-4 cursor-help" : ""}>
            {label}
          </span>
        </Tooltip>
      </div>
      <div className="text-xl font-semibold mt-1 tabular-nums">{value}</div>
      {sub && <div className="text-[11px] text-muted">{sub}</div>}
    </div>
  );
}

export default function Scheduler() {
  const { t } = useTranslation();
  const qc = useQueryClient();
  const q = useLiveQuery<SchedulerStatus>(["scheduler"], api.schedulerStatus, {
    intervalMs: POLL_MS,
  });
  const data = q.data;

  // Tick once a second so the per-job countdowns move between polls.
  const [, setTick] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setTick((n) => n + 1), 1000);
    return () => clearInterval(id);
  }, []);

  const pauseResume = useMutation({
    mutationFn: (paused: boolean) => (paused ? api.resumeSync() : api.pauseSync()),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["scheduler"] }),
    onError: () => notify({ level: "error", message: t("scheduler.toggleFailed") }),
  });

  const intervalMut = useMutation({
    mutationFn: (v: { jobId: string; minutes: number }) =>
      api.updateSchedulerJob(v.jobId, v.minutes),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["scheduler"] }),
    onError: () => notify({ level: "error", message: t("scheduler.intervalFailed") }),
  });

  if (q.isLoading && !data)
    return <div className="p-8 text-muted">{t("scheduler.loading")}</div>;
  if (!data)
    return <div className="p-8 text-muted">{t("common.somethingWrong")}</div>;

  const quotaPct = data.quota.daily_budget
    ? Math.min(100, Math.round((data.quota.used_today / data.quota.daily_budget) * 100))
    : 0;

  return (
    <div className="p-4 max-w-4xl w-full mx-auto space-y-4">
      {/* Status strip */}
      <div className="glass rounded-2xl p-4 flex flex-wrap items-center gap-3">
        <Activity className="w-5 h-5 text-accent shrink-0" />
        <div className="min-w-0">
          <div className="font-semibold">{t("scheduler.title")}</div>
          <div className="text-xs text-muted flex items-center gap-2 flex-wrap">
            <span className="inline-flex items-center gap-1">
              <span
                className={`w-2 h-2 rounded-full ${
                  data.paused ? "bg-amber-500" : data.running_here ? "bg-emerald-500" : "bg-border"
                }`}
              />
              {data.paused
                ? t("scheduler.paused")
                : data.running_here
                  ? t("scheduler.running")
                  : t("scheduler.notHere")}
            </span>
            {q.isFetching && <span className="text-accent">· {t("scheduler.updating")}</span>}
          </div>
        </div>
        <div className="flex-1" />
        <Tooltip hint={t("scheduler.pauseHint")}>
          <button
            onClick={() => pauseResume.mutate(data.paused)}
            disabled={pauseResume.isPending}
            className="glass-card glass-hover flex items-center gap-2 px-3 py-2 rounded-xl text-sm disabled:opacity-50 transition"
          >
            {data.paused ? <Play className="w-4 h-4" /> : <Pause className="w-4 h-4" />}
            {data.paused ? t("scheduler.resume") : t("scheduler.pause")}
          </button>
        </Tooltip>
      </div>

      {!data.running_here && (
        <div className="flex items-center gap-2 text-sm bg-amber-500/15 border border-amber-500/30 rounded-xl px-3 py-2">
          <AlertTriangle className="w-4 h-4 text-amber-500 shrink-0" />
          <span className="text-muted">{t("scheduler.notHereNote")}</span>
        </div>
      )}

      {/* Jobs */}
      <div>
        <div className="text-xs uppercase tracking-wide text-muted mb-2">{t("scheduler.jobsTitle")}</div>
        <StatusLegend />
        <div className="space-y-1.5">
          {data.jobs.map((job) => (
            <JobRow
              key={job.id}
              job={job}
              saving={intervalMut.isPending}
              onSave={(minutes) => intervalMut.mutate({ jobId: job.id, minutes })}
            />
          ))}
        </div>
      </div>

      {/* Queue */}
      <div>
        <div className="text-xs uppercase tracking-wide text-muted mb-2">{t("scheduler.queueTitle")}</div>
        <div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
          <Stat
            icon={Database}
            label={t("scheduler.queue.recentPending")}
            hint={t("scheduler.queue.recentPendingHint")}
            value={data.queue.channels_recent_pending.toLocaleString()}
          />
          <Stat
            icon={Database}
            label={t("scheduler.queue.deepPending")}
            hint={t("scheduler.queue.deepPendingHint")}
            value={data.queue.channels_deep_pending.toLocaleString()}
          />
          <Stat
            icon={Clock}
            label={t("scheduler.queue.enrichPending")}
            hint={t("scheduler.queue.enrichPendingHint")}
            value={data.queue.videos_pending_enrich.toLocaleString()}
          />
          <Stat
            icon={Clock}
            label={t("scheduler.queue.shortsPending")}
            hint={t("scheduler.queue.shortsPendingHint")}
            value={data.queue.videos_pending_shorts.toLocaleString()}
          />
          <Stat
            icon={RadioTower}
            label={t("scheduler.queue.liveRefresh")}
            hint={t("scheduler.queue.liveRefreshHint")}
            value={data.queue.videos_live_refresh.toLocaleString()}
          />
        </div>
      </div>

      {/* Quota */}
      <div>
        <div className="text-xs uppercase tracking-wide text-muted mb-2">{t("scheduler.quotaTitle")}</div>
        <div className="glass-card rounded-xl p-4">
          <div className="flex items-center gap-2 text-sm">
            <Gauge className="w-4 h-4 text-muted shrink-0" />
            <span>
              {t("scheduler.quotaUsed", {
                used: data.quota.used_today.toLocaleString(),
                budget: data.quota.daily_budget.toLocaleString(),
              })}
            </span>
            <span className="flex-1" />
            <span className="text-muted text-xs">
              {t("scheduler.quotaRemaining", {
                count: data.quota.remaining_today,
                formatted: data.quota.remaining_today.toLocaleString(),
              })}
            </span>
          </div>
          <div className="mt-2 h-2 rounded-full bg-border overflow-hidden">
            <div
              className={`h-full rounded-full ${quotaPct > 90 ? "bg-red-500" : "bg-accent"}`}
              style={{ width: `${quotaPct}%` }}
            />
          </div>
          <div className="text-[11px] text-muted mt-1.5">{t("scheduler.quotaNote")}</div>
        </div>
      </div>
    </div>
  );
}
