// ─────────────────────────────────────────────────────────────
// ConnectSheet — preview-first.
//
// Shape:
//   • Slides up from the bottom over a 0.72 backdrop
//   • Header: avatar + handle + stage + mutual-forest summary
//   • Action toolbar: [Message]  [+]  [🌲]   (Message is dominant)
//   • Body: recent trees, mutual forests
//   • Quiet "Propose closer" tile at the bottom (hidden at Close)
//
// Propose flow (the brief's missing piece):
//   • Tapping the Propose tile cross-fades the body to a confirm prompt
//   • Confirm cross-fades to a success beat with a Sunlight pulse
//   • After ~1.6s the sheet dismisses; back in Ladder/Rings, the user
//     gets a "Proposed" chip until they accept on their side.
// ─────────────────────────────────────────────────────────────

function ConnectSheet({ user, isOpen, onClose, onPropose, alreadyProposed,
                        onOpenAddToGroup, onOpenInvite }) {
  // 'preview' → 'confirm' → 'sent'
  const [phase, setPhase] = React.useState('preview');

  // DEBUG: expose setter for screenshot capture
  React.useEffect(() => { window.__SET_PHASE = setPhase; }, []);

  // Reset internal phase whenever the sheet opens for a new user.
  React.useEffect(() => {
    if (isOpen) setPhase('preview');
  }, [isOpen, user?.handle]);

  if (!user) return null;

  const targetStage = nextStageUp(user.stage);     // null at 'close'
  const canPropose  = !!targetStage && !alreadyProposed;
  const isClose     = user.stage === 'close';
  const recents     = RECENT_TREES_BY_USER[user.handle] || [];
  const mutuals     = MUTUAL_FORESTS[user.handle]       || [];

  function commitPropose() {
    setPhase('sent');
    onPropose(user.handle, targetStage);
    // Auto-dismiss after the success beat completes
    window.setTimeout(() => onClose(), 1700);
  }

  return (
    <>
      {/* Backdrop */}
      <div onClick={onClose}
        style={{
          position: 'absolute', inset: 0,
          background: 'rgba(7,16,10,0.72)',
          opacity: isOpen ? 1 : 0,
          pointerEvents: isOpen ? 'auto' : 'none',
          transition: 'opacity 220ms var(--ease-organic)',
          zIndex: 30,
        }}/>

      {/* Sheet */}
      <div
        role="dialog"
        aria-modal="true"
        aria-label={`Connect with ${user.handle}`}
        style={{
          position: 'absolute', left: 0, right: 0, bottom: 0, top: 80,
          background: '#111D0A',
          borderRadius: '20px 20px 0 0',
          border: '0.5px solid #2D3A22', borderBottom: 'none',
          display: 'flex', flexDirection: 'column', overflow: 'hidden',
          transform: isOpen ? 'translateY(0)' : 'translateY(100%)',
          transition: 'transform 220ms var(--ease-organic)',
          zIndex: 31,
          boxShadow: '0 -20px 60px rgba(0,0,0,0.55)',
        }}>
        {/* Drag handle */}
        <div style={{ flexShrink: 0, display: 'flex', justifyContent: 'center', padding: '10px 0 4px' }}>
          <span style={{ width: 36, height: 4, background: '#445239', borderRadius: 2 }}/>
        </div>

        {/* Header — same regardless of phase */}
        <SheetHeader user={user} mutuals={mutuals} onClose={onClose}/>

        {/* Body — three phases. Cross-fade between them. */}
        <div style={{ flex: 1, minHeight: 0, position: 'relative' }}>
          {/* Preview phase */}
          <PhasePane visible={phase === 'preview'}>
            <ActionToolbar user={user}
              onMessage={onClose}
              onAddToGroup={onOpenAddToGroup}
              onInvite={onOpenInvite}/>
            <Body recents={recents} mutuals={mutuals}/>
            <ProposeTile
              user={user}
              isClose={isClose}
              alreadyProposed={alreadyProposed}
              canPropose={canPropose}
              targetStage={targetStage}
              onTap={() => setPhase('confirm')}/>
          </PhasePane>

          {/* Confirm + Sent phases — only mount when a target stage exists,
              otherwise STAGE_META lookups blow up on Close-stage users. */}
          {targetStage && (
            <>
              <PhasePane visible={phase === 'confirm'}>
                <ConfirmProposePane
                  user={user}
                  targetStage={targetStage}
                  onCancel={() => setPhase('preview')}
                  onPropose={commitPropose}/>
              </PhasePane>
              <PhasePane visible={phase === 'sent'}>
                <SentPane user={user} targetStage={targetStage}/>
              </PhasePane>
            </>
          )}
        </div>
      </div>
    </>
  );
}


// ─── Building blocks ───────────────────────────────────────

function PhasePane({ visible, children }) {
  return (
    <div style={{
      position: 'absolute', inset: 0,
      opacity: visible ? 1 : 0,
      transform: visible ? 'translateY(0)' : 'translateY(6px)',
      pointerEvents: visible ? 'auto' : 'none',
      transition: 'opacity 180ms var(--ease-organic), transform 180ms var(--ease-organic)',
      display: 'flex', flexDirection: 'column', minHeight: 0,
    }}>{children}</div>
  );
}

function SheetHeader({ user, mutuals, onClose }) {
  return (
    <div style={{
      padding: '12px 18px 16px',
      display: 'flex', gap: 14, alignItems: 'flex-start',
      borderBottom: '0.5px solid #1F2B16',
      flexShrink: 0,
    }}>
      <FolkAvatar user={user} size={52} online={user.online}/>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
          <span style={{ font: '500 20px var(--font-mono)', color: '#F2EDE4' }}>@{user.handle}</span>
          <FolkStageBadge stage={user.stage}/>
        </div>
        <div style={{ font: 'italic 400 12.5px var(--font-serif)', color: '#8A9678', marginTop: 3 }}>
          {mutuals.length > 0
            ? `${mutuals.length} mutual ${mutuals.length === 1 ? 'forest' : 'forests'} · joined ${user.joined}`
            : `joined ${user.joined}`}
        </div>
      </div>
      <button onClick={onClose} aria-label="Close"
        style={{
          background: 'transparent', border: 'none',
          padding: 6, color: '#586552', cursor: 'pointer',
          display: 'flex', alignSelf: 'flex-start',
        }}>
        <PIcons.X size={18}/>
      </button>
    </div>
  );
}

function ActionToolbar({ user, onMessage, onAddToGroup, onInvite }) {
  return (
    <div style={{
      padding: '12px 18px 10px',
      display: 'flex', gap: 8,
      borderBottom: '0.5px solid #1F2B16',
      flexShrink: 0,
    }}>
      <button onClick={onMessage}
        style={{
          flex: 2, background: '#4F8E51', color: '#F2EDE4',
          border: 'none', padding: '11px', borderRadius: 10,
          font: '500 14px var(--font-sans)',
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
          cursor: 'pointer',
        }}>
        <PIcons.MessageCircle size={16} color="#F2EDE4"/> Message
      </button>
      <button onClick={onAddToGroup} title="Add to a group" aria-label="Add to a group"
        style={{
          flex: 1, background: 'transparent', border: '0.5px solid #2D3A22',
          padding: '11px', borderRadius: 10, color: '#C9D2BB',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          cursor: 'pointer',
        }}>
        <PIcons.UserPlus size={16} color="#C9D2BB"/>
      </button>
      <button onClick={onInvite} title="Invite to a forest" aria-label="Invite to a forest"
        style={{
          flex: 1, background: 'transparent', border: '0.5px solid #2D3A22',
          padding: '11px', borderRadius: 10, color: '#C9D2BB',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          cursor: 'pointer',
        }}>
        <PIcons.Tree size={16} color="#C9D2BB"/>
      </button>
    </div>
  );
}

function Body({ recents, mutuals }) {
  return (
    <div style={{ flex: 1, overflowY: 'auto', padding: '14px 18px 18px', minHeight: 0 }}>
      {/* Recent trees */}
      <div style={{ font: '500 10.5px var(--font-sans)', color: '#76AB78',
                    letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 8 }}>
        Recent trees
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {recents.length === 0 && (
          <div style={{ padding: '10px 12px', border: '0.5px dashed #2D3A22', borderRadius: 10,
                        font: 'italic 400 12.5px var(--font-serif)', color: '#586552' }}>
            Quiet lately.
          </div>
        )}
        {recents.map((n, i) => (
          <div key={i} style={{
            background: '#0B1306', border: '0.5px solid #1F2B16',
            borderLeft: n.private ? '2px solid #7A4F2D' : '0.5px solid #1F2B16',
            borderRadius: 10, padding: '11px 12px',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
              <span style={{ font: '500 10px var(--font-sans)', color: '#8A9678',
                             letterSpacing: '0.08em', textTransform: 'uppercase',
                             whiteSpace: 'nowrap',
                             overflow: 'hidden', textOverflow: 'ellipsis',
                             minWidth: 0, flex: '0 1 auto' }}>
                {n.forest}
              </span>
              <span style={{ font: '400 11px var(--font-sans)', color: '#586552',
                             whiteSpace: 'nowrap', flexShrink: 0 }}>· {n.t}</span>
              {n.private && (
                <span style={{ font: '500 9px var(--font-sans)', color: '#D6BFA8',
                               background: '#1A2812', padding: '1px 6px', borderRadius: 999,
                               textTransform: 'lowercase',
                               whiteSpace: 'nowrap', flexShrink: 0 }}>private</span>
              )}
            </div>
            <p style={{ font: '400 13.5px/1.5 var(--font-sans)', color: '#F2EDE4', margin: 0 }}>
              {n.c}
            </p>
          </div>
        ))}
      </div>

      {/* Mutual forests */}
      {mutuals.length > 0 && (
        <>
          <div style={{ font: '500 10.5px var(--font-sans)', color: '#76AB78',
                        letterSpacing: '0.12em', textTransform: 'uppercase',
                        margin: '18px 0 8px' }}>
            Mutual forests
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            {mutuals.map(f => (
              <span key={f} style={{
                display: 'inline-flex', alignItems: 'center', gap: 6,
                padding: '5px 10px', borderRadius: 999,
                background: '#0B1306', border: '0.5px solid #2D3A22',
                font: '500 11.5px var(--font-sans)', color: '#C9D2BB',
                whiteSpace: 'nowrap',
              }}>
                <FLIcons.TreeMark size={12} active/> {f}
              </span>
            ))}
          </div>
        </>
      )}
    </div>
  );
}


// ─── Propose tile — the calm, low-prominence entry to the propose flow.
function ProposeTile({ user, isClose, alreadyProposed, canPropose, targetStage, onTap }) {
  // Three states: hidden (Close), already-proposed (waiting), available (button)
  if (isClose) {
    return (
      <div style={{
        margin: '0 18px 16px',
        padding: '12px 14px',
        background: '#0B1306', border: '0.5px solid #1F2B16', borderRadius: 12,
        display: 'flex', alignItems: 'center', gap: 10,
        flexShrink: 0,
      }}>
        <span style={{
          width: 10, height: 10, borderRadius: '50%',
          background: '#D4960C',
          boxShadow: '0 0 0 3px rgba(212,150,12,0.22)',
        }}/>
        <span style={{ flex: 1, font: 'italic 400 12.5px var(--font-serif)', color: '#A8C5A0' }}>
          Already in your inner ring — nothing closer to propose.
        </span>
      </div>
    );
  }

  if (alreadyProposed) {
    return (
      <div style={{
        margin: '0 18px 16px',
        padding: '12px 14px',
        background: 'rgba(212,150,12,0.06)',
        border: '0.5px solid rgba(212,150,12,0.35)', borderRadius: 12,
        display: 'flex', alignItems: 'center', gap: 10,
        flexShrink: 0,
      }}>
        <PIcons.ArrowUpRight size={16} color="#F4DCA0"/>
        <div style={{ flex: 1 }}>
          <div style={{ font: '500 13px var(--font-sans)', color: '#F4DCA0' }}>
            Proposed as {STAGE_META[alreadyProposed].label}
          </div>
          <div style={{ font: 'italic 400 11.5px var(--font-serif)', color: '#8A9678', marginTop: 2 }}>
            Waiting for {user.handle} to accept on their side.
          </div>
        </div>
      </div>
    );
  }

  if (!canPropose) return null;

  return (
    <button onClick={onTap}
      style={{
        margin: '0 18px 16px',
        padding: '12px 14px',
        background: 'transparent', border: '0.5px solid #2D3A22',
        borderRadius: 12, cursor: 'pointer', flexShrink: 0,
        display: 'flex', alignItems: 'center', gap: 10,
        textAlign: 'left',
      }}>
      <PIcons.ArrowUpRight size={16} color="#F4DCA0"/>
      <div style={{ flex: 1 }}>
        <div style={{ font: '500 13px var(--font-sans)', color: '#F2EDE4' }}>
          Propose as {STAGE_META[targetStage].label}
        </div>
        <div style={{ font: 'italic 400 11.5px var(--font-serif)', color: '#8A9678', marginTop: 2 }}>
          A quiet ask. Both of you have to agree.
        </div>
      </div>
      <PIcons.ChevronRight size={16} color="#586552"/>
    </button>
  );
}


// ─── Confirm pane — the missing flow ─────────────────────────────
function ConfirmProposePane({ user, targetStage, onCancel, onPropose }) {
  const meta = STAGE_META[targetStage];
  return (
    <div style={{ flex: 1, padding: '20px 22px 22px', display: 'flex', flexDirection: 'column' }}>
      <div style={{ font: '500 10.5px var(--font-sans)', color: '#F4DCA0',
                    letterSpacing: '0.14em', textTransform: 'uppercase', marginBottom: 10 }}>
        Propose closer
      </div>
      <div style={{ font: '500 22px var(--font-mono)', color: '#F2EDE4', letterSpacing: '-0.01em' }}>
        @{user.handle} → {meta.label}
      </div>

      {/* Visual: a tiny ladder showing the proposed step */}
      <div style={{ marginTop: 18, padding: '14px 16px',
                    background: '#0B1306', border: '0.5px solid #1F2B16',
                    borderRadius: 12, display: 'flex', alignItems: 'center', gap: 12 }}>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
                      padding: '6px 10px', borderRadius: 8,
                      background: 'transparent', border: '0.5px solid #1F2B16' }}>
          <FolkStageBadge stage={user.stage}/>
          <span style={{ font: 'italic 400 11px var(--font-serif)', color: '#8A9678' }}>now</span>
        </div>
        <span style={{ font: '500 22px var(--font-sans)', color: '#445239' }}>→</span>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
                      padding: '6px 10px', borderRadius: 8,
                      background: meta.soft, border: `0.5px solid ${meta.accent}` }}>
          <FolkStageBadge stage={targetStage}/>
          <span style={{ font: 'italic 400 11px var(--font-serif)', color: meta.accent }}>proposed</span>
        </div>
      </div>

      {/* The substance — what does this stage actually unlock? */}
      <div style={{ marginTop: 18, font: '500 10.5px var(--font-sans)', color: '#76AB78',
                    letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 8 }}>
        What changes at {meta.label}
      </div>
      <ul style={{ margin: 0, padding: '0 0 0 18px',
                   font: '400 13.5px/1.55 var(--font-sans)', color: '#C9D2BB' }}>
        {whatChangesAt(targetStage).map((line, i) => <li key={i}>{line}</li>)}
      </ul>

      <div style={{
        margin: '18px 0 0', padding: 12,
        background: '#111D0A', border: '0.5px solid #1F2B16', borderRadius: 10,
        font: 'italic 400 12.5px/1.55 var(--font-serif)', color: '#8A9678',
      }}>
        We'll send a quiet nudge — no notification storm. If they accept,
        you'll see them rise on the ladder.
      </div>

      <div style={{ marginTop: 'auto', display: 'flex', gap: 10 }}>
        <button onClick={onCancel}
          style={{
            flex: 1, background: 'transparent', border: '0.5px solid #2D3A22',
            color: '#C9D2BB', padding: '13px', borderRadius: 12,
            font: '500 14px var(--font-sans)', cursor: 'pointer',
          }}>
          Not yet
        </button>
        <button onClick={onPropose}
          style={{
            flex: 2, background: '#4F8E51', color: '#F2EDE4',
            border: 'none', padding: '13px', borderRadius: 12,
            font: '500 14px var(--font-sans)', cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
          }}>
          <PIcons.ArrowUpRight size={16} color="#F2EDE4"/> Propose
        </button>
      </div>
    </div>
  );
}

function whatChangesAt(stage) {
  return {
    acquaintance: [
      'Your handle stays public; nothing changes for them yet.',
      'Mutual forests show your bond on the member list.',
      'You can invite each other to invite-only forests.',
    ],
    friend: [
      'Real names exchanged.',
      'They can see your profile’s city.',
      'You appear in each other’s “Friends” section.',
    ],
    close: [
      'Approximate location + new-tree alerts (you choose which).',
      'Private forests highlight Close folk first.',
      'You become each other’s default DM recipient.',
    ],
  }[stage] || [];
}


// ─── Sent pane — the success beat ────────────────────────────────
function SentPane({ user, targetStage }) {
  return (
    <div style={{
      flex: 1, padding: '36px 24px', display: 'flex', flexDirection: 'column',
      alignItems: 'center', justifyContent: 'center', textAlign: 'center', gap: 14,
    }}>
      {/* The sunlight pulse — concentric rings expanding outward */}
      <div style={{ position: 'relative', width: 92, height: 92, marginBottom: 8 }}>
        <span style={{ position: 'absolute', inset: 0, borderRadius: '50%',
                       border: '1px solid rgba(212,150,12,0.45)',
                       animation: 'sunPulse 1.6s var(--ease-organic) infinite' }}/>
        <span style={{ position: 'absolute', inset: 14, borderRadius: '50%',
                       border: '1px solid rgba(212,150,12,0.55)',
                       animation: 'sunPulse 1.6s 200ms var(--ease-organic) infinite' }}/>
        <span style={{
          position: 'absolute', inset: 30, borderRadius: '50%',
          background: '#D4960C',
          boxShadow: '0 0 24px rgba(212,150,12,0.6)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <PIcons.Check size={18} color="#0B1306"/>
        </span>
      </div>
      <div style={{ font: '500 19px var(--font-mono)', color: '#F2EDE4' }}>
        Sent.
      </div>
      <div style={{ font: 'italic 400 14px/1.55 var(--font-serif)', color: '#A8C5A0', maxWidth: 280 }}>
        @{user.handle} will see your proposal in their Sunlight.
        They'll rise to {STAGE_META[targetStage].label} when they accept.
      </div>
    </div>
  );
}


window.ConnectSheet = ConnectSheet;
