// profile-pane.jsx — Settings → Profile tab content.
//
// R07 / T0012. User-level (NOT workspace-level) settings. T0010 left
// an inline ProfilePaneStub in settings.jsx; this module replaces it
// via the standard `window.<Name>` pattern.
//
// Four stacked sections:
//
//   1. Identity         — read-only email + editable display_name
//                         (direct Firestore self-write on users/{uid};
//                         R03 rules already permit this — see the
//                         `allow update` clause on /users/{uid}).
//   2. Workspaces       — list every workspace the user is a member of
//                         with their role chip; clicking a row deep-
//                         links into /w/<wid>/. Powered by useWorkspace
//                         (which wraps the listMyWorkspaces callable),
//                         not a fresh memberships query — the data is
//                         already loaded by the Settings shell.
//   3. Danger zone      — Sign out + Delete account. Delete opens a
//                         confirmation modal that requires the user to
//                         type their email exactly (Stripe / Notion
//                         pattern) before the Confirm button enables.
//                         The modal also shows owned-count and
//                         detached-count so the user knows EXACTLY
//                         what's about to happen — owned workspaces
//                         are deleted; non-owner memberships are just
//                         detached and the workspace survives.
//
// The `deleteAccount` callable (functions/src/users/deleteAccount.js)
// hasn't been renamed yet (R07 open question #7 owns that rename);
// this UI uses the existing name as-is. Its semantics already match
// what the user expects: deletes owned workspaces, detaches non-owner
// memberships, deletes the user doc and Firebase Auth user.
//
// Exposes window.ProfilePane.

(function (window) {
  'use strict';

  const { db, fns, useAuth, useWorkspace, signOut, navigateTo } =
    window.exoteamAuth || {};
  if (!useAuth) {
    console.error('profile-pane.jsx: window.exoteamAuth missing');
    return;
  }

  function ProfilePane() {
    const { user, userDoc } = useAuth();
    const { workspaces, loading: wsLoading } = useWorkspace();

    // Display name — optimistic local state seeded from userDoc.
    const [displayName, setDisplayName] = React.useState('');
    const [savedDisplayName, setSavedDisplayName] = React.useState('');
    const [saving, setSaving] = React.useState(false);
    const [savedTick, setSavedTick] = React.useState(false);
    const [saveError, setSaveError] = React.useState(null);

    // Seed from userDoc when it loads (and any time it changes from
    // under us — another tab editing, etc.).
    React.useEffect(() => {
      const next = (userDoc && userDoc.display_name) || '';
      setDisplayName(next);
      setSavedDisplayName(next);
    }, [userDoc && userDoc.display_name]);

    // Delete-account modal state.
    const [showDeleteModal, setShowDeleteModal] = React.useState(false);

    async function saveDisplayName() {
      if (!user) return;
      const trimmed = displayName.trim();
      // Nothing to do if unchanged.
      if (trimmed === savedDisplayName) {
        setSavedTick(true);
        setTimeout(() => setSavedTick(false), 1500);
        return;
      }
      setSaving(true);
      setSaveError(null);
      // Optimistic — assume success.
      setSavedDisplayName(trimmed);
      try {
        await db
          .collection('users')
          .doc(user.uid)
          .set({ display_name: trimmed || null }, { merge: true });
        setSavedTick(true);
        setTimeout(() => setSavedTick(false), 1800);
      } catch (err) {
        console.error('ProfilePane: saveDisplayName failed', err);
        setSaveError(err.message || String(err));
        // Roll back optimistic.
        setSavedDisplayName(savedDisplayName);
      } finally {
        setSaving(false);
      }
    }

    const dirty = displayName.trim() !== savedDisplayName;
    const ownedWorkspaces = (workspaces || []).filter((w) => w.role === 'owner');
    const detachedWorkspaces = (workspaces || []).filter((w) => w.role !== 'owner');

    return (
      <div className="exo-admin-pane">
        <h2 className="exo-admin-title">Profile</h2>
        <p className="exo-admin-subtitle">
          Your personal account. Settings here apply to you across every
          Workspace you're a member of.
        </p>

        {/* -------- 1. Identity -------- */}
        <section className="exo-admin-card">
          <h3 className="exo-admin-section-title">Identity</h3>

          <label className="exo-admin-label" style={{ marginTop: 0 }}>Email</label>
          <input
            className="exo-admin-input"
            type="email"
            value={(user && user.email) || ''}
            disabled
            readOnly
          />
          <p className="exo-admin-hint">
            Changing your sign-in email isn't supported yet. Contact
            support if you need this.
          </p>

          <label className="exo-admin-label">Display name</label>
          <input
            className="exo-admin-input"
            value={displayName}
            onChange={(e) => setDisplayName(e.target.value)}
            placeholder="e.g. Max Čelar"
            disabled={saving}
          />
          <p className="exo-admin-hint">
            How you appear to teammates in the Members list and the
            sign-out chip.
          </p>

          {saveError && (
            <div className="exo-admin-banner is-error" style={{ marginTop: 14 }}>
              <span>{saveError}</span>
            </div>
          )}

          <button
            type="button"
            className="exo-admin-btn"
            onClick={saveDisplayName}
            disabled={saving || (!dirty && !savedTick)}
            style={{ marginTop: 18, alignSelf: 'flex-start' }}
          >
            {saving ? 'Saving…' : savedTick ? 'Saved ✓' : 'Save'}
          </button>
        </section>

        {/* -------- 1b. Voice fingerprint (R10T13) -------- */}
        <VoiceFingerprintSection />

        {/* -------- 2. Workspaces -------- */}
        <section className="exo-admin-card">
          <h3 className="exo-admin-section-title">Workspaces you're in</h3>
          <p className="exo-admin-hint" style={{ marginTop: 0, marginBottom: 14 }}>
            Every Workspace you have access to. Click one to open it.
          </p>

          {wsLoading && (
            <p className="exo-admin-hint">Loading…</p>
          )}

          {!wsLoading && (workspaces || []).length === 0 && (
            <p className="exo-admin-hint">
              You aren't a member of any Workspace yet.
            </p>
          )}

          <ul className="exo-admin-list">
            {(workspaces || []).map((w) => (
              <li key={w.workspace_id} className="exo-admin-list-row">
                <div style={{ flex: 1, minWidth: 0 }}>
                  <strong>{w.display_name || w.workspace_id}</strong>
                  <div className="exo-admin-list-row-meta">{w.workspace_id}</div>
                </div>
                <span className={'exo-admin-pill ' + rolePillModifier(w.role)}>{w.role}</span>
                <button
                  type="button"
                  className="exo-admin-btn--link"
                  onClick={() => navigateTo(`/w/${w.workspace_id}/`)}
                >
                  Open →
                </button>
              </li>
            ))}
          </ul>
        </section>

        {/* -------- 3. Danger zone -------- */}
        <section className="exo-admin-card exo-admin-card--danger">
          <h3
            className="exo-admin-section-title"
            style={{
              color: 'var(--exo-accent-destructive)',
              textTransform: 'uppercase',
              letterSpacing: '0.05em',
              fontSize: 13,
            }}
          >
            Danger zone
          </h3>

          <div className="exo-admin-danger-zone-row">
            <div style={{ flex: 1, minWidth: 0 }}>
              <strong>Sign out</strong>
              <p className="exo-admin-hint" style={{ margin: '4px 0 0' }}>
                End this session on this device. You can sign back in any time.
              </p>
            </div>
            <button
              type="button"
              className="exo-admin-btn--link is-destructive"
              onClick={() => signOut()}
            >
              Sign out
            </button>
          </div>

          <hr
            style={{
              border: 'none',
              borderTop: '1px solid var(--exo-hairline)',
              margin: '18px 0',
            }}
          />

          <div className="exo-admin-danger-zone-row">
            <div style={{ flex: 1, minWidth: 0 }}>
              <strong>Delete account</strong>
              <p className="exo-admin-hint" style={{ margin: '4px 0 0' }}>
                Permanently deletes your account, every Workspace you own
                ({ownedWorkspaces.length}), and your memberships on the
                other Workspaces you're in ({detachedWorkspaces.length}).
                This cannot be undone.
              </p>
            </div>
            <button
              type="button"
              className="exo-admin-btn--link is-destructive"
              onClick={() => setShowDeleteModal(true)}
              style={{ fontWeight: 600 }}
            >
              Delete my account
            </button>
          </div>
        </section>

        {showDeleteModal && (
          <DeleteAccountModal
            email={(user && user.email) || ''}
            ownedWorkspaces={ownedWorkspaces}
            detachedWorkspaces={detachedWorkspaces}
            onCancel={() => setShowDeleteModal(false)}
          />
        )}
      </div>
    );
  }

  // ---------- Delete-account confirmation modal ----------
  function DeleteAccountModal({ email, ownedWorkspaces, detachedWorkspaces, onCancel }) {
    const [typed, setTyped] = React.useState('');
    const [busy, setBusy] = React.useState(false);
    const [error, setError] = React.useState(null);

    React.useEffect(() => {
      const onKey = (e) => { if (e.key === 'Escape' && !busy) onCancel(); };
      window.addEventListener('keydown', onKey);
      return () => window.removeEventListener('keydown', onKey);
    }, [onCancel, busy]);

    const matched = typed.trim().toLowerCase() === (email || '').trim().toLowerCase()
      && email.length > 0;

    async function confirmDelete() {
      if (!matched) return;
      setBusy(true);
      setError(null);
      try {
        const callable = fns.httpsCallable('deleteAccount');
        await callable({});
        // Success — Firestore + Auth user are gone. Token refresh
        // will fail at the next attempt; for a clean exit, sign the
        // user out locally then bounce to the marketing site.
        try { await signOut(); } catch (_e) { /* best-effort */ }
        window.location.assign('/');
      } catch (err) {
        console.error('deleteAccount failed', err);
        setError(err.message || String(err));
        setBusy(false);
      }
    }

    return (
      <div className="exo-admin-modal-backdrop" onClick={busy ? undefined : onCancel}>
        <div className="exo-admin-modal" onClick={(e) => e.stopPropagation()}>
          <h3
            className="exo-admin-modal-title"
            style={{ color: 'var(--exo-accent-destructive)' }}
          >
            Delete your account permanently?
          </h3>
          <p className="exo-admin-modal-body">
            You're about to permanently delete your account. This will:
          </p>

          <ul style={{
            margin: '0 0 14px',
            paddingLeft: 20,
            color: 'var(--exo-ink-secondary)',
            fontSize: 13.5,
            lineHeight: 1.6,
          }}>
            <li>
              <strong>Delete {ownedWorkspaces.length} Workspace{ownedWorkspaces.length === 1 ? '' : 's'} you own</strong>
              {ownedWorkspaces.length > 0 && (
                <>: {ownedWorkspaces.map((w) => w.display_name || w.workspace_id).join(', ')}</>
              )}
              {'.'}
            </li>
            <li>
              <strong>Remove you from {detachedWorkspaces.length} other Workspace{detachedWorkspaces.length === 1 ? '' : 's'}</strong>
              {detachedWorkspaces.length > 0 && (
                <> ({detachedWorkspaces.map((w) => w.display_name || w.workspace_id).join(', ')}) — they will keep them</>
              )}
              {'.'}
            </li>
            <li>Delete your Firebase Auth user so you can't sign back in.</li>
          </ul>

          <p className="exo-admin-modal-body" style={{ marginBottom: 6 }}>
            This cannot be undone. To confirm, type your email{' '}
            <strong>{email}</strong> below.
          </p>

          <input
            className="exo-admin-input"
            type="email"
            value={typed}
            onChange={(e) => setTyped(e.target.value)}
            placeholder={email}
            disabled={busy}
            autoFocus
          />

          {error && (
            <div className="exo-admin-banner is-error" style={{ marginTop: 12 }}>
              <span>{error}</span>
            </div>
          )}

          <div className="exo-admin-modal-actions">
            <button
              type="button"
              className="exo-admin-btn--ghost exo-admin-btn"
              onClick={onCancel}
              disabled={busy}
            >
              Cancel
            </button>
            <button
              type="button"
              className="exo-admin-btn exo-admin-btn--destructive"
              onClick={confirmDelete}
              disabled={!matched || busy}
            >
              {busy ? 'Deleting…' : 'Delete my account'}
            </button>
          </div>
        </div>
      </div>
    );
  }

  // Map a membership role to one of the `.exo-admin-pill` modifier
  // classes. Owner → success (green), admin → accent (blue), the rest →
  // muted. The pill itself is hairline-only (no background); the colour
  // is the only differentiator, which keeps the role badge readable
  // without competing with the row content.
  function rolePillModifier(role) {
    if (role === 'owner') return 'is-success';
    if (role === 'admin') return 'is-accent';
    return 'is-muted';
  }

  // R10T13 — voice fingerprint refresh card. Lives inside Profile pane
  // (per-user, not per-workspace). User can edit samples, re-run the
  // analyser, or clear. Drafter / grant writer / proposal writer
  // (R10T12) all read this for tone.
  function VoiceFingerprintSection() {
    const { user, userDoc } = useAuth();
    const [text, setText] = React.useState('');
    const [saving, setSaving] = React.useState(false);
    const [reanalysing, setReanalysing] = React.useState(false);
    const [error, setError] = React.useState(null);
    const [savedAt, setSavedAt] = React.useState(null);

    React.useEffect(() => {
      const vf = userDoc && userDoc.voice_fingerprint;
      if (vf && Array.isArray(vf.samples)) {
        setText(vf.samples.join('\n\n---\n\n'));
      }
    }, [userDoc && userDoc.voice_fingerprint && userDoc.voice_fingerprint.sample_count]);

    function parseSamples(blob) {
      if (!blob || typeof blob !== 'string') return [];
      const explicit = blob.split(/\n\s*-{3,}\s*\n/);
      const collected = (explicit.length > 1 ? explicit : blob.split(/\n\n+/))
        .map((s) => s.trim()).filter((s) => s.length >= 30);
      return collected.slice(0, 5);
    }

    async function save() {
      if (!user) return;
      setSaving(true); setError(null);
      try {
        const samples = parseSamples(text);
        await db.collection('users').doc(user.uid).set({
          voice_fingerprint: {
            samples,
            sample_count: samples.length,
            captured_at: firebase.firestore.FieldValue.serverTimestamp(),
          },
        }, { merge: true });
        setSavedAt(new Date());
        // Kick off analysis in background.
        if (samples.length && fns) {
          fns.httpsCallable('analyseVoiceFingerprint')({}).catch(() => {/* non-fatal */});
        }
      } catch (err) {
        console.error('VoiceFingerprint save failed', err);
        setError(err.message || String(err));
      } finally {
        setSaving(false);
      }
    }

    async function reanalyse() {
      setReanalysing(true); setError(null);
      try {
        await fns.httpsCallable('analyseVoiceFingerprint')({});
      } catch (err) {
        console.error('analyseVoiceFingerprint failed', err);
        setError(err.message || String(err));
      } finally {
        setReanalysing(false);
      }
    }

    const samples = parseSamples(text);
    const vf = (userDoc && userDoc.voice_fingerprint) || {};
    const analysis = vf.analysis || null;

    return (
      <section className="exo-admin-card">
        <h3 className="exo-admin-section-title">Voice fingerprint</h3>
        <p className="exo-admin-hint" style={{ marginTop: 0, marginBottom: 14 }}>
          The drafter, grant writer, and proposal writer read your
          samples and try to write in your voice. Per-USER — your
          drafts sound like <em>you</em>, not the workspace.
        </p>

        <label className="exo-admin-label">Your writing samples <span style={{ color: '#86868b' }}>(blank line separates samples)</span></label>
        <textarea
          className="exo-admin-input"
          style={{ minHeight: 180, fontFamily: 'inherit', resize: 'vertical' }}
          value={text}
          onChange={(e) => setText(e.target.value)}
          placeholder="Paste 2-5 short pieces of your writing — an email, a LinkedIn post, a brief paragraph."
          disabled={saving || reanalysing}
        />
        <p className="exo-admin-hint">
          {samples.length === 0
            ? 'No samples yet — paste 2+ blocks separated by blank lines.'
            : `${samples.length} sample${samples.length === 1 ? '' : 's'} parsed.`}
        </p>

        {analysis && (
          <div style={{
            margin: '8px 0', padding: '10px 12px',
            background: 'rgba(91,141,239,0.05)',
            border: '1px solid rgba(91,141,239,0.12)',
            borderRadius: 8, fontSize: 12.5, color: '#4a4a52',
          }}>
            <div style={{ fontWeight: 600, color: 'var(--exo-ink, #1d1d1f)', marginBottom: 4 }}>
              Current analysis
            </div>
            {analysis.summary_line && <div>{analysis.summary_line}</div>}
            {(analysis.tone || analysis.formality || analysis.sentence_length) && (
              <div style={{ marginTop: 4, fontSize: 11.5, color: '#6e6e73' }}>
                Tone: <strong>{analysis.tone || '?'}</strong>
                {' · '}Formality: <strong>{analysis.formality || '?'}</strong>
                {' · '}Sentences: <strong>{analysis.sentence_length || '?'}</strong>
              </div>
            )}
          </div>
        )}

        {error && <p className="exo-admin-error">{error}</p>}

        <div style={{ display: 'flex', gap: 10, marginTop: 10, flexWrap: 'wrap' }}>
          <button type="button" className="exo-admin-submit"
            disabled={saving || reanalysing}
            onClick={save}
          >
            {saving ? 'Saving…' : 'Save samples'}
          </button>
          {vf.sample_count > 0 && (
            <button type="button" className="exo-admin-link"
              disabled={saving || reanalysing}
              onClick={reanalyse}
            >
              {reanalysing ? 'Re-analysing…' : 'Re-run analysis'}
            </button>
          )}
          {savedAt && <span style={{ fontSize: 12, color: '#5db98a', alignSelf: 'center' }}>Saved.</span>}
        </div>
      </section>
    );
  }

  window.ProfilePane = ProfilePane;
})(window);
