import { useState } from "react";

const API_BASE = (() => {
  const override = import.meta.env.VITE_API_BASE;
  if (override) return override;
  if (window.location.port === "5173") {
    return `${window.location.protocol}//${window.location.hostname}:8002`;
  }
  return window.location.origin;
})();
const BUILD_STAMP = new Date().toISOString();

type Slot = {
  id: string;
  label: string;
  accept: string;
  file: File | null;
  setFile: (file: File | null) => void;
  required?: boolean;
};

function formatSize(file: File) {
  const kb = file.size / 1024;
  if (kb < 1024) return `${kb.toFixed(1)} KB`;
  return `${(kb / 1024).toFixed(1)} MB`;
}

export default function App() {
  const [status, setStatus] = useState<string | null>(null);
  const [busyLabel, setBusyLabel] = useState<string | null>(null);

  const [baseFile, setBaseFile] = useState<File | null>(null);
  const [serversFile, setServersFile] = useState<File | null>(null);
  const [actionsFile, setActionsFile] = useState<File | null>(null);
  const [outputsFile, setOutputsFile] = useState<File | null>(null);
  const [keyboardsFile, setKeyboardsFile] = useState<File | null>(null);
  const [loggingFile, setLoggingFile] = useState<File | null>(null);

  const slots: Slot[] = [
    { id: "base", label: "Base .set", accept: ".set", file: baseFile, setFile: setBaseFile, required: true },
    { id: "servers", label: "Servers", accept: ".xlsx", file: serversFile, setFile: setServersFile },
    { id: "actions", label: "Actions", accept: ".xlsx", file: actionsFile, setFile: setActionsFile },
    { id: "outputs", label: "Outputs", accept: ".xlsx", file: outputsFile, setFile: setOutputsFile },
    { id: "keyboards", label: "Keyboards", accept: ".xlsx", file: keyboardsFile, setFile: setKeyboardsFile },
    { id: "logging", label: "Logging", accept: ".xlsx", file: loggingFile, setFile: setLoggingFile },
  ];

  const handleBuild = async () => {
    if (!baseFile) {
      setStatus("Select a base .set file.");
      return;
    }
    const body = new FormData();
    body.append("base_set", baseFile);
    if (serversFile) body.append("servers", serversFile);
    if (actionsFile) body.append("actions", actionsFile);
    if (outputsFile) body.append("outputs", outputsFile);
    if (keyboardsFile) body.append("keyboards", keyboardsFile);
    if (loggingFile) body.append("logging", loggingFile);

    setStatus("Building combined .set...");
    setBusyLabel("Building .set");
    const controller = new AbortController();
    const timeoutId = window.setTimeout(() => controller.abort(), 300000);
    try {
      const res = await fetch(`${API_BASE}/api/batch/build`, {
        method: "POST",
        body,
        signal: controller.signal,
      });
      if (!res.ok) {
        setStatus(await res.text());
        return;
      }
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = "combined.set";
      link.click();
      URL.revokeObjectURL(url);
      setStatus("Combined .set downloaded.");
    } catch (error: any) {
      if (error?.name === "AbortError") {
        setStatus("Build timed out.");
      } else {
        setStatus("Build failed.");
      }
    } finally {
      window.clearTimeout(timeoutId);
      setBusyLabel(null);
    }
  };

  return (
    <div className="shell simple">
      <header className="topbar">
        <div className="topbar__brand">
          <div className="logo">GV</div>
          <div>
            <div className="topbar__title">GeViSet Builder</div>
            <div className="topbar__subtitle">Batch .set generator • {BUILD_STAMP}</div>
          </div>
        </div>
        <div className="topbar__actions">
          <div className="statusbar">
            {busyLabel && <span className="spinner" />}
            {busyLabel ?? status ?? "Ready."}
          </div>
        </div>
      </header>

      <main className="simple__body">
        <section className="card">
          <div className="card__header">
            <div>
              <h2>Build Combined .set</h2>
              <p>Select the base .set and any Excel files you want to apply. Only selected files are used.</p>
            </div>
            <button className="chip" onClick={handleBuild}>
              Build .set
            </button>
          </div>

          <div className="card__content">
            {slots.map((slot) => (
              <div key={slot.id} className="file-block">
                <label className="file-row">
                  {slot.label}{slot.required ? " *" : ""}
                  <input
                    type="file"
                    accept={slot.accept}
                    onChange={(e) => {
                      const file = e.target.files?.[0] || null;
                      slot.setFile(file);
                      e.target.value = "";
                    }}
                  />
                </label>
                {slot.file ? (
                  <div className="file-meta">
                    <span className="file-name">{slot.file.name}</span>
                    <span className="file-size">{formatSize(slot.file)}</span>
                    <button className="chip chip--ghost" onClick={() => slot.setFile(null)}>
                      Clear
                    </button>
                  </div>
                ) : (
                  <div className="file-meta file-meta--empty">Not selected</div>
                )}
              </div>
            ))}
          </div>
        </section>
      </main>
    </div>
  );
}
