// Submit page — multi-file upload with real Supabase Storage + Formspree ping.
// On submit:
//   1. Generate a submission ID (uuid v4)
//   2. Upload each file to the "submissions" bucket at <id>/<filename>
//      with per-file progress (XHR upload events)
//   3. Insert a row into the "submissions" table with file metadata
//   4. Ping Formspree so the studio inbox gets a notification
//   5. Show the polished success state with the submission ID
//
// Falls back gracefully if Supabase isn't configured — see the inline notice.

const MAX_FILE_BYTES = 50 * 1024 * 1024;     // 50 MB hard cap per file (Supabase free-tier limit)
const SUBMIT_FORMSPREE_ID = "YOUR_FORM_ID";  // share with Estimator (or move to a shared config later)

function fmtBytes(n) {
  if (n < 1024) return `${n} B`;
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
  return `${(n / 1024 / 1024).toFixed(2)} MB`;
}

function uuidv4() {
  if (window.crypto && crypto.randomUUID) return crypto.randomUUID();
  return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
    (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  );
}

// Human-friendly reference: RS-YYMMDD-XXXX (date + 4-char code).
function makeRef() {
  const d = new Date();
  const ymd = String(d.getFullYear()).slice(2) +
    String(d.getMonth() + 1).padStart(2, "0") +
    String(d.getDate()).padStart(2, "0");
  let rand = "";
  const chars = "ABCDEFGHJKMNPQRSTUVWXYZ23456789"; // no easily-confused chars
  const r = (window.crypto && crypto.getRandomValues) ? crypto.getRandomValues(new Uint8Array(4)) : null;
  for (let i = 0; i < 4; i++) rand += chars[(r ? r[i] : Math.floor(Math.random() * 256)) % chars.length];
  return `RS-${ymd}-${rand}`;
}

function SubmitPage({ go }) {
  const [files, setFiles]       = React.useState([]); // [{file, progress: 0..1, error: string|null}]
  const [drag,  setDrag]        = React.useState(false);
  const [name,  setName]        = React.useState("");
  const [email, setEmail]       = React.useState("");
  const [svc,   setSvc]         = React.useState([]);
  const [notes, setNotes]       = React.useState("");
  const [ndaOpen, setNdaOpen]   = React.useState(false);
  const [ndaCopied, setNdaCopied] = React.useState(false);
  const [deadline, setDeadline] = React.useState("");
  const [deadlineUnknown, setDeadlineUnknown] = React.useState(false);
  const dateRef = React.useRef(null);
  const [status, setStatus]     = React.useState("idle"); // idle | uploading | sending | sent | error
  const [errMsg, setErrMsg]     = React.useState("");
  const [submissionId, setSubmissionId] = React.useState("");
  const [submissionRef, setSubmissionRef] = React.useState("");
  const [estimate, setEstimate] = React.useState(null);
  const inputRef = React.useRef(null);

  // Pick up an estimate carried over from the Estimator (used within ~2 hours).
  React.useEffect(() => {
    try {
      const raw = localStorage.getItem("rs_estimate");
      if (!raw) return;
      const est = JSON.parse(raw);
      if (est && est.total && est.ts && (Date.now() - est.ts) < 2 * 60 * 60 * 1000) {
        setEstimate(est);
      }
    } catch (e) {}
  }, []);

  const addFiles = (list) => {
    if (!list || !list.length) return;
    const toAdd = Array.from(list).map(file => ({
      file,
      progress: 0,
      error: file.size > MAX_FILE_BYTES
        ? `Over 50 MB — please send via WeTransfer and reference in notes.`
        : null,
    }));
    setFiles(prev => [...prev, ...toAdd]);
  };

  const removeFile = (i) => setFiles(prev => prev.filter((_, j) => j !== i));

  // Build a prefilled NDA-request email, and a copy-address fallback so the
  // affordance never dead-ends when there's no mail client.
  const ndaMailtoHref = () => {
    const subject = "NDA request — before submitting materials";
    const body =
`Hello,

Before I send my score, I'd like to put a mutual NDA in place.

Name: ${name || ""}
Email: ${email || ""}

Thank you.`;
    return `mailto:${SUBMIT_STUDIO_EMAIL}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
  };
  const copyStudioEmail = async () => {
    try { await navigator.clipboard.writeText(SUBMIT_STUDIO_EMAIL); setNdaCopied(true); setTimeout(() => setNdaCopied(false), 1800); }
    catch (e) { window.prompt("Copy the studio email:", SUBMIT_STUDIO_EMAIL); }
  };

  const onDrop = (e) => {
    e.preventDefault();
    setDrag(false);
    addFiles(e.dataTransfer.files);
  };

  const totalBytes = files.reduce((s, f) => s + f.file.size, 0);
  const validFiles = files.filter(f => !f.error);
  const hasOversize = files.some(f => !!f.error);

  // Deadline within a week (incl. today) auto-flags the submission as urgent.
  const todayStr = new Date().toISOString().slice(0, 10);
  const daysUntilDeadline = deadline
    ? Math.ceil((new Date(deadline + "T00:00:00") - new Date(todayStr + "T00:00:00")) / 86400000)
    : null;
  const urgentFromDeadline = daysUntilDeadline !== null && daysUntilDeadline <= 7;
  const isUrgent = urgentFromDeadline;

  const submit = async (e) => {
    e.preventDefault();
    if (status === "uploading" || status === "sending") return;
    setErrMsg("");

    if (svc.length === 0) {
      setStatus("error");
      setErrMsg('Please select at least one service.');
      return;
    }

    if (!deadline && !deadlineUnknown) {
      setStatus("error");
      setErrMsg('Please choose a deadline, or select "I don\'t know yet".');
      return;
    }

    // Backend availability check
    const supaReady = window.supaConfigured && window.supaConfigured();
    if (!supaReady) {
      setStatus("error");
      setErrMsg(
        `Submission system isn't activated yet. Please email ${SUBMIT_STUDIO_EMAIL} directly with your score and brief — we'll come back to you within 24 hours.`
      );
      return;
    }

    const id = uuidv4();
    const ref = makeRef();
    setSubmissionId(id);
    setSubmissionRef(ref);
    setStatus("uploading");

    // Upload files sequentially so progress reads cleanly.
    try {
      for (let i = 0; i < files.length; i++) {
        if (files[i].error) continue;
        const safe = window.sanitizeFilename(files[i].file.name);
        const path = `${id}/${safe}`;
        await window.uploadFile("submissions", path, files[i].file, (p) => {
          setFiles(prev => prev.map((f, j) => j === i ? { ...f, progress: p } : f));
        });
        setFiles(prev => prev.map((f, j) => j === i ? { ...f, progress: 1 } : f));
      }
    } catch (err) {
      console.error(err);
      setStatus("error");
      setErrMsg(`File upload failed: ${err.message}. Please try again, or email ${SUBMIT_STUDIO_EMAIL} directly.`);
      return;
    }

    // Write the metadata row.
    setStatus("sending");
    const fileMeta = files.filter(f => !f.error).map(f => ({
      path: `${id}/${window.sanitizeFilename(f.file.name)}`,
      name: f.file.name,
      size: f.file.size,
      type: f.file.type || "application/octet-stream",
    }));

    try {
      await window.supaInsert("submissions", {
        id, ref, name, email, service: svc.join(", "), notes,
        urgent: isUrgent,
        deadline: deadlineUnknown ? "not sure" : (deadline || null),
        estimate_total: estimate ? estimate.total : null,
        estimate_detail: estimate ? estimate.detail : null,
        files: fileMeta,
      });
    } catch (err) {
      console.error(err);
      setStatus("error");
      setErrMsg(`Couldn't save submission details: ${err.message}. Files uploaded successfully — please email ${SUBMIT_STUDIO_EMAIL} with reference ID ${id}.`);
      return;
    }

    // Studio notification — fire-and-forget. Don't block on failure.
    if (SUBMIT_FORMSPREE_ID && SUBMIT_FORMSPREE_ID !== "YOUR_FORM_ID") {
      try {
        await fetch(`https://formspree.io/f/${SUBMIT_FORMSPREE_ID}`, {
          method: "POST",
          headers: { "Content-Type": "application/json", Accept: "application/json" },
          body: JSON.stringify({
            _subject: `${isUrgent ? "[URGENT] " : ""}New submission — ${name} — ${svc.join(", ")}`,
            _replyto: email,
            reference: ref,
            submission_id: id,
            estimate: estimate ? estimate.total : "none",
            name, email, service: svc.join(", "), notes,
            deadline: deadlineUnknown ? "not sure" : (deadline || "not given"),
            urgent: isUrgent ? "YES — deadline within a week" : "no",
            files: fileMeta.map(f => `${f.name} (${fmtBytes(f.size)})`).join("\n"),
            file_count: fileMeta.length,
          }),
        });
      } catch (err) {
        console.warn("Notification ping failed (submission still recorded):", err);
      }
    }

    try { localStorage.removeItem("rs_estimate"); } catch (e) {}
    setStatus("sent");
  };

  // ── Success state ──────────────────────────────────────────────────────────
  if (status === "sent") {
    return (
      <div className="page">
        <div className="wrap wrap--narrow" style={{ paddingTop: 96 }}>
          <div className="submit-done-check" aria-hidden="true">✓</div>
          <h1 className="submit-done-title">
            Your score is<br />with the studio.
          </h1>
          <p className="submit-done-sub">
            {isUrgent
              ? "You flagged this as urgent — we'll be in touch as soon as we possibly can."
              : "A firm quote and turnaround will reach you by email within 24 hours."}
          </p>
          <div className="mono-sm submit-done-ref">Reference&nbsp;&nbsp;{submissionRef || submissionId}</div>
          <div className="mono-sm" style={{ marginTop: 10, color: "var(--fg-muted)" }}>
            {validFiles.length} file{validFiles.length !== 1 ? "s" : ""} · {fmtBytes(validFiles.reduce((s, f) => s + f.file.size, 0))} · sent to {email}
          </div>
          <div style={{ marginTop: 44, display: "flex", gap: 16 }}>
            <button className="btn-primary" onClick={() => go("home")}>
              <span>Back to home</span><span className="arrow"></span>
            </button>
            <button className="btn-secondary" onClick={() => {
              setFiles([]); setName(""); setEmail(""); setNotes("");
              setDeadline(""); setDeadlineUnknown(false);
              setSvc([]); setStatus("idle"); setSubmissionId(""); setSubmissionRef("");
            }}>Submit another →</button>
          </div>
        </div>
      </div>);
  }

  // ── Main form ──────────────────────────────────────────────────────────────
  const uploading = status === "uploading" || status === "sending";

  return (
    <div className="page">
      <div className="wrap wrap--narrow">
        <div className="hero" style={{ paddingBottom: 48 }}>
          <div className="hero-meta">
            <div className="mono">Submit a score</div>
            <div className="mono"></div>
          </div>
          <h1 className="hero-title hero-title--sans" style={{ fontSize: "clamp(48px, 7vw, 104px)" }}>
            Send us your score.
          </h1>
          <p className="mono-sm" style={{ marginTop: 24, maxWidth: 640, lineHeight: 1.7 }}>
            Not sure where to start? Try the <button type="button" className="faq-inline-link" onClick={() => go("studio", "estimator")}>quick estimator</button> for an indicative price, browse the <button type="button" className="faq-inline-link" onClick={() => go("studio")}>full list of services</button>, or check the <button type="button" className="faq-inline-link" onClick={() => go("faq")}>FAQ</button> for accepted file types and turnarounds.
          </p>
        </div>

        <form className="submit-grid" onSubmit={submit}>
          {estimate && (
            <div className="submit-estimate" style={{ gridColumn: "1 / -1" }}>
              <div className="submit-estimate-head">
                <div>
                  <div className="mono-sm">Estimate attached</div>
                  <div className="submit-estimate-total">{estimate.total}</div>
                </div>
                <button type="button" className="submit-estimate-rm" disabled={uploading}
                  onClick={() => { setEstimate(null); try { localStorage.removeItem("rs_estimate"); } catch (e) {} }}>
                  Remove
                </button>
              </div>
              {Array.isArray(estimate.services) && estimate.services.length > 0 && (
                <div className="submit-estimate-svcs mono-sm">
                  {estimate.services.join(" · ")}{estimate.turnaround ? ` · ${estimate.turnaround} turnaround` : ""}
                </div>
              )}
              <div className="submit-estimate-note mono-sm">Your estimator quote travels with this request — no need to re-enter it.</div>
            </div>
          )}
          {/* Upload — full row */}
          <div style={{ gridColumn: "1 / -1" }}>
            <div className="mono-sm" style={{ marginBottom: 12 }}>01 · Score file(s)<span className="req-star">*</span> — PDF, MusicXML, Sibelius, Dorico, audio refs</div>
            <div
              className={`upload-zone ${drag ? "drag" : ""} ${files.length ? "has-file" : ""} ${uploading ? "disabled" : ""}`}
              onDragOver={(e) => { if (!uploading) { e.preventDefault(); setDrag(true); } }}
              onDragLeave={() => setDrag(false)}
              onDrop={(e) => { if (!uploading) onDrop(e); }}
              onClick={() => !uploading && inputRef.current?.click()}>
              <div className="mono-sm">Drop files here, or</div>
              <div className="lg">{files.length ? `${files.length} file${files.length !== 1 ? "s" : ""} selected` : "choose files"}</div>
              <div className="mono-sm">
                {files.length
                  ? `${fmtBytes(totalBytes)} total · click to add more`
                  : "Up to 50 MB per file · multiple files OK"}
              </div>
              <input
                ref={inputRef}
                type="file"
                multiple
                disabled={uploading}
                style={{ display: "none" }}
                onChange={(e) => { addFiles(e.target.files); e.target.value = ""; }} />
            </div>

            {/* File list with progress */}
            {files.length > 0 && (
              <div className="submit-filelist">
                {files.map((f, i) => (
                  <div key={i} className={`submit-fileitem ${f.error ? "err" : ""}`}>
                    <div className="submit-fileitem-info">
                      <div className="submit-fileitem-name">{f.file.name}</div>
                      <div className="submit-fileitem-meta mono-sm">
                        {fmtBytes(f.file.size)}
                        {f.error && <span className="submit-fileitem-err"> · {f.error}</span>}
                        {!f.error && uploading && f.progress > 0 && f.progress < 1 && (
                          <span> · {Math.round(f.progress * 100)}%</span>
                        )}
                        {!f.error && f.progress === 1 && <span> · ✓ uploaded</span>}
                      </div>
                      {!f.error && uploading && (
                        <div className="submit-fileitem-bar">
                          <div className="submit-fileitem-bar-fill" style={{ width: `${f.progress * 100}%` }} />
                        </div>
                      )}
                    </div>
                    {!uploading && (
                      <button type="button" className="submit-fileitem-rm" onClick={() => removeFile(i)} aria-label="Remove file">×</button>
                    )}
                  </div>
                ))}
              </div>
            )}

            {hasOversize && (
              <div className="submit-warn mono-sm">
                One or more files are larger than 50&nbsp;MB. Send those via <a href="https://wetransfer.com" target="_blank" rel="noopener noreferrer">WeTransfer</a> to <a href={`mailto:${SUBMIT_STUDIO_EMAIL}`}>{SUBMIT_STUDIO_EMAIL}</a> referencing your submission ID, or compress the score to PDF first.
              </div>
            )}
          </div>

          {/* Confidentiality reassurance */}
          <div className="submit-confidential" style={{ gridColumn: "1 / -1" }}>
            <div className="submit-confidential-main">
              <div className="mono-sm">Held in complete confidence</div>
              <p>
                Every score is treated as private, unpublished work. Your materials are never shared, performed, or shown as an example without your written permission — they're stored on a private, access-controlled server and deleted on request once the work is delivered.
              </p>
            </div>
          </div>

          <div className="submit-field">
            <label>02 · Your name<span className="req-star">*</span></label>
            <input type="text" placeholder="Full name" required value={name} onChange={e => setName(e.target.value)} disabled={uploading} />
          </div>
          <div className="submit-field">
            <label>03 · Contact email<span className="req-star">*</span></label>
            <input type="email" placeholder="you@studio.com" required value={email} onChange={e => setEmail(e.target.value)} disabled={uploading} />
          </div>

          <div className="submit-field" style={{ gridColumn: "1 / -1" }}>
            <label>04 · Service<span className="req-star">*</span> <span className="req-hint">— select all that apply</span></label>
            <div className="est-chips" style={{ marginTop: 8 }}>
              {[
              ["engraving", "Score & parts"],
              ["digitisation", "Digitisation"],
              ["transcription", "Transcription"],
              ["reduction", "Piano reduction"],
              ["transposition", "Transposition"],
              ["mockup", "Audio mockup"],
              ["print", "Print & bind"]].
              map(([k, l]) =>
              <button type="button" key={k}
                disabled={uploading}
                className={`est-chip ${svc.includes(k) ? "on" : ""}`}
                onClick={() => setSvc(prev =>
                  prev.includes(k)
                    ? prev.filter(x => x !== k)
                    : [...prev, k]
                )}>{l}</button>
              )}
            </div>
          </div>

          <div className="submit-field" style={{ gridColumn: "1 / -1" }}>
            <label>05 · Deadline<span className="req-star">*</span> <span className="req-hint">— when do you need it by?</span></label>
            <div className="submit-deadline">
              <input
                ref={dateRef}
                type="date"
                className="submit-date-input"
                min={todayStr}
                value={deadline}
                disabled={uploading || deadlineUnknown}
                onClick={() => { try { dateRef.current && dateRef.current.showPicker && dateRef.current.showPicker(); } catch (e) {} }}
                onChange={e => { setDeadline(e.target.value); setDeadlineUnknown(false); }} />
              <span className="submit-deadline-or mono-sm">or</span>
              <button type="button"
                className={`est-chip ${deadlineUnknown ? "on" : ""}`}
                disabled={uploading}
                onClick={() => { setDeadlineUnknown(u => !u); setDeadline(""); }}>
                I don't know yet
              </button>
            </div>
            {urgentFromDeadline && (
              <div className="submit-deadline-note mono-sm">
                {daysUntilDeadline <= 0 ? "Needed today" : `${daysUntilDeadline} day${daysUntilDeadline === 1 ? "" : "s"} away`} — we've flagged this as urgent.
              </div>
            )}
          </div>

          <div className="submit-field" style={{ gridColumn: "1 / -1" }}>
            <label>06 · Notes — source materials, references, anything unusual</label>
            <textarea
              placeholder={`e.g. A3 conductor score + 18 parts, first rehearsal 12 May…\n\nFor files over 50 MB, paste a WeTransfer link here.`}
              value={notes}
              onChange={e => setNotes(e.target.value)}
              disabled={uploading} />
          </div>

          {status === "error" && errMsg && (
            <div className="submit-error" style={{ gridColumn: "1 / -1" }}>
              {errMsg}
            </div>
          )}

          <div className="submit-actions">
            <div className="mono-sm">
              {status === "uploading" ? "UPLOADING SCORE…"
                : status === "sending" ? "RECORDING SUBMISSION…"
                : isUrgent ? "URGENT — WE'LL REPLY AS SOON AS POSSIBLE."
                : "WE REPLY WITHIN 24 HOURS."}
            </div>
            <button type="submit" className="btn-primary" disabled={uploading || validFiles.length === 0 || svc.length === 0 || (!deadline && !deadlineUnknown)}>
              <span>{uploading ? "Sending…" : "Submit"}</span>
              {!uploading && <span className="arrow"></span>}
            </button>
          </div>
        </form>

        <SiteFooter go={go} />
      </div>
    </div>);
}

const SUBMIT_STUDIO_EMAIL = "studio@mrmusicstudio.com";

window.SubmitPage = SubmitPage;
