// JoinRequestModal.jsx — §22.8: request-to-join a scope.
//
// A gated project or collection is invisible to non-members, so a user who
// knows it exists asks to join — naming a desired role ({owner, contributor})
// and an optional message. The request is recorded and fanned out to the
// scope's Owners across the subtree (the cross-collection inbox), who accept
// (writing the membership row) or decline.
//
// Sibling of ScopeMembersModal (the Owner's grant surface) and the per-RFC
// ContributeRequestForm (the per-entry ask). Opens from the "Request to join"
// affordance the directory / collection view shows when the viewer's
// `can_request_join` flag is set.

import { useEffect, useState } from 'react'
import { joinTarget, requestJoin } from '../api'

const ROLE_OPTIONS = [
  { value: 'contributor', label: 'RFC Contributor — propose entries in the scope' },
  { value: 'owner', label: 'Owner — administer the scope and its membership' },
]

export default function JoinRequestModal({ scopeType, scopeId, scopeName, onClose }) {
  const [target, setTarget] = useState(null)
  const [role, setRole] = useState('contributor')
  const [message, setMessage] = useState('')
  const [submitting, setSubmitting] = useState(false)
  const [error, setError] = useState(null)
  const [done, setDone] = useState(false)

  useEffect(() => {
    let live = true
    joinTarget(scopeType, scopeId)
      .then(t => { if (live) setTarget(t) })
      .catch(e => { if (live) setError(e.message || 'Could not load this scope.') })
    return () => { live = false }
  }, [scopeType, scopeId])

  const label = (target && target.name) || scopeName || scopeId
  const where = scopeType === 'collection' ? 'collection' : 'project'

  async function handleSubmit(e) {
    e.preventDefault()
    if (submitting) return
    setSubmitting(true)
    setError(null)
    try {
      await requestJoin(scopeType, scopeId, { role, message: message.trim() || null })
      setDone(true)
    } catch (err) {
      setError(err.message || 'Failed to send the request.')
    } finally {
      setSubmitting(false)
    }
  }

  return (
    <div className="modal-overlay" onClick={e => { if (e.target === e.currentTarget) onClose() }}>
      <div className="modal" style={{ maxWidth: 520 }}>
        <div className="modal-header">
          <h2>Request to join</h2>
          <button className="modal-close" onClick={onClose}>×</button>
        </div>
        <div className="modal-body">
          {done ? (
            <p>
              Your request to join {where} <strong>{label}</strong> has been sent to
              its Owners. You'll get an inbox notification when it's decided.
            </p>
          ) : target && !target.eligible ? (
            <p style={{ color: '#666' }}>
              {target.already_requested
                ? `You already have a pending request to join ${where} ${label}.`
                : (target.reason || 'You cannot request to join this scope.')}
            </p>
          ) : (
            <form onSubmit={handleSubmit} className="invitations-form">
              <p style={{ marginTop: 0, color: '#666' }}>
                Ask the Owners of {where} <strong>{label}</strong> for a role. An{' '}
                <strong>RFC Contributor</strong> may propose entries; an{' '}
                <strong>Owner</strong> administers the scope.
              </p>
              <label htmlFor="join-role">Role</label>
              <select id="join-role" value={role} onChange={e => setRole(e.target.value)}>
                {ROLE_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
              </select>
              <label htmlFor="join-message" style={{ marginTop: 10 }}>
                Message <span style={{ color: '#999' }}>(optional)</span>
              </label>
              <textarea
                id="join-message"
                value={message}
                onChange={e => setMessage(e.target.value)}
                rows={3}
                placeholder="Who you are and why you'd like to join."
                maxLength={4000}
              />
              <div style={{ marginTop: 12, display: 'flex', gap: 8, alignItems: 'center' }}>
                <button type="submit" className="btn-primary" disabled={submitting}>
                  {submitting ? 'Sending…' : 'Send request'}
                </button>
                {error && <span style={{ color: '#c33' }}>{error}</span>}
              </div>
            </form>
          )}
        </div>
        <div className="modal-footer">
          <button type="button" className="btn-link" onClick={onClose}>
            {done ? 'Close' : 'Cancel'}
          </button>
        </div>
      </div>
    </div>
  )
}
