// RUT241 eSIM Auto Provisioning -- Configurations page (spec §23/§24).
// Two fixed, version-controlled config profile families --
// SOLO-RUT241-UK-EU and SOLO-RUT241-US-NA. Each version can optionally
// carry an uploaded base configuration FILE (RutOS .cfg export, JSON
// bundle, whatever) stored in R2 -- see the "rut241/configurations"
// routes added to admin-rut241.ts (mirrors admin-assets.ts's
// spec-sheet-file pattern, but keyed per version row so every past
// version keeps its own file -- full history survives).
//
// Viewing the version list and downloading the current/any file is
// available to every RUT241 role that can reach this area at all
// (view_provisioning_status) -- technical/production admins may need
// to read the base config while working a router. Creating a new
// version, uploading/replacing/removing a file, or flipping which
// version is "current" is restricted to manage_config_templates,
// which only super_admin holds (see lib/rut241Roles.ts) -- so this
// page renders read-only for the other two roles, same isReadOnly
// pattern as admin-spec-sheets-page.jsx.
//
// Reuses formatBytes/formatDate from admin-spec-sheets-page.jsx,
// SectionLabel/EmptyNote/MiniField/ActionButton/ModalShell/ModalError/
// adminInputStyle/adminSelectStyle from admin-assets-page.jsx,
// AdminShell from admin-shell.jsx, and RUT241_REGION_LABELS from
// admin-rut241-dashboard-page.jsx -- must load after all of those
// (see index.html script order).

const RUT241_CONFIG_PROFILES = ["SOLO-RUT241-UK-EU", "SOLO-RUT241-US-NA"];
const RUT241_CONFIG_PROFILE_LABELS = {
  "SOLO-RUT241-UK-EU": "SOLO-RUT241-UK-EU — UK / Europe",
  "SOLO-RUT241-US-NA": "SOLO-RUT241-US-NA — USA / North America",
};

function AdminRut241ConfigPage({ onNavigate }) {
  const [admin, setAdmin] = useState(null);
  const [status, setStatus] = useState("loading");
  const [configurations, setConfigurations] = useState([]);
  const [permissions, setPermissions] = useState([]);
  const [error, setError] = useState("");
  const [newVersionProfile, setNewVersionProfile] = useState(null);

  const load = () => {
    Promise.all([
      fetch("/api/admin/me", { credentials: "same-origin" }).then((r) => (r.ok ? r.json() : Promise.reject())),
      fetch("/api/admin/rut241/me", { credentials: "same-origin" }).then((r) => (r.ok ? r.json() : Promise.reject())),
    ])
      .then(([me, rut241Me]) => {
        setAdmin(me.admin);
        setPermissions(rut241Me.permissions || []);
        return fetch("/api/admin/rut241/configurations", { credentials: "same-origin" }).then((r) => (r.ok ? r.json() : Promise.reject()));
      })
      .then((data) => {
        setConfigurations(data.configurations || []);
        setStatus("ready");
      })
      .catch(() => onNavigate("admin-login"));
  };

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

  const isReadOnly = !permissions.includes("manage_config_templates");

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

  const grouped = RUT241_CONFIG_PROFILES.map((profileName) => ({
    profileName,
    versions: configurations.filter((v) => v.profile_name === profileName),
  }));

  return (
    <AdminShell admin={admin} page="admin-rut241-dashboard" onNavigate={onNavigate}
      subtitle="RUT241 eSIM Auto Provisioning" title="Configurations.">
      {error && <ModalError>{error}</ModalError>}

      <div style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "rgba(0,0,0,0.6)", marginBottom: 28, maxWidth: 720, lineHeight: 1.6 }}>
        Two fixed base-configuration families, one per region -- version-controlled, with an optional uploaded config file (RutOS export, JSON bundle, etc.) per version.
        {isReadOnly && (
          <div style={{ marginTop: 8, color: "rgba(0,0,0,0.45)" }}>
            You can view versions and download files here, but only a super admin can create a new version, upload/replace a file, or change which version is current.
          </div>
        )}
      </div>

      {grouped.map((group) => (
        <Rut241ConfigProfileBlock
          key={group.profileName}
          profileName={group.profileName}
          versions={group.versions}
          isReadOnly={isReadOnly}
          onError={setError}
          onSaved={load}
          onNewVersion={() => setNewVersionProfile(group.profileName)}
        />
      ))}

      {newVersionProfile && (
        <Rut241NewVersionModal
          profileName={newVersionProfile}
          onCancel={() => setNewVersionProfile(null)}
          onSaved={() => { setNewVersionProfile(null); load(); }}
        />
      )}
    </AdminShell>
  );
}

function Rut241ConfigProfileBlock({ profileName, versions, isReadOnly, onError, onSaved, onNewVersion }) {
  return (
    <div style={{ marginBottom: 34 }}>
      <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", flexWrap: "wrap", gap: 10 }}>
        <SectionLabel>{RUT241_CONFIG_PROFILE_LABELS[profileName] || profileName}</SectionLabel>
        {!isReadOnly && (
          <ActionButton onClick={onNewVersion} testId={`rut241-config-new-${profileName}`}>+ New version</ActionButton>
        )}
      </div>
      {versions.length === 0 ? (
        <EmptyNote>No versions yet for this profile.</EmptyNote>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {versions.map((v) => (
            <Rut241ConfigVersionRow key={v.id} version={v} isReadOnly={isReadOnly} onError={onError} onSaved={onSaved} />
          ))}
        </div>
      )}
    </div>
  );
}

function Rut241ConfigVersionRow({ version, isReadOnly, onError, onSaved }) {
  const [uploading, setUploading] = useState(false);
  const [removing, setRemoving] = useState(false);
  const [settingCurrent, setSettingCurrent] = useState(false);
  const fileInputRef = useRef(null);

  const hasFile = Boolean(version.file_name);

  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/rut241/configurations/${version.id}/file`, {
        method: "POST", credentials: "same-origin", body: formData,
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { onError(data.error || "Couldn't upload that configuration file."); 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/rut241/configurations/${version.id}/file`, {
        method: "DELETE", credentials: "same-origin",
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { onError(data.error || "Couldn't remove that file."); return; }
      onSaved();
    } catch {
      onError("Couldn't reach the server. Check your connection and try again.");
    } finally {
      setRemoving(false);
    }
  };

  const makeCurrent = async () => {
    onError("");
    setSettingCurrent(true);
    try {
      const res = await fetch(`/api/admin/rut241/configurations/${version.id}/make-current`, {
        method: "POST", credentials: "same-origin",
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { onError(data.error || "Couldn't set that version as current."); return; }
      onSaved();
    } catch {
      onError("Couldn't reach the server. Check your connection and try again.");
    } finally {
      setSettingCurrent(false);
    }
  };

  return (
    <div data-testid={`rut241-config-version-${version.id}`} style={{
      background: version.is_current ? "rgba(20,140,60,0.05)" : "rgba(0,0,0,0.02)",
      border: version.is_current ? "1px solid rgba(20,140,60,0.35)" : "1px solid rgba(0,0,0,0.14)",
      padding: "18px 20px", display: "flex", alignItems: "flex-start", gap: 16, flexWrap: "wrap",
    }}>
      <div style={{ minWidth: 130, flex: "0 0 130px" }}>
        <div style={{ fontFamily: "var(--font-display)", fontWeight: 700, fontSize: 15, color: "#000" }}>
          v{version.version}
        </div>
        {Boolean(version.is_current) && (
          <div style={{
            fontFamily: "var(--font-body)", fontSize: 10, fontWeight: 700, letterSpacing: "0.08em",
            textTransform: "uppercase", color: "rgba(20,140,60,0.95)", marginTop: 4,
          }}>
            Current
          </div>
        )}
        <div style={{ fontFamily: "var(--font-body)", fontSize: 11, color: "rgba(0,0,0,0.45)", marginTop: 6 }}>
          {formatDate(version.created_at)}
          {version.created_by_name ? ` · ${version.created_by_name}` : ""}
        </div>
      </div>

      <div style={{ flex: "1 1 260px", minWidth: 200 }}>
        {version.notes ? (
          <div style={{ fontFamily: "var(--font-body)", fontSize: 12.5, color: "rgba(0,0,0,0.7)", lineHeight: 1.5 }}>
            {version.notes}
          </div>
        ) : (
          <div style={{ fontFamily: "var(--font-body)", fontSize: 12.5, color: "rgba(0,0,0,0.4)" }}>No notes.</div>
        )}
      </div>

      <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
        {!version.is_current && !isReadOnly && (
          <ActionButton onClick={makeCurrent} disabled={settingCurrent} testId={`rut241-config-make-current-${version.id}`}>
            {settingCurrent ? "Setting…" : "Make current"}
          </ActionButton>
        )}
      </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",
        }}>
          Config file
        </div>

        {hasFile ? (
          <div style={{ fontFamily: "var(--font-body)", fontSize: 12.5, color: "rgba(0,0,0,0.8)" }}>
            <i className="fas fa-file-code" style={{ color: "rgba(60,100,190,0.9)", marginRight: 6 }} />
            {version.file_name}
            <span style={{ color: "rgba(0,0,0,0.45)", marginLeft: 8 }}>
              {[formatBytes(version.file_size), formatDate(version.file_uploaded_at)].filter(Boolean).join(" · ")}
            </span>
          </div>
        ) : (
          <div style={{ fontFamily: "var(--font-body)", fontSize: 12.5, color: "rgba(0,0,0,0.45)" }}>
            No file uploaded yet.
          </div>
        )}

        {hasFile && (
          <a
            href={`/api/admin/rut241/configurations/${version.id}/file`}
            target="_blank" rel="noopener noreferrer"
            data-testid={`rut241-config-download-${version.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",
            }}
          >
            Download ↗
          </a>
        )}

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

function Rut241NewVersionModal({ profileName, onCancel, onSaved }) {
  const [version, setVersion] = useState("");
  const [notes, setNotes] = useState("");
  const [makeCurrent, setMakeCurrent] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState("");

  const save = async () => {
    if (!version.trim()) { setError("A version label is required (e.g. 1.0, 2024-06)."); return; }
    setSaving(true);
    setError("");
    try {
      const res = await fetch("/api/admin/rut241/configurations", {
        method: "POST", credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ profileName, version: version.trim(), notes: notes.trim() || undefined, makeCurrent }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { setError(data.error || "Couldn't create that version."); setSaving(false); return; }
      onSaved();
    } catch {
      setError("Couldn't reach the server. Check your connection and try again.");
      setSaving(false);
    }
  };

  return (
    <ModalShell title={`New version — ${RUT241_CONFIG_PROFILE_LABELS[profileName] || profileName}`} onCancel={onCancel}>
      {error && <ModalError>{error}</ModalError>}
      <MiniField label="Version label">
        <input value={version} onChange={(e) => setVersion(e.target.value)} placeholder="e.g. 1.0" style={adminInputStyle} />
      </MiniField>
      <MiniField label="Notes (optional)">
        <input value={notes} onChange={(e) => setNotes(e.target.value)} placeholder="What changed in this version" style={adminInputStyle} />
      </MiniField>
      <label style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 10, fontFamily: "var(--font-body)", fontSize: 12.5, color: "rgba(0,0,0,0.7)" }}>
        <input type="checkbox" checked={makeCurrent} onChange={(e) => setMakeCurrent(e.target.checked)} />
        Make this the current version for this profile
      </label>
      <div style={{ fontFamily: "var(--font-body)", fontSize: 11.5, color: "rgba(0,0,0,0.45)", marginTop: 10, lineHeight: 1.5 }}>
        You can upload the base configuration file for this version right after creating it.
      </div>
      <div style={{ display: "flex", gap: 10, marginTop: 18 }}>
        <ActionButton onClick={onCancel}>Cancel</ActionButton>
        <ActionButton onClick={save} disabled={saving}>{saving ? "Creating…" : "Create version"}</ActionButton>
      </div>
    </ModalShell>
  );
}

Object.assign(window, { AdminRut241ConfigPage });
