// open-questions-pane.jsx — Settings → Open Questions tab.
//
// F021B Phase 3. Subscribes to
// `workspaces/{wid}.enrichment.open_questions[]` via a Firestore
// snapshot. Each question renders as a textarea + Save button; Save
// calls `recordDecisionFromOpenQuestion` which writes a `decisions/{slug}`
// spine doc + removes the question from the workspace doc's array.
//
// Below the list, a "Run another pass to refine" CTA calls
// `refineWorkspaceEnrichment` with the workspace's recorded decisions
// as additional grounding; surfaces a summary toast on success.
//
// Exposes `window.OpenQuestionsPane`.

(function (window) {
  'use strict';

  const { db, fns } = window.exoteamAuth || {};
  if (!db) {
    console.error('open-questions-pane.jsx: window.exoteamAuth.db missing');
    return;
  }

  const ANSWER_CHAR_CAP = 2000;

  function OpenQuestionsPane({ workspaceId }) {
    const [workspace, setWorkspace] = React.useState(null);
    const [loading, setLoading] = React.useState(true);
    const [drafts, setDrafts] = React.useState({});       // question -> draft text
    const [savingQuestion, setSavingQuestion] = React.useState(null);
    const [errorByQuestion, setErrorByQuestion] = React.useState({});
    const [dismissed, setDismissed] = React.useState({}); // local-only skip set
    const [refining, setRefining] = React.useState(false);
    const [refineError, setRefineError] = React.useState(null);
    const [refineToast, setRefineToast] = React.useState(null);
    const [decisionsCount, setDecisionsCount] = React.useState(0);

    // Workspace doc subscription (for the open_questions[] array).
    React.useEffect(() => {
      if (!workspaceId) return undefined;
      const unsub = db
        .collection('workspaces')
        .doc(workspaceId)
        .onSnapshot(
          (snap) => {
            if (snap.exists) {
              setWorkspace({ id: snap.id, ...snap.data() });
            }
            setLoading(false);
          },
          (err) => {
            console.error('OpenQuestionsPane: workspace snapshot', err);
            setLoading(false);
          },
        );
      return unsub;
    }, [workspaceId]);

    // Decisions count (for enabling/disabling the refine CTA).
    React.useEffect(() => {
      if (!workspaceId) return undefined;
      const unsub = db
        .collection('workspaces')
        .doc(workspaceId)
        .collection('decisions')
        .onSnapshot(
          (snap) => setDecisionsCount(snap.size),
          (err) => console.error('OpenQuestionsPane: decisions snapshot', err),
        );
      return unsub;
    }, [workspaceId]);

    const openQuestions = React.useMemo(() => {
      const list = workspace && workspace.enrichment && workspace.enrichment.open_questions;
      return Array.isArray(list) ? list : [];
    }, [workspace]);

    function setDraft(question, value) {
      setDrafts((d) => ({ ...d, [question]: value.slice(0, ANSWER_CHAR_CAP) }));
    }

    function dismiss(question) {
      // Local-only skip (does NOT persist — F021B §"Out of scope").
      setDismissed((d) => ({ ...d, [question]: true }));
    }

    async function save(question) {
      const answer = (drafts[question] || '').trim();
      if (!answer) {
        setErrorByQuestion((e) => ({ ...e, [question]: 'Type an answer first.' }));
        return;
      }
      setSavingQuestion(question);
      setErrorByQuestion((e) => ({ ...e, [question]: null }));
      try {
        const callable = fns.httpsCallable('recordDecisionFromOpenQuestion');
        await callable({
          workspace_id: workspaceId,
          question,
          answer,
        });
        // The Firestore listener will catch up — we don't need to clear
        // local state explicitly. But clear the draft so the textarea
        // collapses on the next render if the question reappears.
        setDrafts((d) => {
          const copy = { ...d };
          delete copy[question];
          return copy;
        });
      } catch (err) {
        console.error('OpenQuestionsPane: save failed', err);
        let message = err.message || String(err);
        if (err.code === 'already-exists') {
          message = 'This question already has a recorded decision. View it under Settings → Decisions.';
        }
        setErrorByQuestion((e) => ({ ...e, [question]: message }));
      } finally {
        setSavingQuestion(null);
      }
    }

    async function refine() {
      setRefining(true);
      setRefineError(null);
      setRefineToast(null);
      try {
        const callable = fns.httpsCallable('refineWorkspaceEnrichment');
        const { data } = await callable({ workspace_id: workspaceId });
        const counts = data && data.spine_writes_by_kind ? data.spine_writes_by_kind : {};
        const total = (counts.products || 0) + (counts.people || 0) + (counts.customers || 0)
          + (counts.competitors || 0) + (counts.content || 0) + (counts.decisions || 0);
        const remaining = Array.isArray(data && data.open_questions) ? data.open_questions.length : 0;
        setRefineToast(
          `Refined ${total} entit${total === 1 ? 'y' : 'ies'}. ${remaining} open question${remaining === 1 ? '' : 's'} remaining.`,
        );
        setTimeout(() => setRefineToast(null), 6000);
      } catch (err) {
        console.error('OpenQuestionsPane: refine failed', err);
        setRefineError(err.message || String(err));
      } finally {
        setRefining(false);
      }
    }

    if (loading || !workspace) {
      return (
        <div>
          <h2 className="exo-admin-title">Open Questions</h2>
          <p className="exo-admin-hint">Loading…</p>
        </div>
      );
    }

    const visibleQuestions = openQuestions.filter((q) => !dismissed[q]);

    return (
      <div>
        <h2 className="exo-admin-title">Open Questions</h2>
        <p className="exo-admin-subtitle">
          Gemini couldn't find these from public sources. Answer one and it
          becomes a permanent <strong>decision</strong> the outreach
          drafter, grant researcher, and proposal writer all consult.
        </p>

        {visibleQuestions.length === 0 ? (
          <p className="exo-admin-hint" style={{ marginTop: 16 }}>
            No open questions left. {decisionsCount > 0 && (
              <span>
                View your recorded decisions under{' '}
                <a
                  href={`/w/${workspaceId}/settings/decisions`}
                  style={{ color: 'var(--exo-accent)' }}
                  onClick={(e) => {
                    e.preventDefault();
                    if (window.exoteamAuth && window.exoteamAuth.navigateTo) {
                      window.exoteamAuth.navigateTo(`/w/${workspaceId}/settings/decisions`);
                    }
                  }}
                >
                  Settings → Decisions
                </a>.
              </span>
            )}
          </p>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16, marginTop: 18 }}>
            {visibleQuestions.map((q, idx) => (
              <QuestionCard
                key={q + '__' + idx}
                question={q}
                draft={drafts[q] || ''}
                onChangeDraft={(v) => setDraft(q, v)}
                onSave={() => save(q)}
                onSkip={() => dismiss(q)}
                saving={savingQuestion === q}
                error={errorByQuestion[q] || null}
              />
            ))}
          </div>
        )}

        <hr className="exo-admin-divider" />

        <h3 className="exo-admin-section-title">Refine enrichment</h3>
        <p className="exo-admin-subtitle">
          After recording a few decisions, click below to re-prompt Gemini
          with the new context. Newly-surfaced or refined entities land in
          the spine immediately.
        </p>
        {refineToast && (
          <div className="exo-admin-banner is-success" style={{ marginBottom: 10 }}>
            <span>{refineToast}</span>
          </div>
        )}
        {refineError && (
          <div className="exo-admin-banner is-error" style={{ marginBottom: 10 }}>
            <span>{refineError}</span>
          </div>
        )}
        <button
          type="button"
          className="exo-admin-btn"
          onClick={refine}
          disabled={refining || decisionsCount === 0}
          style={{ marginTop: 4, alignSelf: 'flex-start' }}
          title={decisionsCount === 0 ? 'Record at least one decision first.' : undefined}
        >
          {refining ? 'Refining…' : 'Run another pass to refine'}
        </button>
        {decisionsCount === 0 && (
          <p className="exo-admin-hint">
            Record at least one decision before refining.
          </p>
        )}
      </div>
    );
  }

  function QuestionCard({ question, draft, onChangeDraft, onSave, onSkip, saving, error }) {
    return (
      <div className="exo-admin-card" style={{ padding: 22, gap: 10 }}>
        <label
          className="exo-admin-label"
          style={{ fontWeight: 600, color: 'var(--exo-ink)', margin: 0, fontSize: 14 }}
        >
          {question}
        </label>
        <textarea
          className="exo-admin-textarea"
          value={draft}
          onChange={(e) => onChangeDraft(e.target.value)}
          placeholder="Type a short answer. This becomes a permanent decision."
          rows={3}
          maxLength={2000}
          disabled={saving}
        />
        {error && (
          <p style={{ margin: 0, color: 'var(--exo-accent-destructive)', fontSize: 12 }}>{error}</p>
        )}
        <div style={{ display: 'flex', gap: 16, alignItems: 'center' }}>
          <button
            type="button"
            className="exo-admin-btn--link"
            onClick={onSave}
            disabled={saving || !draft.trim()}
            style={{ color: 'var(--exo-ink)', fontWeight: 600 }}
          >
            {saving ? 'Saving…' : 'Save as decision'}
          </button>
          <button
            type="button"
            className="exo-admin-btn--link is-muted"
            onClick={onSkip}
            disabled={saving}
          >
            Skip
          </button>
        </div>
      </div>
    );
  }

  window.OpenQuestionsPane = OpenQuestionsPane;
})(window);
