/* global React */
// Data Source hook + status badge + settings drawer.

const { useState: useStateD, useEffect: useEffectD, useCallback: useCallbackD } = React;

/* Hook: load time-off based on current settings, expose status + refresh */
function useTimeOff() {
  const [settings, setSettings] = useStateD(() => window.CSConnector.loadSettings());
  const [data, setData] = useStateD(null);
  const [loading, setLoading] = useStateD(false);
  const [error, setError] = useStateD(null);
  const [tick, setTick] = useStateD(0);

  const refresh = useCallbackD(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await window.CSConnector.fetchTimeOff(settings);
      setData(res);
    } catch (e) {
      setError(e.message || String(e));
    } finally {
      setLoading(false);
    }
  }, [settings]);

  useEffectD(() => { refresh(); }, [refresh]);

  // Auto-refresh every 60s when live
  useEffectD(() => {
    if (settings.mode !== "workable") return;
    const id = setInterval(refresh, 60_000);
    return () => clearInterval(id);
  }, [settings.mode, refresh]);

  // Re-render every 15s so "synced 12s ago" stays fresh
  useEffectD(() => {
    const id = setInterval(() => setTick(t => t + 1), 15_000);
    return () => clearInterval(id);
  }, []);

  const update = (patch) => {
    const next = { ...settings, ...patch };
    setSettings(next);
    window.CSConnector.saveSettings(next);
  };

  return { settings, update, data, loading, error, refresh, tick };
}

/* Small status badge for the header */
function DataSourceBadge({ source, onClick }) {
  const { settings, data, loading, error } = source;
  const live = settings.mode === "workable";

  let label, klass = "";
  if (loading) { label = "Syncing…"; klass = "is-loading"; }
  else if (error) { label = "Error"; klass = "is-error"; }
  else if (!live) { label = "Mock data"; klass = "is-mock"; }
  else if (data?.at) { label = "Workable · " + relativeTime(data.at); klass = "is-live"; }
  else { label = "Workable"; klass = "is-live"; }

  return (
    <button className={`ds-badge ${klass}`} onClick={onClick} title={error || "Configure data source"}>
      <span className="ds-badge-dot" />
      <span>{label}</span>
      <span className="ds-badge-gear">⚙</span>
    </button>
  );
}

function relativeTime(iso) {
  const then = new Date(iso).getTime();
  const diff = Math.max(0, Date.now() - then);
  const s = Math.round(diff / 1000);
  if (s < 5) return "just now";
  if (s < 60) return s + "s ago";
  const m = Math.round(s / 60);
  if (m < 60) return m + "m ago";
  const h = Math.round(m / 60);
  return h + "h ago";
}

/* Settings drawer */
function DataSourceDrawer({ open, onClose, source }) {
  const { settings, update, data, error, loading, refresh } = source;
  const [draft, setDraft] = useStateD(settings);
  const [testStatus, setTestStatus] = useStateD(null);

  useEffectD(() => { setDraft(settings); }, [open, settings]);

  if (!open) return null;

  const handleSave = () => {
    update(draft);
  };

  const handleTest = async () => {
    setTestStatus({ kind: "loading" });
    try {
      const res = await window.CSConnector.fetchTimeOff(draft);
      setTestStatus({ kind: "ok", count: res.items.length, sample: res.items.slice(0, 3) });
    } catch (e) {
      setTestStatus({ kind: "error", message: e.message });
    }
  };

  return (
    <>
      <div className="ds-scrim" onClick={onClose} />
      <aside className="ds-drawer" role="dialog" aria-label="Data Source settings">
        <header className="ds-drawer-head">
          <div>
            <div className="ds-drawer-eyebrow">Data Source</div>
            <h2 className="ds-drawer-title">Time-off connector</h2>
          </div>
          <button className="ds-close" onClick={onClose} aria-label="Close">✕</button>
        </header>

        <div className="ds-drawer-body">
          <section className="ds-section">
            <h3>Source</h3>
            <div className="ds-mode-grid">
              <label className={`ds-mode-card ${draft.mode === "mock" ? "is-active" : ""}`}>
                <input
                  type="radio"
                  name="mode"
                  value="mock"
                  checked={draft.mode === "mock"}
                  onChange={() => setDraft({ ...draft, mode: "mock" })}
                />
                <div className="ds-mode-card-body">
                  <div className="ds-mode-card-name">Mock data</div>
                  <div className="ds-mode-card-desc">Static spreadsheet data baked into the page. Useful for demos.</div>
                </div>
              </label>
              <label className={`ds-mode-card ${draft.mode === "workable" ? "is-active" : ""}`}>
                <input
                  type="radio"
                  name="mode"
                  value="workable"
                  checked={draft.mode === "workable"}
                  onChange={() => setDraft({ ...draft, mode: "workable" })}
                />
                <div className="ds-mode-card-body">
                  <div className="ds-mode-card-name">Workable (via proxy)</div>
                  <div className="ds-mode-card-desc">Live time-off requests from Workable's API.</div>
                </div>
              </label>
            </div>
          </section>

          {draft.mode === "workable" && (
            <>
              <section className="ds-section">
                <h3>Proxy endpoint</h3>
                <p className="ds-help">
                  Workable's API can't be called from a browser directly (CORS + key safety).
                  Deploy a tiny server that holds your Workable token and exposes <code>/timeoff</code>.
                  See the snippet below.
                </p>
                <label className="ds-field">
                  <span>Proxy URL</span>
                  <input
                    type="url"
                    placeholder="https://cs-proxy.your-domain.com/api/workable"
                    value={draft.proxyUrl}
                    onChange={(e) => setDraft({ ...draft, proxyUrl: e.target.value })}
                  />
                </label>
                <label className="ds-field">
                  <span>Workable subdomain <em>(informational)</em></span>
                  <input
                    type="text"
                    placeholder="acme"
                    value={draft.subdomain}
                    onChange={(e) => setDraft({ ...draft, subdomain: e.target.value })}
                  />
                </label>
                <label className="ds-field">
                  <span>Proxy bearer token <em>(optional)</em></span>
                  <input
                    type="password"
                    placeholder="If your proxy requires auth"
                    value={draft.token}
                    onChange={(e) => setDraft({ ...draft, token: e.target.value })}
                  />
                </label>
                <div className="ds-actions">
                  <button className="ds-btn ds-btn-ghost" onClick={handleTest} disabled={!draft.proxyUrl}>
                    Test connection
                  </button>
                  {testStatus?.kind === "loading" && <span className="ds-test ds-test-loading">Testing…</span>}
                  {testStatus?.kind === "ok" && (
                    <span className="ds-test ds-test-ok">
                      ✓ Connected · {testStatus.count} time-off entr{testStatus.count === 1 ? "y" : "ies"}
                    </span>
                  )}
                  {testStatus?.kind === "error" && (
                    <span className="ds-test ds-test-error">✗ {testStatus.message}</span>
                  )}
                </div>
              </section>

              <section className="ds-section">
                <h3>Reference proxy (Cloudflare Worker)</h3>
                <pre className="ds-code">{`// worker.js — drop into Cloudflare Workers / Vercel edge
export default {
  async fetch(req, env) {
    if (new URL(req.url).pathname.endsWith("/timeoff")) {
      const r = await fetch(
        \`https://\${env.WORKABLE_SUBDOMAIN}.workable.com/spi/v3/timeoff/requests?status=approved\`,
        { headers: { Authorization: \`Bearer \${env.WORKABLE_TOKEN}\` } }
      );
      const body = await r.text();
      return new Response(body, {
        status: r.status,
        headers: {
          "content-type": "application/json",
          "access-control-allow-origin": "*",
        },
      });
    }
    return new Response("Not found", { status: 404 });
  },
};`}</pre>
              </section>
            </>
          )}

          <section className="ds-section">
            <h3>Status</h3>
            <div className="ds-status">
              {loading && <div className="ds-status-row ds-status-loading">Refreshing…</div>}
              {error && <div className="ds-status-row ds-status-error">⚠ {error}</div>}
              {!loading && !error && data && (
                <>
                  <div className="ds-status-row">
                    <strong>{data.items.length}</strong> agent{data.items.length === 1 ? "" : "s"} away today
                  </div>
                  <div className="ds-status-row ds-status-meta">
                    Source: <code>{data.source}</code> · last synced {relativeTime(data.at)}
                  </div>
                </>
              )}
              <button className="ds-btn ds-btn-ghost ds-status-refresh" onClick={refresh}>
                Refresh now
              </button>
            </div>
          </section>
        </div>

        <footer className="ds-drawer-foot">
          <button className="ds-btn ds-btn-ghost" onClick={onClose}>Cancel</button>
          <button className="ds-btn ds-btn-primary" onClick={() => { handleSave(); onClose(); }}>
            Save changes
          </button>
        </footer>
      </aside>
    </>
  );
}

window.useTimeOff = useTimeOff;
window.DataSourceBadge = DataSourceBadge;
window.DataSourceDrawer = DataSourceDrawer;
