"use client";
import { useState, useCallback } from "react";
import { useRouter } from "next/navigation";

/** POST/PATCH helper returning {ok,data,error}. */
export async function call(url: string, body?: any, method = "POST") {
  try {
    const r = await fetch(url, { method, headers: { "Content-Type": "application/json" }, body: body === undefined ? undefined : JSON.stringify(body) });
    const data = await r.json().catch(() => ({}));
    return r.ok ? { ok: true as const, data, error: "" } : { ok: false as const, data, error: String(data.error || "Something went wrong") };
  } catch { return { ok: false as const, data: {}, error: "Network error — check your connection" }; }
}

/** Hook: busy/error state around an API call, with optional router refresh. */
export function useAction() {
  const router = useRouter();
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");
  const [msg, setMsg] = useState("");
  const run = useCallback(async (url: string, body?: any, o: { refresh?: boolean; method?: string; confirm?: string } = {}) => {
    if (o.confirm && !window.confirm(o.confirm)) return null;
    setBusy(true); setError(""); setMsg("");
    const r = await call(url, body, o.method);
    setBusy(false);
    if (!r.ok) { setError(r.error); return null; }
    if (r.data?.message) setMsg(r.data.message);
    if (o.refresh !== false) router.refresh();
    return r.data;
  }, [router]);
  return { run, busy, error, msg, setError, setMsg };
}

export const Alert = ({ kind = "bad", children }: { kind?: "bad" | "ok"; children?: React.ReactNode }) =>
  children ? <div role="alert" className={`rounded-xl border px-3.5 py-2.5 text-sm ${kind === "bad" ? "border-rose-200 bg-rose-50 text-rose-700" : "border-emerald-200 bg-emerald-50 text-emerald-700"}`}>{children}</div> : null;

export const Field = ({ label, children, hint }: { label: string; children: React.ReactNode; hint?: string }) =>
  <label className="block"><span className="label">{label}</span>{children}{hint && <span className="mt-1 block text-[11px] text-slate-400">{hint}</span>}</label>;

export function Modal({ open, onClose, title, children, wide }: { open: boolean; onClose: () => void; title: string; children: React.ReactNode; wide?: boolean }) {
  if (!open) return null;
  return (
    <div className="fixed inset-0 z-50 flex items-end justify-center bg-slate-900/40 p-0 backdrop-blur-sm sm:items-center sm:p-4" onMouseDown={(e) => e.target === e.currentTarget && onClose()} role="dialog" aria-modal aria-label={title}>
      <div className={`max-h-[92dvh] w-full overflow-y-auto rounded-t-3xl bg-white p-5 shadow-2xl sm:rounded-3xl sm:p-6 ${wide ? "sm:max-w-3xl" : "sm:max-w-lg"}`}>
        <div className="mb-4 flex items-center justify-between"><h3 className="text-lg font-bold">{title}</h3><button onClick={onClose} className="rounded-full p-1.5 text-slate-400 hover:bg-slate-100" aria-label="Close">✕</button></div>
        {children}
      </div>
    </div>
  );
}

const STATUS: Record<string, string> = { paid: "ok", succeeded: "ok", active: "ok", approved: "ok", open: "warn", pending: "warn", pending_review: "warn", initiated: "gray", failed: "bad", rejected: "bad", cancelled: "gray", closed: "gray", expired: "bad", suspended: "bad", disabled: "bad" };
export const Status = ({ s }: { s: string }) => <span className={`badge ${STATUS[s] || "gray"}`}>{s.replace("_", " ")}</span>;
