/* ============================================================================
   VAULT — passports, visa, tickets, hotels, insurance. Locked until tapped.
   Seed docs from TRIP.documents + user-added docs (tickets/hotels/etc).
   ============================================================================ */
function VaultScreen({ go }) {
  const T = window.TRIP;
  const store = useDocs();
  const [locked, setLocked] = React.useState(true);
  const [adding, setAdding] = React.useState(false);
  const [viewDoc, setViewDoc] = React.useState(null); // document being previewed

  const total = store.list.length;

  return (
    <div style={{ minHeight: "100%", background: "var(--colorNeutralBackground2)" }}>
      {/* custom top bar */}
      <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "16px 16px 14px",
        background: "var(--colorNeutralBackground1)", borderBottom: "1px solid var(--colorNeutralStroke2)" }}>
        <button onClick={() => (adding ? setAdding(false) : go("home"))} aria-label="back" style={{ width: 36, height: 36, borderRadius: 10, border: "1px solid var(--colorNeutralStroke2)", background: "var(--colorNeutralBackground1)", display: "inline-flex", alignItems: "center", justifyContent: "center", cursor: "pointer" }}>
          <Icon name={adding ? "dismiss" : "chevron_left"} size={20} color="var(--colorNeutralForeground1)" />
        </button>
        <div style={{ flex: 1 }}>
          <Serif size={20} weight={600}>{adding ? "Add document" : "Document vault"}</Serif>
        </div>
        {!adding && !locked && (
          <button onClick={() => setAdding(true)} style={{ display: "inline-flex", alignItems: "center", gap: 5, padding: "8px 12px", borderRadius: 11, border: "none", background: "var(--color-grape)", color: "#fff", fontWeight: 600, fontSize: 13.5, cursor: "pointer", fontFamily: "var(--fontFamilyBase)" }}>
            <Icon name="add" size={16} color="#fff" /> Add
          </button>
        )}
        {(adding || locked) && <Icon name={locked ? "lock_closed" : "lock_open"} size={20} color={locked ? "var(--color-grape)" : "var(--colorStatusSuccessForeground1)"} filled />}
      </div>

      <div style={{ position: "relative", padding: "16px 16px 8px" }}>
        {adding ? (
          <AddDocForm onCancel={() => setAdding(false)} onSave={() => setAdding(false)} />
        ) : locked ? (
          <LockPanel total={total} seed={store.list} onUnlock={() => setLocked(false)} />
        ) : (
          <>
            <div style={{ display: "flex", alignItems: "center", gap: 11, padding: "12px 14px", borderRadius: 14,
              background: "rgba(113,96,232,0.08)", border: "1px solid rgba(113,96,232,0.2)", marginBottom: 16 }}>
              <Icon name="shield_keyhole" size={22} filled color="var(--color-grape)" />
              <div style={{ fontSize: 12.5, color: "var(--colorNeutralForeground2)", lineHeight: 1.35 }}>
                Passports, visas, tickets &amp; bookings — shared with the trip, ready offline.
              </div>
            </div>

            {store.list.length > 0 ? (
              <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
                {store.list.map((d) => <DocCard key={d.id} doc={d} onOpen={setViewDoc} onDelete={() => { fileStore.remove(d.id); docStore.remove(d.id); }} />)}
              </div>
            ) : (
              <div style={{ textAlign: "center", color: "var(--colorNeutralForeground3)", fontSize: 13, padding: "10px 0 4px" }}>No documents yet — add your passports, visas and bookings below.</div>
            )}

            <button onClick={() => setAdding(true)} style={{
              width: "100%", marginTop: 12, padding: "14px", borderRadius: 14, cursor: "pointer",
              border: "1.5px dashed var(--colorNeutralStroke1)", background: "transparent",
              display: "flex", alignItems: "center", justifyContent: "center", gap: 8,
              color: "var(--color-grape)", fontWeight: 600, fontSize: 14, fontFamily: "var(--fontFamilyBase)",
            }}>
              <Icon name="add_circle" size={18} filled color="var(--color-grape)" /> Add a ticket, hotel or document
            </button>
          </>
        )}
      </div>

      {viewDoc && <DocViewer doc={viewDoc} onClose={() => setViewDoc(null)} />}
    </div>
  );
}

function LockPanel({ total, seed, onUnlock }) {
  return (
    <div style={{ marginTop: 36, display: "flex", flexDirection: "column",
      alignItems: "center", justifyContent: "center", gap: 14, padding: "24px 24px 48px", textAlign: "center" }}>
      <div style={{ width: 76, height: 76, borderRadius: "50%", background: "var(--color-grape)",
        display: "flex", alignItems: "center", justifyContent: "center", boxShadow: "var(--shadow16)" }}>
        <Icon name="lock_closed" size={34} filled color="#fff" />
      </div>
      <div>
        <div style={{ fontSize: 16, fontWeight: 700, color: "var(--colorNeutralForeground1)" }}>{total} documents secured</div>
        <div style={{ fontSize: 13, color: "var(--colorNeutralForeground3)", marginTop: 3 }}>Unlock to view passports, tickets &amp; bookings</div>
      </div>
      <Btn kind="primary" icon="fingerprint" onClick={onUnlock} style={{ background: "var(--color-grape)" }}>Unlock vault</Btn>
      <div style={{ display: "flex", flexDirection: "column", gap: 8, width: "100%", marginTop: 18, opacity: 0.5 }}>
        {seed.slice(0, 3).map((d) => (
          <div key={d.id} style={{ height: 14, borderRadius: 7, background: "var(--colorNeutralBackground4)" }} />
        ))}
      </div>
    </div>
  );
}

function fileExt(f) {
  if (!f) return "";
  const n = (f.name || "").split(".").pop();
  if (n && n.length <= 5) return n.toUpperCase();
  if ((f.type || "").includes("pdf")) return "PDF";
  return "FILE";
}
const isImg = (f) => !!f && (f.type || "").startsWith("image/");

function DocCard({ doc, onDelete, onOpen }) {
  const hasFile = !!doc.file_path;
  const f = hasFile ? { name: doc.file_name, type: doc.file_type } : null;
  const inputRef = React.useRef(null);
  const pickFile = (files) => { const file = files && files[0]; if (file) window.fileStore.put(doc.id, file); };
  const thumbTap = () => { if (hasFile) onOpen && onOpen(doc); else inputRef.current && inputRef.current.click(); };

  return (
    <div style={{ background: "var(--colorNeutralBackground1)", borderRadius: 16, overflow: "hidden",
      border: "1px solid var(--colorNeutralStroke2)", boxShadow: "var(--shadow2)" }}>
      <div style={{ height: 4, background: doc.accent }} />
      <div style={{ display: "flex", gap: 13, padding: 14 }}>
        {/* attachment thumbnail (any file type) */}
        <input ref={inputRef} type="file" hidden onChange={(e) => { pickFile(e.target.files); e.target.value = ""; }} />
        <button onClick={thumbTap} aria-label={hasFile ? "open document" : "attach file"} style={{
          flexShrink: 0, width: 74, height: 96, borderRadius: 8, overflow: "hidden", padding: 0, cursor: "pointer",
          background: "var(--colorNeutralBackground3)", border: "1px solid var(--colorNeutralStroke2)",
          display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 4 }}>
          {hasFile ? (
            <>
              <Icon name={isImg(f) ? "image_multiple" : "document"} size={26} color={doc.accent} filled />
              <span style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: "0.04em", color: "var(--colorNeutralForeground3)" }}>{fileExt(f)}</span>
            </>
          ) : (
            <>
              <Icon name="add_circle" size={22} color="var(--colorNeutralForeground4)" />
              <span style={{ fontSize: 10, fontWeight: 600, color: "var(--colorNeutralForeground4)" }}>Add file</span>
            </>
          )}
        </button>

        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 7 }}>
            <span style={{ width: 8, height: 8, borderRadius: "50%", background: doc.accent, flexShrink: 0 }} />
            <span style={{ fontSize: 15, fontWeight: 700, color: "var(--colorNeutralForeground1)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{doc.kind}</span>
          </div>
          <div style={{ fontSize: 12.5, color: "var(--colorNeutralForeground3)", marginTop: 2 }}>{doc.holder}</div>
          {doc.number && <div style={{ fontFamily: "var(--fontFamilyMonospace)", fontSize: 13, color: "var(--colorNeutralForeground2)", marginTop: 8, letterSpacing: "0.02em", wordBreak: "break-word" }}>{doc.number}</div>}
          {doc.expiry && (
            <div style={{ display: "flex", alignItems: "center", gap: 6, marginTop: 6 }}>
              <Icon name="calendar_ltr" size={13} color="var(--colorNeutralForeground4)" />
              <span style={{ fontSize: 12, color: "var(--colorNeutralForeground3)" }}>{doc.expiry}</span>
            </div>
          )}
          {/* actions */}
          <div style={{ display: "flex", gap: 14, marginTop: 10 }}>
            {hasFile ? (
              <>
                <button onClick={() => onOpen && onOpen(doc)} style={linkBtn}>Open</button>
                <button onClick={() => inputRef.current && inputRef.current.click()} style={linkBtn}>Replace</button>
              </>
            ) : (
              <button onClick={() => inputRef.current && inputRef.current.click()} style={linkBtn}>Attach file (PDF, image…)</button>
            )}
          </div>
        </div>

        {onDelete && (
          <button onClick={onDelete} aria-label="delete document" style={{ alignSelf: "flex-start", border: "none", background: "none", cursor: "pointer", padding: 2 }}>
            <Icon name="delete" size={18} color="var(--colorNeutralForeground4)" />
          </button>
        )}
      </div>
    </div>
  );
}

const linkBtn = {
  border: "none", background: "none", padding: 0, cursor: "pointer",
  color: "var(--color-grape)", fontWeight: 600, fontSize: 12.5, fontFamily: "var(--fontFamilyBase)",
};

/* Full-screen in-app document viewer with download + open-in-tab. */
function DocViewer({ doc, onClose }) {
  const { loading, file, url } = window.useFile(doc);
  const pdf = file && (file.type || "").includes("pdf");
  const image = isImg(file);

  return (
    <div style={{ position: "fixed", inset: 0, zIndex: 1000, background: "rgba(8,12,14,0.92)",
      display: "flex", flexDirection: "column", WebkitBackdropFilter: "blur(6px)", backdropFilter: "blur(6px)" }}>
      <div style={{ flexShrink: 0, display: "flex", alignItems: "center", gap: 10, padding: "max(env(safe-area-inset-top),12px) 14px 12px",
        background: "rgba(0,0,0,0.35)", color: "#fff" }}>
        <button onClick={onClose} aria-label="close" style={{ width: 36, height: 36, borderRadius: 10, border: "none", cursor: "pointer",
          background: "rgba(255,255,255,0.14)", color: "#fff", display: "inline-flex", alignItems: "center", justifyContent: "center" }}>
          <Icon name="dismiss" size={18} color="#fff" />
        </button>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 14, fontWeight: 700, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{doc.kind}</div>
          <div style={{ fontSize: 11.5, color: "rgba(255,255,255,0.65)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{(file && file.name) || doc.holder}</div>
        </div>
        {url && <a href={url} target="_blank" rel="noopener noreferrer" style={viewerTextLink}>Open</a>}
        {url && <a href={url} download={(file && file.name) || doc.kind} style={{ ...viewerTextLink, background: "var(--color-grape)" }}>Download</a>}
      </div>

      <div style={{ flex: 1, minHeight: 0, display: "flex", alignItems: "center", justifyContent: "center", overflow: "auto", padding: image ? 12 : 0 }}>
        {loading ? (
          <span style={{ color: "rgba(255,255,255,0.7)", fontSize: 13 }}>Loading…</span>
        ) : !file ? (
          <span style={{ color: "rgba(255,255,255,0.7)", fontSize: 13 }}>No file attached.</span>
        ) : image ? (
          <img src={url} alt={file.name} style={{ maxWidth: "100%", maxHeight: "100%", objectFit: "contain", borderRadius: 6 }} />
        ) : pdf ? (
          <iframe title={file.name} src={url} style={{ width: "100%", height: "100%", border: "none", background: "#fff" }} />
        ) : (
          <div style={{ textAlign: "center", color: "#fff", padding: 24 }}>
            <Icon name="document" size={48} color="rgba(255,255,255,0.85)" filled />
            <div style={{ fontSize: 14, fontWeight: 700, marginTop: 12 }}>{file.name}</div>
            <div style={{ fontSize: 12.5, color: "rgba(255,255,255,0.6)", marginTop: 4 }}>Preview not supported for this file type.</div>
            <a href={url} download={file.name} style={{ display: "inline-block", marginTop: 16, padding: "10px 18px", borderRadius: 11, background: "var(--color-grape)", color: "#fff", fontWeight: 600, fontSize: 13.5, textDecoration: "none" }}>Download</a>
          </div>
        )}
      </div>
    </div>
  );
}

const viewerTextLink = {
  flexShrink: 0, textDecoration: "none", padding: "8px 13px", borderRadius: 10,
  background: "rgba(255,255,255,0.14)", color: "#fff", fontSize: 13, fontWeight: 600,
  fontFamily: "var(--fontFamilyBase)", display: "inline-flex", alignItems: "center",
};

function AddDocForm({ onCancel, onSave }) {
  const [kindIdx, setKindIdx] = React.useState(0);
  const [title, setTitle] = React.useState("");
  const [number, setNumber] = React.useState("");
  const [date, setDate] = React.useState("");
  const [file, setFile] = React.useState(null); // raw File (any type)
  const [imgPreview, setImgPreview] = React.useState(null);
  const fileRef = React.useRef(null);
  const k = DOC_KINDS[kindIdx];
  const valid = title.trim().length > 0;

  const pick = (files) => {
    const f = files && files[0];
    if (!f) return;
    setFile(f);
    if (f.type.startsWith("image/")) {
      const u = URL.createObjectURL(f);
      setImgPreview((prev) => { if (prev) URL.revokeObjectURL(prev); return u; });
    } else {
      setImgPreview((prev) => { if (prev) URL.revokeObjectURL(prev); return null; });
    }
  };

  const save = async () => {
    if (!valid) return;
    const id = "ud" + Date.now();
    // create the row first, then attach the file (file upload patches the row)
    await window.db.documents.upsert({ id, kind: k.kind, accent: k.accent, holder: title.trim(), number: number.trim(), expiry: date.trim() });
    if (file) await window.fileStore.put(id, file);
    onSave();
  };

  const vinput = {
    width: "100%", boxSizing: "border-box", padding: "12px 14px", borderRadius: 12,
    border: "1px solid var(--colorNeutralStroke1)", background: "var(--colorNeutralBackground1)", fontSize: 15,
    fontFamily: "var(--fontFamilyBase)", outline: "none", color: "var(--colorNeutralForeground1)",
  };
  const lbl = { fontSize: 12, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--colorNeutralForeground3)", marginBottom: 8 };

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <div>
        <div style={lbl}>Type</div>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
          {DOC_KINDS.map((d, i) => (
            <button key={d.kind} onClick={() => setKindIdx(i)} style={{
              display: "inline-flex", alignItems: "center", gap: 6, padding: "8px 13px", borderRadius: 999, cursor: "pointer",
              fontFamily: "var(--fontFamilyBase)", fontSize: 13, fontWeight: 600,
              border: kindIdx === i ? `1.5px solid ${d.accent}` : "1px solid var(--colorNeutralStroke1)",
              background: kindIdx === i ? "var(--colorNeutralBackground1)" : "#fff",
              color: kindIdx === i ? "var(--colorNeutralForeground1)" : "var(--colorNeutralForeground2)",
            }}>
              <Icon name={d.icon} size={15} color={d.accent} filled={kindIdx === i} /> {d.kind}
            </button>
          ))}
        </div>
      </div>

      <div>
        <div style={lbl}>Name / details</div>
        <input value={title} onChange={(e) => setTitle(e.target.value)} placeholder="e.g. Cu Chi Tunnels tour · 4 pax" style={vinput} />
      </div>
      <div>
        <div style={lbl}>Booking / reference no.</div>
        <input value={number} onChange={(e) => setNumber(e.target.value)} placeholder="e.g. Booking #VN-2241" style={vinput} />
      </div>
      <div>
        <div style={lbl}>Date</div>
        <input value={date} onChange={(e) => setDate(e.target.value)} placeholder="e.g. Jun 18, 9:00am" style={vinput} />
      </div>

      <div>
        <div style={lbl}>Attachment (optional · PDF, image or any file)</div>
        <input ref={fileRef} type="file" hidden onChange={(e) => { pick(e.target.files); e.target.value = ""; }} />
        {file ? (
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            {imgPreview ? (
              <img src={imgPreview} alt="" style={{ width: 84, height: 110, objectFit: "cover", borderRadius: 10, border: "1px solid var(--colorNeutralStroke2)" }} />
            ) : (
              <div style={{ width: 84, height: 110, borderRadius: 10, background: "var(--colorNeutralBackground3)", border: "1px solid var(--colorNeutralStroke2)",
                display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 5 }}>
                <Icon name="document" size={28} color="var(--color-grape)" filled />
                <span style={{ fontSize: 9.5, fontWeight: 800, color: "var(--colorNeutralForeground3)" }}>{fileExt(file)}</span>
              </div>
            )}
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 13, color: "var(--colorNeutralForeground1)", fontWeight: 600, wordBreak: "break-word" }}>{file.name}</div>
              <div style={{ display: "flex", gap: 14, marginTop: 8 }}>
                <button onClick={() => fileRef.current && fileRef.current.click()} style={linkBtn}>Replace</button>
                <button onClick={() => { setFile(null); setImgPreview((prev) => { if (prev) URL.revokeObjectURL(prev); return null; }); }} style={linkBtn}>Remove</button>
              </div>
            </div>
          </div>
        ) : (
          <button onClick={() => fileRef.current && fileRef.current.click()} style={{
            width: "100%", padding: "16px", borderRadius: 12, cursor: "pointer", background: "var(--colorNeutralBackground3)",
            border: "1.5px dashed var(--colorNeutralStroke1)", display: "flex", alignItems: "center", justifyContent: "center", gap: 8,
            color: "var(--colorNeutralForeground3)", fontFamily: "var(--fontFamilyBase)", fontSize: 13, fontWeight: 600,
          }}>
            <Icon name="add_circle" size={20} color="var(--color-grape)" /> Choose a file
          </button>
        )}
      </div>

      <div style={{ display: "flex", gap: 10, marginTop: 4 }}>
        <Btn kind="ghost" onClick={onCancel} full>Cancel</Btn>
        <Btn kind={valid ? "primary" : "soft"} onClick={save} full style={{ background: valid ? "var(--color-grape)" : undefined, opacity: valid ? 1 : 0.5 }}>Save document</Btn>
      </div>
    </div>
  );
}

Object.assign(window, { VaultScreen });
