// app.jsx — main entry, state, layout, tweaks

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#2F6F5C",
  "density": "regular",
  "showPreview": true,
  "requireContract": false,
  "showRoadblock": true,
  "headline": "Schedule a job"
}/*EDITMODE-END*/;

const ACCENT_PRESETS = {
  "#2F6F5C": { deep: "#1F4A3D", tint: "#E3EFE9", name: "Sage" },
  "#C24E2E": { deep: "#8C3414", tint: "#FBE6DD", name: "Terracotta" },
  "#3B82C4": { deep: "#235B92", tint: "#DEEAF5", name: "Bay" },
  "#7A4F2A": { deep: "#52311A", tint: "#EFE3D2", name: "Walnut" },
};

function todayISO() {
  const d = new Date();
  return d.toISOString().slice(0,10);
}
function defaultTime() {
  return "09:00";
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // apply density + accent to root
  React.useEffect(() => {
    document.documentElement.dataset.density = t.density;
    const root = document.documentElement.style;
    const meta = ACCENT_PRESETS[t.accent] || ACCENT_PRESETS["#2F6F5C"];
    root.setProperty("--accent", t.accent);
    root.setProperty("--accent-deep", meta.deep);
    root.setProperty("--accent-tint", meta.tint);
  }, [t.density, t.accent]);

  const [data, setData] = React.useState({
    name: "",
    phone: "",
    email: "",
    address: "",
    zip: "",
    town: "",
    gasUtility: "",
    electricUtility: "",
    fuel: "oil",
    amount: "",
    jobType: "waiting",
    roadblock: "none",
    barriers: {},
    date: todayISO(),
    time: defaultTime(),
    duration: 120,
    calendar: "wx",
    color: "sage",
    reminders: [1440],
    emailReminder: true,
    notes: "",
    files: [],
  });
  const set = (k, v) => setData(d => ({ ...d, [k]: v }));

  // sync color id with accent preset choice
  React.useEffect(() => {
    const map = { "#2F6F5C": "sage", "#C24E2E": "coral", "#3B82C4": "blue", "#7A4F2A": "olive" };
    if (map[t.accent]) set("color", map[t.accent]);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [t.accent]);

  // auto-pick event color from WX status
  const STATUS_COLOR = {
    waiting:    "graphite",
    scheduled:  "sage",
    callback:   "amber",
    roadblock:  "coral",
    reschedule: "amber",
    canceled:   "graphite",
    walk:       "plum",
    completed:  "olive",
    invoiced:   "blue",
    paid:       "sage",
  };
  React.useEffect(() => {
    const c = STATUS_COLOR[data.jobType];
    if (c) set("color", c);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data.jobType]);

  const [toast, setToast] = React.useState({ on: false, msg: "", link: "", error: false });
  const [justAdded, setJustAdded] = React.useState(false);
  const [submitting, setSubmitting] = React.useState(false);
  const [showSettings, setShowSettings] = React.useState(false);
  const [appsUrl, setAppsUrl] = React.useState(
    () => localStorage.getItem("cwb_apps_url") || ""
  );
  React.useEffect(() => {
    localStorage.setItem("cwb_apps_url", appsUrl);
  }, [appsUrl]);

  const showToast = (msg, link, error) => {
    setToast({ on: true, msg, link: link || "", error: !!error });
    setTimeout(() => setToast(t => ({ ...t, on: false })), 5000);
  };

  const submit = async () => {
    if (!appsUrl) {
      // demo mode — pretend it worked
      setJustAdded(true);
      showToast("Demo: event added to Google Calendar", "");
      setTimeout(() => setJustAdded(false), 1800);
      return;
    }
    setSubmitting(true);
    try {
      const res = await fetch(appsUrl, {
        method: "POST",
        // Apps Script web apps don't accept preflighted requests — use
        // text/plain and let Apps Script parse e.postData.contents.
        headers: { "Content-Type": "text/plain;charset=utf-8" },
        body: JSON.stringify(data),
        redirect: "follow",
      });
      const out = await res.json();
      if (out.ok) {
        setJustAdded(true);
        setTimeout(() => setJustAdded(false), 1800);
        showToast("Event created in Google Calendar", out.htmlLink);
      } else {
        showToast("Apps Script error: " + (out.error || "unknown"), "", true);
      }
    } catch (err) {
      showToast("Could not reach Apps Script — " + err.message, "", true);
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="app">
      {/* top bar */}
      <header className="topbar">
        <div className="brand">
          <div className="brand-mark">c</div>
          <div className="brand-name">
            Cordwood<em>·book</em>
          </div>
        </div>
        <div className="topbar-right">
          <span className="gcal-pill" style={appsUrl ? null : { color: "var(--ink-mute)" }}>
            <span className="dot" style={appsUrl ? null : { background: "#C24E2E", boxShadow: "0 0 0 3px rgba(194,78,46,.18)" }}></span>
            {appsUrl ? "Connected to Google Calendar" : "Not connected — demo mode"}
          </span>
          <button className="icon-btn" aria-label="Settings"
            onClick={() => setShowSettings(s => !s)}
            title="Apps Script settings">
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
              <circle cx="12" cy="12" r="3"></circle>
              <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09a1.65 1.65 0 0 0 1.51-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33h0a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82v0a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
            </svg>
          </button>
        </div>
      </header>

      {/* heading */}
      <div className="page-head">
        <div>
          <h1 className="h-title">{t.headline.split(" ").slice(0,-1).join(" ")} <em>{t.headline.split(" ").slice(-1)}</em></h1>
          <p className="h-sub">
            Enter the customer details once. We'll create a Google Calendar event on
            your <b>{(CALENDARS.find(c => c.id === data.calendar) || CALENDARS[0]).label}</b> calendar
            with all the job info attached.
          </p>
        </div>
        <div className="page-head-actions">
          <button className="btn-ghost" type="button">Save draft</button>
          <button className="btn-ghost" type="button">
            Templates <span className="kbd">⌘K</span>
          </button>
        </div>
      </div>

      {/* main */}
      <div className="grid" style={!t.showPreview ? { gridTemplateColumns: "minmax(0,1fr)" } : null}>
        <div>
          <EntryForm
            data={data}
            set={set}
            onSubmit={submit}
            requireContract={t.requireContract}
            layout={t.showPreview ? "split" : "wide"}
          />
        </div>

        {t.showPreview && (
          <aside className="preview-col">
            <CalendarPreview data={data} justAdded={justAdded} />
            <SummaryCard data={data} />
          </aside>
        )}
      </div>

      {/* settings drawer */}
      {showSettings && (
        <div className="settings-overlay" onClick={() => setShowSettings(false)}>
          <div className="settings-card" onClick={e => e.stopPropagation()}>
            <div className="settings-head">
              <h3>Google Calendar connection</h3>
              <button className="icon-btn" onClick={() => setShowSettings(false)} aria-label="Close">
                <Icon.x />
              </button>
            </div>
            <p className="settings-p">
              Paste the <b>Web app URL</b> from your Apps Script deployment.
              See <code>apps-script/SETUP.md</code> for the 10-minute walk-through.
            </p>
            <input className="input" type="url"
              placeholder="https://script.google.com/macros/s/.../exec"
              value={appsUrl}
              onChange={(e) => setAppsUrl(e.target.value.trim())} />
            <div className="settings-row">
              <span className="settings-status" data-on={appsUrl ? "1" : "0"}>
                {appsUrl ? "✓ URL saved — events will be created on your calendar" : "⚠ No URL set — submissions stay in demo mode"}
              </span>
              {appsUrl && (
                <button className="btn-ghost" type="button"
                  onClick={() => setAppsUrl("")}>Disconnect</button>
              )}
            </div>
            <div className="settings-help">
              <b>Quick test:</b> open the URL above in a new tab — you should see
              <code>{"{\"ok\":true,…}"}</code>. If you don't, the deployment isn't live.
            </div>
          </div>
        </div>
      )}

      {/* toast */}
      <div className={"toast " + (toast.on ? "is-on" : "") + (toast.error ? " is-err" : "")}>
        <span className="check">{toast.error ? "!" : <Icon.check />}</span>
        {toast.msg}
        {toast.link && (
          <a href={toast.link} target="_blank" rel="noopener"
            style={{ color: "#9ad7ff", marginLeft: 8, textDecoration: "underline", fontSize: 13 }}>
            Open event ↗
          </a>
        )}
      </div>

      {/* tweaks */}
      <TweaksPanel title="Tweaks">
        <TweakSection label="Theme" />
        <TweakColor label="Accent" value={t.accent}
          options={Object.keys(ACCENT_PRESETS)}
          onChange={(v) => setTweak("accent", v)} />
        <TweakRadio label="Density" value={t.density}
          options={["compact","regular","comfy"]}
          onChange={(v) => setTweak("density", v)} />

        <TweakSection label="Layout" />
        <TweakToggle label="Show calendar preview" value={t.showPreview}
          onChange={(v) => setTweak("showPreview", v)} />
        <TweakToggle label="Show road-block flag" value={t.showRoadblock}
          onChange={(v) => setTweak("showRoadblock", v)} />

        <TweakSection label="Form" />
        <TweakToggle label="Require contract amount" value={t.requireContract}
          onChange={(v) => setTweak("requireContract", v)} />
        <TweakText label="Headline" value={t.headline}
          onChange={(v) => setTweak("headline", v)} />

        <TweakSection label="Demo" />
        <TweakButton label="Fill with sample data"
          onClick={() => setData(d => ({
            ...d,
            name: "Margaret Holloway",
            phone: "(207) 555-0142",
            email: "mholloway@example.com",
            address: "27 Maple St",
            zip: "01001",
            town: "Agawam",
            gasUtility: "Eversource Gas Co. of MA",
            electricUtility: "Eversource Electric",
            fuel: "oil",
            amount: "8,420",
            jobType: "scheduled",
            roadblock: "cleared",
            barriers: {
              "knob-tube":  { present: true, signed: true },
              "vermiculite": { present: true, signed: false },
            },
            date: todayISO(),
            time: "10:30",
            duration: 180,
            notes: "Friendly black lab on site. Crawl-space access through bulkhead in back. Leave invoice with homeowner.",
            reminders: [1440],
            emailReminder: true,
          }))} />
        <TweakButton label="Reset"
          onClick={() => setData({
            name: "", phone: "", email: "", address: "", zip: "", town: "", gasUtility: "", electricUtility: "",
            fuel: "oil", amount: "", jobType: "waiting", roadblock: "none", barriers: {},
            date: todayISO(), time: defaultTime(), duration: 120,
            calendar: "wx", color: "sage", reminders: [1440], emailReminder: true,
            notes: "", files: [],
          })} />
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
