// Solo staff admin area — Spec Sheets: per product, staff can either paste
// a link to that product's spec sheet on the public marketing website
// (solosecure.tech) or any other externally-hosted PDF/page, OR upload a
// single PDF file directly (stored in R2 — see migrations/0008 and the
// /spec-sheet/file routes in admin-assets.ts). Only one PDF is kept per
// product — re-uploading replaces it, no version history. When a PDF has
// been uploaded, the "Open ↗" link prefers it over the URL field; the URL
// is left in place either way so staff can remove the PDF and fall back to
// it. Reached via the sidebar nav in AdminShell (see admin-shell.jsx).
// Reuses MiniField/ActionButton/SectionLabel/EmptyNote/ModalError/
// adminInputStyle from admin-assets-page.jsx (loaded earlier — see
// index.html), same pattern as admin-pricing-page.jsx.

const formatBytes = (bytes) => {
  if (!bytes) return "";
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
};

const formatDate = (iso) => {
  if (!iso) return "";
  try {
    return new Date(iso).toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric" });
  } catch {
    return "";
  }
};

function AdminSpecSheetsPage({ onNavigate }) {
  const [state, setState] = useState({ status: "loading", admin: null, products: [] });
  const [error, setError] = useState("");

  const load = () => {
    Promise.all([
      fetch("/api/admin/me", { credentials: "same-origin" }).then((r) => (r.ok ? r.json() : Promise.reject())),
      fetch("/api/admin/products", { credentials: "same-origin" }).then((r) => (r.ok ? r.json() : Promise.reject())),
    ])
      .then(([me, products]) => {
        setState({ status: "ready", admin: me.admin, products: products.products || [] });
      })
      .catch(() => onNavigate("admin-login"));
  };

  useEffect(load, []); // eslint-disable-line react-hooks/exhaustive-deps -- mount-only

  const isReadOnly = state.admin && state.admin.role !== "super_admin";

  if (state.status === "loading") {
    return <section style={{ background: "#fff", minHeight: "calc(100vh - 88px)" }} />;
  }

  return (
    <AdminShell admin={state.admin} page="admin-spec-sheets" onNavigate={onNavigate}
      subtitle="Staff only" title="Spec sheets.">
      <div style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "rgba(0,0,0,0.6)", marginBottom: 24, maxWidth: 760, lineHeight: 1.6 }}>
        Paste a link to each product's spec sheet on the website (or any other externally-hosted PDF/page). Anything saved here shows up as a direct "Open spec sheet" link on that product — for your own reference, and to hand straight to a customer.
      </div>
      {error && <ModalError>{error}</ModalError>}

      <SectionLabel>Products ({state.products.length})</SectionLabel>
      {state.products.length === 0 ? (
        <EmptyNote>No products in the catalogue yet.</EmptyNote>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          {state.products.map((p) => (
            <SpecSheetRow key={p.id} product={p} isReadOnly={isReadOnly} onError={setError} onSaved={load} />
          ))}
        </div>
      )}
    </AdminShell>
  );
}

function SpecSheetRow({ product, isReadOnly, onError, onSaved }) {
  const [value, setValue] = useState(product.spec_sheet_url || "");
  const [saving, setSaving] = useState(false);
  const [saved, setSaved] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [removing, setRemoving] = useState(false);
  const fileInputRef = useRef(null);

  useEffect(() => { setValue(product.spec_sheet_url || ""); }, [product.spec_sheet_url]);

  const dirty = value.trim() !== (product.spec_sheet_url || "");
  const hasFile = Boolean(product.spec_sheet_key);
  const openHref = hasFile ? `/api/admin/products/${product.id}/spec-sheet/file` : product.spec_sheet_url;

  const save = async () => {
    setSaving(true);
    onError("");
    try {
      const res = await fetch(`/api/admin/products/${product.id}/spec-sheet`, {
        method: "PATCH", credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ specSheetUrl: value.trim() }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { onError(data.error || "Something went wrong."); return; }
      setSaved(true);
      onSaved();
      setTimeout(() => setSaved(false), 1800);
    } catch {
      onError("Couldn't reach the server. Check your connection and try again.");
    } finally {
      setSaving(false);
    }
  };

  const pickFile = () => fileInputRef.current && fileInputRef.current.click();

  const uploadFile = async (file) => {
    if (!file) return;
    onError("");
    setUploading(true);
    try {
      const formData = new FormData();
      formData.append("file", file);
      const res = await fetch(`/api/admin/products/${product.id}/spec-sheet/file`, {
        method: "POST", credentials: "same-origin", body: formData,
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { onError(data.error || "Couldn't upload that PDF."); return; }
      onSaved();
    } catch {
      onError("Couldn't reach the server. Check your connection and try again.");
    } finally {
      setUploading(false);
    }
  };

  const onFileChange = (e) => {
    const file = e.target.files && e.target.files[0];
    e.target.value = ""; // allow re-selecting the same filename later
    if (file) uploadFile(file);
  };

  const removeFile = async () => {
    onError("");
    setRemoving(true);
    try {
      const res = await fetch(`/api/admin/products/${product.id}/spec-sheet/file`, {
        method: "DELETE", credentials: "same-origin",
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { onError(data.error || "Couldn't remove that PDF."); return; }
      onSaved();
    } catch {
      onError("Couldn't reach the server. Check your connection and try again.");
    } finally {
      setRemoving(false);
    }
  };

  return (
    <div data-testid={`spec-sheet-row-${product.id}`} style={{
      background: "rgba(0,0,0,0.02)", border: "1px solid rgba(0,0,0,0.14)", padding: "18px 20px",
      display: "flex", alignItems: "flex-end", gap: 16, flexWrap: "wrap",
    }}>
      <div style={{ minWidth: 150, flex: "0 0 150px" }}>
        <div style={{
          fontFamily: "var(--font-display)", fontWeight: 700, fontSize: 15,
          textTransform: "uppercase", color: "#000",
        }}>{product.name}</div>
        {!product.active && (
          <div style={{ fontFamily: "var(--font-body)", fontSize: 10.5, color: "rgba(0,0,0,0.45)", marginTop: 4 }}>
            Discontinued
          </div>
        )}
      </div>

      <div style={{ flex: "1 1 320px", minWidth: 240 }}>
        <MiniField label="Spec sheet URL">
          <input
            value={value}
            onChange={(e) => setValue(e.target.value)}
            onKeyDown={(e) => { if (e.key === "Enter") save(); }}
            placeholder="https://www.solosecure.tech/?page=product-detail&id=pro-tower"
            data-testid={`spec-sheet-input-${product.id}`}
            style={{ ...adminInputStyle, width: "100%" }}
          />
        </MiniField>
      </div>

      <div style={{ display: "flex", alignItems: "center", gap: 10, paddingBottom: 2 }}>
        {openHref && (
          <a
            href={openHref} target="_blank" rel="noopener noreferrer"
            data-testid={`spec-sheet-open-${product.id}`}
            style={{
              fontFamily: "var(--font-body)", fontSize: 11.5, fontWeight: 500,
              letterSpacing: "0.08em", textTransform: "uppercase",
              color: "rgba(180,110,0,0.95)", textDecoration: "none",
              border: "1px solid rgba(180,110,0,0.4)", padding: "9px 14px",
              whiteSpace: "nowrap",
            }}
          >
            Open ↗
          </a>
        )}
        <ActionButton
          onClick={save}
          disabled={!dirty || saving}
          readOnly={isReadOnly}
          testId={`spec-sheet-save-${product.id}`}
        >
          {saving ? "Saving…" : "Save"}
        </ActionButton>
        {saved && !saving && (
          <span style={{ fontFamily: "var(--font-body)", fontSize: 10.5, color: "rgba(20,140,60,0.95)" }}>Saved ✓</span>
        )}
      </div>

      <div style={{
        flex: "1 1 100%", display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap",
        borderTop: "1px solid rgba(0,0,0,0.1)", paddingTop: 14, marginTop: 2,
      }}>
        <div style={{
          fontFamily: "var(--font-body)", fontSize: 10.5, letterSpacing: "0.08em",
          textTransform: "uppercase", color: "rgba(0,0,0,0.45)", whiteSpace: "nowrap",
        }}>
          PDF upload
        </div>

        {hasFile ? (
          <div style={{ fontFamily: "var(--font-body)", fontSize: 12.5, color: "rgba(0,0,0,0.8)" }}>
            <i className="fas fa-file-pdf" style={{ color: "rgba(190,40,40,0.9)", marginRight: 6 }} />
            {product.spec_sheet_filename || "spec-sheet.pdf"}
            <span style={{ color: "rgba(0,0,0,0.45)", marginLeft: 8 }}>
              {[formatBytes(product.spec_sheet_size), formatDate(product.spec_sheet_uploaded_at)].filter(Boolean).join(" · ")}
            </span>
          </div>
        ) : (
          <div style={{ fontFamily: "var(--font-body)", fontSize: 12.5, color: "rgba(0,0,0,0.45)" }}>
            No PDF uploaded yet.
          </div>
        )}

        <input
          ref={fileInputRef}
          type="file"
          accept="application/pdf"
          onChange={onFileChange}
          data-testid={`spec-sheet-file-input-${product.id}`}
          style={{ display: "none" }}
        />
        <ActionButton
          onClick={pickFile}
          disabled={uploading || removing}
          readOnly={isReadOnly}
          testId={`spec-sheet-upload-${product.id}`}
        >
          {uploading ? "Uploading…" : hasFile ? "Replace PDF" : "Upload PDF"}
        </ActionButton>
        {hasFile && (
          <ActionButton
            onClick={removeFile}
            disabled={uploading || removing}
            readOnly={isReadOnly}
            danger
            testId={`spec-sheet-remove-${product.id}`}
          >
            {removing ? "Removing…" : "Remove PDF"}
          </ActionButton>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { AdminSpecSheetsPage });
