// ADM-PROC-04 · Bulk create requirements (AMOMS Module 1)
// Admin Web · Procurement Manager · P1 · 1440×900
// Components: C-019 Tab bar · C-011 File upload tile · C-201 Data table (editable)
//             C-106 Inline error banner · C-108 Confirmation modal
// Registered as window.Pages.bulkCreate

const Ic4 = window.Icons;
const BUILT_04 = window.BUILT_PAGES;
const COLS_04 = ["Product", "Qty (kg)", "Rate", "Variance", "Delivery start", "Delivery end", "Response deadline", "Priority"];

// Base CSV-parsed rows. Errors injected per demo state.
const CSV_BASE = [
  { product: "Hass",      qty: "24000", rate: "96", variance: "10", start: "2026-05-20", end: "2026-05-27", deadline: "2026-05-18", priority: "Normal" },
  { product: "Fuerte",    qty: "12000", rate: "80", variance: "10", start: "2026-05-21", end: "2026-05-28", deadline: "2026-05-19", priority: "Normal" },
  { product: "Hass",      qty: "30000", rate: "95", variance: "8",  start: "2026-05-22", end: "2026-05-29", deadline: "2026-05-20", priority: "Urgent" },
  { product: "Local",     qty: "6000",  rate: "62", variance: "12", start: "2026-05-23", end: "2026-05-30", deadline: "2026-05-21", priority: "Normal" },
  { product: "Pinkerton", qty: "3500",  rate: "82", variance: "10", start: "2026-05-24", end: "2026-05-31", deadline: "2026-05-22", priority: "Normal" },
  { product: "Hass",      qty: "18000", rate: "93", variance: "10", start: "2026-05-25", end: "2026-06-01", deadline: "2026-05-23", priority: "Normal" },
];

// Returns a copy of CSV_BASE with per-row error maps depending on the demo state.
const buildPreview = (state) => {
  const rows = CSV_BASE.map(r => ({ ...r, errors: {} }));
  if (state === "valid" || state === "empty" || state === "parsing") return rows;
  if (state === "partial") {
    rows[1].qty = ""; rows[1].errors = { qty: "Quantity is required" };
    rows[3].deadline = "2026-05-30"; rows[3].errors = { deadline: "Must be before delivery start" };
    rows[4].product = "Haas"; rows[4].errors = { product: "Unknown variety \u201CHaas\u201D" };
    return rows;
  }
  if (state === "allerrors") {
    return rows.map((r, i) => ({
      ...r,
      product: i % 2 ? "Haas" : r.product,
      qty: i % 3 === 0 ? "" : "-5",
      errors: {
        ...(i % 2 ? { product: "Unknown variety" } : {}),
        qty: i % 3 === 0 ? "Quantity is required" : "Must be a positive number",
        ...(i === 2 ? { deadline: "Must be before delivery start" } : {}),
      },
    }));
  }
  return rows;
};

// ── File drop tile (C-011) ──
const DropTile = ({ onPick, fileName }) => {
  const [drag, setDrag] = useState(false);
  return (
    <label className={`bk-drop${drag ? " drag" : ""}`}
      onDragOver={(e) => { e.preventDefault(); setDrag(true); }}
      onDragLeave={() => setDrag(false)}
      onDrop={(e) => { e.preventDefault(); setDrag(false); onPick(e.dataTransfer.files?.[0]?.name || "requirements.csv"); }}>
      <input type="file" accept=".csv" style={{ display: "none" }} onChange={(e) => onPick(e.target.files?.[0]?.name || "requirements.csv")} />
      <span className="bk-drop-ic"><Ic4.Upload size={22} /></span>
      {fileName ? (
        <>
          <div className="bk-drop-title"><Ic4.File size={14} style={{ marginRight: 6, verticalAlign: "-2px" }} />{fileName}</div>
          <div className="muted" style={{ fontSize: 12 }}>Click to replace · or drop a new file</div>
        </>
      ) : (
        <>
          <div className="bk-drop-title">Drag CSV here or <span className="bk-link">browse</span></div>
          <div className="muted" style={{ fontSize: 12 }}>Accepts .csv only · max 5 MB · UTF-8</div>
        </>
      )}
    </label>
  );
};

const CellStatus = ({ ok }) => (
  ok ? <span className="proc-ic tone-success" style={{ width: 22, height: 22, borderRadius: 6 }}><Ic4.Check size={13} /></span>
     : <span className="proc-ic tone-soil" style={{ width: 22, height: 22, borderRadius: 6 }}><Ic4.Warning size={13} /></span>
);

// ── CSV preview table ──
const CsvPreview = ({ rows, parsing }) => {
  const [expanded, setExpanded] = useState(() => new Set());
  if (parsing) {
    return (
      <div className="card-body">
        {Array.from({ length: 5 }).map((_, i) => (
          <div key={i} style={{ display: "flex", gap: 16, padding: "10px 0", borderTop: i ? "1px solid var(--border)" : "none" }}>
            {[40, 14, 12, 14, 16, 16, 12].map((w, j) => <div key={j} className="sk" style={{ width: w + "%" }} />)}
          </div>
        ))}
        <div className="muted" style={{ textAlign: "center", fontSize: 12.5, marginTop: 14, display: "flex", alignItems: "center", justifyContent: "center", gap: 8 }}>
          <span className="cr-save-dot saving" style={{ width: 8, height: 8 }} />Parsing &amp; validating rows…
        </div>
      </div>
    );
  }
  return (
    <div className="card-body flush">
      <div className="tbl-wrap">
        <table className="tbl bk-tbl">
          <thead>
            <tr>
              <th style={{ width: 40 }}>Row</th>
              <th style={{ width: 44 }}></th>
              {COLS_04.map(c => <th key={c}>{c}</th>)}
            </tr>
          </thead>
          <tbody>
            {rows.map((r, i) => {
              const ok = Object.keys(r.errors).length === 0;
              const isOpen = expanded.has(i);
              return (
                <React.Fragment key={i}>
                  <tr className={ok ? "" : "bk-row-err"}>
                    <td className="muted">{i + 1}</td>
                    <td>
                      {ok ? <CellStatus ok /> : (
                        <button className="bk-expand" onClick={() => { const s = new Set(expanded); s.has(i) ? s.delete(i) : s.add(i); setExpanded(s); }} aria-label="Show errors">
                          <CellStatus ok={false} />
                        </button>
                      )}
                    </td>
                    {["product", "qty", "rate", "variance", "start", "end", "deadline", "priority"].map(key => (
                      <td key={key} className={r.errors[key] ? "bk-cell-err" : ""}>
                        {r[key] || <span className="muted">—</span>}
                      </td>
                    ))}
                  </tr>
                  {!ok && isOpen && (
                    <tr className="bk-err-detail">
                      <td colSpan={COLS_04.length + 2}>
                        <div className="bk-err-list">
                          {Object.entries(r.errors).map(([k, v]) => (
                            <span key={k} className="bk-err-chip"><Ic4.Warning size={11} />{v}</span>
                          ))}
                        </div>
                      </td>
                    </tr>
                  )}
                </React.Fragment>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
};

// ── Multi-row editable form ──
const EMPTY_ROW = { product: "", qty: "", rate: "", variance: "10", start: "", end: "", deadline: "", priority: "Normal" };
const rowValid = (r) => r.product && PRODUCTS_MR.includes(r.product) && Number(r.qty) > 0 && Number(r.rate) > 0 && r.start && r.end >= r.start && r.deadline && r.deadline < r.start;
const PRODUCTS_MR = ["Hass", "Fuerte", "Pinkerton", "Local"];

const MultiRow = ({ rows, setRows }) => {
  const upd = (i, key, val) => setRows(rs => rs.map((r, j) => j === i ? { ...r, [key]: val } : r));
  return (
    <div className="card-body flush">
      <div className="tbl-wrap">
        <table className="tbl bk-tbl bk-edit">
          <thead>
            <tr>
              <th style={{ width: 36 }}></th>
              {COLS_04.map(c => <th key={c}>{c}</th>)}
              <th style={{ width: 40 }}></th>
            </tr>
          </thead>
          <tbody>
            {rows.map((r, i) => {
              const ok = rowValid(r);
              return (
                <tr key={i}>
                  <td>{r.product || r.qty ? <CellStatus ok={ok} /> : <span className="muted" style={{ fontSize: 11 }}>—</span>}</td>
                  <td>
                    <select className="bk-input" value={r.product} onChange={(e) => upd(i, "product", e.target.value)}>
                      <option value="">Variety…</option>
                      {PRODUCTS_MR.map(p => <option key={p} value={p}>{p}</option>)}
                    </select>
                  </td>
                  <td><input className="bk-input num" inputMode="numeric" placeholder="0" value={r.qty} onChange={(e) => upd(i, "qty", e.target.value.replace(/[^\d]/g, ""))} /></td>
                  <td><input className="bk-input num" inputMode="numeric" placeholder="0" value={r.rate} onChange={(e) => upd(i, "rate", e.target.value.replace(/[^\d.]/g, ""))} /></td>
                  <td><input className="bk-input num" inputMode="numeric" placeholder="10" value={r.variance} onChange={(e) => upd(i, "variance", e.target.value.replace(/[^\d]/g, ""))} /></td>
                  <td><input type="date" className="bk-input" value={r.start} onChange={(e) => upd(i, "start", e.target.value)} /></td>
                  <td><input type="date" className="bk-input" value={r.end} onChange={(e) => upd(i, "end", e.target.value)} /></td>
                  <td><input type="date" className="bk-input" value={r.deadline} onChange={(e) => upd(i, "deadline", e.target.value)} /></td>
                  <td>
                    <select className="bk-input" value={r.priority} onChange={(e) => upd(i, "priority", e.target.value)}>
                      <option>Normal</option><option>Urgent</option>
                    </select>
                  </td>
                  <td>
                    <button className="btn btn-ghost btn-icon btn-sm" aria-label="Remove row" disabled={rows.length === 1}
                      onClick={() => setRows(rs => rs.filter((_, j) => j !== i))}><Ic4.Trash size={15} /></button>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
      <div style={{ padding: "12px 16px" }}>
        <Button size="sm" variant="outline" icon={Ic4.Plus} onClick={() => setRows(rs => [...rs, { ...EMPTY_ROW }])}>Add row</Button>
      </div>
    </div>
  );
};

// ── Page ──
const BulkCreate = ({ tweaks }) => {
  const toast = useToast();
  const bulkState = (tweaks && tweaks.bulkState) || "valid";
  const go = (file) => { if (BUILT_04.includes(file)) window.location.href = file; else toast({ title: `${file.replace(".html", "")} isn't part of this prototype`, tone: "danger" }); };

  const [tab, setTab] = useState("csv");
  const [fileName, setFileName] = useState(bulkState === "empty" ? "" : "amoms_week3_plan.csv");
  const [parsing, setParsing] = useState(bulkState === "parsing");
  const [mrRows, setMrRows] = useState([
    { product: "Hass", qty: "24000", rate: "96", variance: "10", start: "2026-05-20", end: "2026-05-27", deadline: "2026-05-18", priority: "Normal" },
    { ...EMPTY_ROW },
  ]);
  const [confirmCancel, setConfirmCancel] = useState(false);
  const [savedModal, setSavedModal] = useState(false);

  const previewRows = useMemo(() => buildPreview(bulkState), [bulkState]);
  const hasFile = !!fileName && bulkState !== "empty";

  // counts
  const csvValid = previewRows.filter(r => Object.keys(r.errors).length === 0).length;
  const csvInvalid = previewRows.length - csvValid;
  const mrValidCount = mrRows.filter(rowValid).length;
  const mrInvalid = mrRows.filter(r => (r.product || r.qty) && !rowValid(r)).length;

  const onCsv = tab === "csv";
  const showPreview = onCsv ? hasFile : true;
  const validCount = onCsv ? csvValid : mrValidCount;
  const invalidCount = onCsv ? csvInvalid : mrInvalid;
  const canSave = validCount > 0 && !(onCsv && parsing);
  const allErrors = onCsv && hasFile && csvValid === 0 && bulkState === "allerrors";

  const pickFile = (name) => { setFileName(name); setParsing(true); setTimeout(() => setParsing(false), 1100); };

  const saveAll = () => {
    if (!canSave) return;
    setSavedModal(true);
  };

  return (
    <div className="page cr-page">
      {/* Header */}
      <div className="cr-head">
        <button className="btn btn-ghost btn-icon" aria-label="Back" onClick={() => setConfirmCancel(true)}><Ic4.ChevronLeft size={18} /></button>
        <div className="cr-head-title">
          <h1 className="cr-title">Bulk create requirements</h1>
          <div className="cr-autosave"><span className="muted">Plan a whole procurement cycle in one operation</span></div>
        </div>
        <div className="cr-head-actions">
          <Button variant="outline" onClick={() => setConfirmCancel(true)}>Cancel</Button>
          <Button variant="primary" icon={Ic4.File} onClick={saveAll} className={!canSave ? "is-disabled" : ""}>Save all as drafts{validCount > 0 ? ` (${validCount})` : ""}</Button>
        </div>
      </div>

      {/* Tab switcher (C-019) */}
      <div style={{ marginBottom: 16 }}>
        <Tabs value={tab} onChange={setTab} options={[
          { value: "csv", label: "Upload CSV" },
          { value: "multi", label: "Multi-row form" },
        ]} />
      </div>

      {/* Validation summary banner (C-106) */}
      {showPreview && !parsing && (
        allErrors ? (
          <div className="alert alert-soil" style={{ marginBottom: 16 }}>
            <span className="alert-icon"><Ic4.XCircle size={16} /></span>
            <div className="alert-body">
              <div className="alert-title">No valid requirements</div>
              <div className="alert-desc">Every row has at least one error. Fix the issues below and try again — nothing will be saved until at least one row is valid.</div>
            </div>
          </div>
        ) : invalidCount > 0 ? (
          <div className="alert alert-warning" style={{ marginBottom: 16 }}>
            <span className="alert-icon"><Ic4.Warning size={16} /></span>
            <div className="alert-body">
              <div className="alert-title"><b>{validCount}</b> row{validCount !== 1 ? "s" : ""} valid · <b>{invalidCount}</b> with errors</div>
              <div className="alert-desc">Only the {validCount} valid row{validCount !== 1 ? "s" : ""} will be saved as drafts. Fix the highlighted cells to include the rest.</div>
            </div>
          </div>
        ) : validCount > 0 ? (
          <div className="alert alert-success" style={{ marginBottom: 16 }}>
            <span className="alert-icon"><Ic4.CheckCircle size={16} /></span>
            <div className="alert-body">
              <div className="alert-title">All {validCount} rows valid</div>
              <div className="alert-desc">Ready to save as drafts. Each becomes its own requirement — broadcast happens individually afterwards.</div>
            </div>
          </div>
        ) : null
      )}

      {onCsv ? (
        <>
          {/* Template + dropzone */}
          <Card style={{ marginBottom: 16 }}>
            <div className="bk-upload-grid">
              <div>
                <div className="card-title" style={{ marginBottom: 4 }}>1 · Start from the template</div>
                <div className="card-desc" style={{ marginBottom: 12 }}>Download the CSV template — it includes column headers and a sample row. Dates in ISO format (YYYY-MM-DD); rate is a plain number.</div>
                <Button variant="outline" icon={Ic4.Download} onClick={() => toast({ title: "Template downloaded", desc: "amoms_requirement_template.csv" })}>Download template</Button>
              </div>
              <div>
                <div className="card-title" style={{ marginBottom: 4 }}>2 · Upload your file</div>
                <DropTile onPick={pickFile} fileName={hasFile ? fileName : ""} />
              </div>
            </div>
          </Card>

          {hasFile && (
            <Card>
              <CardHead title="Preview" desc={parsing ? "Validating…" : `${previewRows.length} rows parsed · click a flagged row to see details`} />
              <CsvPreview rows={previewRows} parsing={parsing} />
            </Card>
          )}
        </>
      ) : (
        <Card>
          <CardHead title="Requirements" desc="Each row becomes its own draft. Validation runs as you type." />
          <MultiRow rows={mrRows} setRows={setMrRows} />
        </Card>
      )}

      {/* Cancel confirm (C-108) */}
      <Modal open={confirmCancel} onClose={() => setConfirmCancel(false)} title="Discard bulk entry?" sub="Unsaved rows will be lost."
        footer={<>
          <Button variant="outline" onClick={() => setConfirmCancel(false)}>Keep editing</Button>
          <Button variant="destructive" onClick={() => go("ADM-PROC-02.html")}>Discard</Button>
        </>}>
        <div className="muted" style={{ fontSize: 13 }}>You'll return to the requirement list. Nothing entered here has been saved yet.</div>
      </Modal>

      {/* Saved confirmation (C-108) */}
      <Modal open={savedModal} onClose={() => setSavedModal(false)} title={`${validCount} draft${validCount !== 1 ? "s" : ""} created`} sub="Drafts are not broadcast automatically."
        footer={<>
          <Button variant="outline" onClick={() => setSavedModal(false)}>Create more</Button>
          <Button variant="primary" icon={Ic4.ArrowRight} onClick={() => go("ADM-PROC-02.html")}>Go to requirement list</Button>
        </>}>
        <div className="row" style={{ gap: 12, alignItems: "flex-start" }}>
          <span className="proc-ic tone-success"><Ic4.CheckCircle size={16} /></span>
          <div className="muted" style={{ fontSize: 13, lineHeight: 1.5 }}>
            {validCount} requirement{validCount !== 1 ? "s were" : " was"} saved as draft{validCount !== 1 ? "s" : ""} and highlighted in the list. Broadcast each one individually when you're ready — this forces a review step before farmers are notified.
          </div>
        </div>
      </Modal>
    </div>
  );
};

window.Pages = Object.assign(window.Pages || {}, { bulkCreate: BulkCreate });
