/* global React, window */
const {
  LogoGoat, SignOff, getBrowserLocation, reverseGeocode, fetchWeather, LGStore,
  IcoLedger, IcoPencil, IcoEnvelope, IcoLocation, IcoX, IcoCheck, IcoTrash,
  StampPicker, TagPicker
} = window;

/*
 * The Ritual — focused new-entry overlay.
 * Save-as picker at the end: Goat Note (gold), Draft (sage), Letter (wax).
 * Geolocation + manual location input.
 */

function Ritual({ onClose }) {
  const [step, setStep] = React.useState(0);
  const [title, setTitle] = React.useState("");
  const [location, setLocation] = React.useState("");
  const [coords, setCoords] = React.useState("");
  const [weather, setWeather] = React.useState("");
  const [to, setTo] = React.useState("");
  const [body, setBody] = React.useState("");
  const [tags, setTags] = React.useState([]);
  const [heroImage, setHeroImage] = React.useState("");
  const [geoBusy, setGeoBusy] = React.useState(false);
  const [filed, setFiled] = React.useState(null); // {kind}
  const taRef = React.useRef(null);

  const onPickHero = async (e) => {
    const f = e.target.files && e.target.files[0];
    if (!f) return;
    try {
      const url = window.processUploadedImage
        ? await window.processUploadedImage(f)
        : await new Promise((res, rej) => {
            const r = new FileReader();
            r.onload = () => res(r.result);
            r.onerror = () => rej(new Error("Couldn't read that file."));
            r.readAsDataURL(f);
          });
      setHeroImage(url);
    } catch (err) {
      alert(err.message || "Couldn't use that image.");
    }
    // reset so picking the same file again still fires onChange
    e.target.value = "";
  };

  // Word count, derived from the body. Used for the field card.
  const wordCount = React.useMemo(
    () => body.split(/\s+/).filter(Boolean).length,
    [body]
  );

  const today = React.useMemo(() => {
    const d = new Date();
    const months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
    return `${months[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`;
  }, []);

  React.useEffect(() => {
    const t1 = setTimeout(() => setStep(1), 300);
    const t2 = setTimeout(() => setStep(2), 1100);
    const t3 = setTimeout(() => setStep(3), 1900);
    return () => { clearTimeout(t1); clearTimeout(t2); clearTimeout(t3); };
  }, []);

  React.useEffect(() => {
    if (step === 3 && taRef.current) setTimeout(() => taRef.current.focus(), 200);
  }, [step]);

  const fetchGeo = async () => {
    setGeoBusy(true);
    const r = await getBrowserLocation();
    if (!r) {
      setGeoBusy(false);
      alert("Couldn't read your location. Type one in by hand.");
      return;
    }
    setCoords(r.coords);
    // Reverse-geocode to a human-readable place + fetch current weather
    // in parallel. Both fall back to "n/a" gracefully on error.
    const [place, wx] = await Promise.all([
      reverseGeocode ? reverseGeocode(r.lat, r.lon) : Promise.resolve("n/a"),
      fetchWeather   ? fetchWeather(r.lat, r.lon)   : Promise.resolve("n/a")
    ]);
    setLocation(place);
    setWeather(wx);
    setGeoBusy(false);
  };

  const fileAs = (kind) => {
    const item = {
      kind,
      title: title || (kind === "letters" ? `To ${to || "—"}` : "Untitled"),
      to,
      date: today,
      location: location.trim() || "n/a",
      coords:   coords.trim()   || "n/a",
      weather:  weather.trim()  || "n/a",
      wordCount,
      body,
      tags,
      heroImage,
      preview: body.slice(0, 80).replace(/\s+/g, " ") + (body.length > 80 ? "…" : "")
    };
    LGStore.add(kind, item);
    LGStore.clearActiveDraft();
    setFiled({ kind });
    setStep(4);
    setTimeout(() => onClose(), 1800);
  };

  // Insert a {{sketch:kind}} marker into the body — same behavior as the Field
  // Desk Write mode, so the published note renders inline plates the same way.
  const insertStamp = (id) => {
    setBody(b => b + (b && !b.endsWith("\n") ? "\n\n" : "") + `{{sketch:${id}}}\n\n`);
  };

  const SAVE = [
    { kind: "entries", label: "Goat Note", hint: "publish",  Icon: IcoLedger,   color: "var(--cat-gold)" },
    { kind: "drafts",  label: "Draft",     hint: "keep working", Icon: IcoPencil, color: "var(--cat-sage)" },
    { kind: "letters", label: "Letter",    hint: "to someone", Icon: IcoEnvelope, color: "var(--cat-wax)" },
  ];

  return (
    <>
      <div className="lamplight" />
      <div className="ritual-overlay" onClick={(e) => { if (e.target.classList.contains('ritual-overlay') && step >= 3) onClose(); }}>
        <div className="ritual-page" style={step === 4 ? { animation: 'page-rise 700ms reverse forwards' } : undefined}>
          <div style={{ padding: '24px 32px 8px', borderBottom: '1px solid var(--rule)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', background: 'rgba(0,0,0,0.02)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              <LogoGoat size={32} tone="gold" />
              <div>
                <div className="eyebrow">Field Desk · New Entry</div>
                <div style={{ fontFamily: 'var(--f-mono)', fontSize: 11, letterSpacing: '0.2em', color: 'var(--ink-faint)', textTransform: 'uppercase', marginTop: 2 }}>
                  {step < 2 ? "preparing the page…" : step < 3 ? "stamping the date…" : step < 4 ? "ready · take your time" : "filing entry…"}
                </div>
              </div>
            </div>
            <button
              onClick={onClose}
              className="lg-esc-btn"
              title="Discard and close"
              aria-label="Discard and close"
            >
              {IcoTrash ? <IcoTrash size={16} /> : null}
              <span>esc</span>
            </button>
          </div>

          <div className="ritual-page__inner">
            {step >= 2 && (
              <div className="ritual-stamp">
                <span className="stamp">{today.toUpperCase()}</span>
              </div>
            )}

            <div style={{
              marginBottom: 28,
              background: 'var(--paper)',
              position: 'relative',
              zIndex: 1,
              paddingBottom: 16,
              borderBottom: '1px solid var(--rule)',
              opacity: step >= 2 ? 1 : 0,
              transition: 'opacity 600ms'
            }}>
              <div style={{ display: 'grid', gridTemplateColumns: '90px 1fr', gap: 12, padding: '6px 0', borderBottom: '1px dashed var(--rule)' }}>
                <span className="eyebrow">Date</span>
                <span style={{ fontFamily: 'var(--f-type)', fontSize: 16 }}>{today}</span>
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '90px 1fr', gap: 12, padding: '6px 0', borderBottom: '1px dashed var(--rule)', alignItems: 'center' }}>
                <span className="eyebrow">Loc.</span>
                <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
                  <input className="ritual-line" value={location} onChange={e => setLocation(e.target.value)} placeholder="auto-fills with your location, or type one" disabled={step < 3} style={{ borderBottom: 'none', flex: 1 }} />
                  <button onClick={fetchGeo} disabled={step < 3 || geoBusy} className="btn btn--ghost btn--sm" title="Use my location">
                    <IcoLocation size={14} /> <span style={{marginLeft:4}}>{geoBusy ? "Locating…" : "Use my location"}</span>
                  </button>
                </div>
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '90px 1fr', gap: 12, padding: '6px 0', borderBottom: '1px dashed var(--rule)' }}>
                <span className="eyebrow">Coord.</span>
                <input className="ritual-line" value={coords} onChange={e => setCoords(e.target.value)} placeholder="29.2498° N, 103.2502° W" disabled={step < 3} style={{ borderBottom: 'none', fontFamily: 'var(--f-mono)' }} />
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '90px 1fr', gap: 12, padding: '6px 0', borderBottom: '1px dashed var(--rule)' }}>
                <span className="eyebrow">Wx.</span>
                <input className="ritual-line" value={weather} onChange={e => setWeather(e.target.value)} placeholder="auto-fills with your location" disabled={step < 3} style={{ borderBottom: 'none' }} />
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '90px 1fr', gap: 12, padding: '6px 0', borderBottom: '1px dashed var(--rule)' }}>
                <span className="eyebrow">Title</span>
                <input className="ritual-line" value={title} onChange={e => setTitle(e.target.value)} placeholder="what are you calling this?" disabled={step < 3} style={{ borderBottom: 'none' }} />
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '90px 1fr', gap: 12, padding: '6px 0', borderBottom: '1px dashed var(--rule)', alignItems: 'center' }}>
                <span className="eyebrow">Words</span>
                <span style={{ fontFamily: 'var(--f-type)', fontSize: 16, color: 'var(--ink-soft)' }}>
                  {wordCount} {wordCount === 1 ? 'word' : 'words'} · auto
                </span>
              </div>
              {/* Optional hero photo — disposable-camera vibe on the published note */}
              <div style={{ display: 'grid', gridTemplateColumns: '90px 1fr', gap: 12, padding: '6px 0', borderBottom: '1px dashed var(--rule)', alignItems: 'center' }}>
                <span className="eyebrow">Photo</span>
                <div style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
                  {heroImage ? (
                    <>
                      <img src={heroImage} alt="" style={{ width: 60, height: 40, objectFit: 'cover', border: '1px solid var(--rule)' }} />
                      <button onClick={() => setHeroImage("")} className="btn btn--ghost btn--sm" disabled={step < 3}>Remove</button>
                    </>
                  ) : (
                    <label className={"btn btn--ghost btn--sm" + (step < 3 ? " disabled" : "")} style={{ cursor: step < 3 ? 'not-allowed' : 'pointer', pointerEvents: step < 3 ? 'none' : 'auto', opacity: step < 3 ? 0.5 : 1 }}>
                      Upload a photo
                      <input type="file" accept="image/*" onChange={onPickHero} style={{ display: 'none' }} />
                    </label>
                  )}
                  <span style={{ fontFamily: 'var(--f-serif)', fontStyle: 'italic', fontSize: 13, color: 'var(--ink-faint)' }}>
                    optional · disposable-camera vibe applied automatically
                  </span>
                </div>
              </div>

              {/* Tags — same picker the Field Desk uses */}
              {TagPicker && (
                <div style={{
                  opacity: step >= 3 ? 1 : 0.45,
                  pointerEvents: step >= 3 ? 'auto' : 'none',
                  transition: 'opacity 400ms'
                }}>
                  <TagPicker value={tags} onChange={setTags} />
                </div>
              )}
            </div>

            <div style={{ opacity: step >= 3 ? 1 : 0, transition: 'opacity 700ms 200ms' }}>
              <div style={{ marginBottom: 12, background: 'var(--paper)', position: 'relative', zIndex: 1, paddingTop: 4, paddingBottom: 4 }}>
                <span className="eyebrow">The entry</span>
              </div>
              <textarea
                ref={taRef}
                className="ritual-input"
                placeholder="It started the way most things start out here…"
                value={body}
                onChange={(e) => setBody(e.target.value)}
                disabled={step < 3 || step === 4}
              />
              {/* Same stamp picker as the Field Desk Write mode — drops a
                  {{sketch:kind}} marker into the body, rendered inline on read. */}
              {StampPicker && (
                <div style={{
                  marginTop: 10,
                  display: 'flex',
                  justifyContent: 'flex-end',
                  alignItems: 'center',
                  opacity: step >= 3 && step < 4 ? 1 : 0.45,
                  pointerEvents: step >= 3 && step < 4 ? 'auto' : 'none',
                  transition: 'opacity 400ms'
                }}>
                  <StampPicker onPick={insertStamp} />
                </div>
              )}
            </div>

            {step === 4 && filed && (
              <div style={{ position: 'absolute', inset: 0, background: 'rgba(239, 230, 207, 0.94)', display: 'grid', placeItems: 'center', textAlign: 'center' }}>
                <div>
                  <div className="stamp stamp--ink" style={{ fontSize: 18, padding: '10px 18px', transform: 'rotate(-4deg)' }}>
                    FILED · {filed.kind === "entries" ? "GOAT NOTE" : filed.kind === "letters" ? "LETTER" : "DRAFT"}
                  </div>
                  <div style={{ marginTop: 18 }}><SignOff size={42} /></div>
                </div>
              </div>
            )}
          </div>

          {/* Save-as picker bar */}
          <div className="ritual-page__bar ritual-page__bar--save">
            <div style={{ fontFamily: 'var(--f-mono)', fontSize: 10, letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--ink-faint)' }}>
              {body.length} chars · {body.split(/\s+/).filter(Boolean).length} words
            </div>
            <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
              <span className="eyebrow" style={{marginRight: 4}}>Save as</span>
              {SAVE.map(s => {
                const Icon = s.Icon;
                return (
                  <button
                    key={s.kind}
                    onClick={() => fileAs(s.kind)}
                    disabled={step < 3 || step === 4 || !body.trim()}
                    className="saveas__btn"
                    style={{ '--cat-color': s.color }}
                  >
                    <Icon size={16} color={s.color} />
                    <span>{s.label}</span>
                    <span className="saveas__hint">{s.hint}</span>
                  </button>
                );
              })}
              <button className="btn btn--ghost btn--sm lg-discard-btn" onClick={onClose} title="Discard this entry">
                {IcoTrash ? <IcoTrash size={14} /> : null}
                <span style={{ marginLeft: 6 }}>Discard</span>
              </button>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

window.Ritual = Ritual;
