// app.jsx — RoCo Arts Council site shell
// Mounts the React app, wires the hash router to page components,
// and provides global utilities (toasts, newsletter, push notifications).

// ─── Toast system ─────────────────────────────────────────────────
// Accessible from anywhere via window.showToast(message, type, duration).
// Types: 'info' (default) | 'success' | 'error'

let _toastId = 0;
const _toastListeners = new Set();

function showToast(message, type = 'info', duration = 4500) {
  const id = ++_toastId;
  _toastListeners.forEach(fn => fn({ id, message, type, duration }));
  return id;
}

function ToastManager() {
  const [toasts, setToasts] = React.useState([]);

  React.useEffect(() => {
    const listener = (toast) => {
      setToasts(prev => [...prev, toast]);
      setTimeout(() => {
        setToasts(prev => prev.filter(t => t.id !== toast.id));
      }, toast.duration);
    };
    _toastListeners.add(listener);
    return () => _toastListeners.delete(listener);
  }, []);

  const dismiss = (id) => setToasts(prev => prev.filter(t => t.id !== id));
  const root = document.getElementById('roco-toasts');
  if (!root || !toasts.length) return null;

  const icons = { success: '✓', error: '✕', info: '◉' };

  return ReactDOM.createPortal(
    <>
      {toasts.map(t => (
        <div key={t.id} className={`roco-toast toast-${t.type}`} role="alert">
          <span className="roco-toast-icon" aria-hidden>{icons[t.type] || icons.info}</span>
          <span style={{ flex: 1 }}>{t.message}</span>
          <button className="roco-toast-close" onClick={() => dismiss(t.id)} aria-label="Dismiss">×</button>
        </div>
      ))}
    </>,
    root
  );
}

// ─── Newsletter inline form ────────────────────────────────────────
// Used in the news strip and footer. Calls API.subscribeNewsletter().
function NewsletterForm({ buttonText = 'Subscribe', dark = true }) {
  const [email, setEmail] = React.useState('');
  const [status, setStatus] = React.useState('idle'); // idle | loading | done | error

  const submit = async (e) => {
    e.preventDefault();
    if (!email || status === 'loading') return;
    setStatus('loading');
    try {
      await API.subscribeNewsletter(email);
      setStatus('done');
      setEmail('');
      showToast("You're on the list. One email a month, no spam.", 'success');
    } catch {
      setStatus('error');
      showToast('Something went wrong — try again or email us directly.', 'error');
    }
  };

  if (status === 'done') {
    return (
      <span style={{ color: dark ? '#78BE4D' : '#2F7A2E', fontWeight: 600, fontSize: 14 }}>
        ✓ You're subscribed.
      </span>
    );
  }

  return (
    <form onSubmit={submit} style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
      <input
        type="email" required
        value={email}
        onChange={e => setEmail(e.target.value)}
        placeholder="your@email.com"
        style={{
          flex: '1 1 180px', padding: '10px 14px', borderRadius: 6,
          border: `1.5px solid ${dark ? 'rgba(251,247,238,0.25)' : '#E8E2D3'}`,
          background: dark ? 'rgba(251,247,238,0.08)' : '#fff',
          color: dark ? '#FBF7EE' : '#1F1B2E',
          fontSize: 14, fontFamily: 'inherit', outline: 'none',
        }}
      />
      <button
        type="submit"
        disabled={status === 'loading'}
        style={{
          padding: '10px 20px', borderRadius: 999, border: 'none',
          background: '#F3CF03', color: '#1F1B2E',
          fontWeight: 700, fontSize: 13.5, cursor: 'pointer',
          opacity: status === 'loading' ? 0.7 : 1,
        }}
      >
        {status === 'loading' ? 'Sending…' : buttonText}
      </button>
    </form>
  );
}

// ─── Placeholder pages ────────────────────────────────────────────
function PageNotFound() {
  return (
    <div className="roco-root" style={{
      minHeight: '80vh', display: 'flex', flexDirection: 'column',
      alignItems: 'center', justifyContent: 'center',
      background: '#FBF7EE', padding: '80px 24px', textAlign: 'center',
    }}>
      <div style={{
        fontFamily: 'var(--font-display)', fontWeight: 800,
        fontSize: 96, color: '#E8E2D3', lineHeight: 1,
      }}>404</div>
      <h1 style={{
        fontFamily: 'var(--font-display)', fontSize: 32,
        color: '#01234B', margin: '16px 0 8px',
      }}>Page not found</h1>
      <p style={{ color: '#6B6577', maxWidth: 360, marginBottom: 32 }}>
        This page doesn't exist. Maybe it moved, or maybe it's still being built.
      </p>
      <a href="#/" style={{
        padding: '12px 24px', borderRadius: 999,
        background: '#45217A', color: '#FBF7EE',
        fontWeight: 700, fontSize: 15, fontFamily: 'var(--font-body)',
      }}>← Back to home</a>
    </div>
  );
}

function PageComingSoon({ title, description }) {
  return (
    <div className="roco-root" style={{
      minHeight: '80vh', display: 'flex', flexDirection: 'column',
      alignItems: 'center', justifyContent: 'center',
      background: '#FBF7EE', padding: '80px 24px', textAlign: 'center',
    }}>
      <div style={{
        fontFamily: 'var(--font-display)', fontWeight: 800,
        fontSize: 64, color: '#E8E2D3', lineHeight: 1, marginBottom: 24,
      }}>Coming soon</div>
      <h1 style={{
        fontFamily: 'var(--font-display)', fontSize: 36,
        color: '#01234B', margin: '0 0 12px',
      }}>{title}</h1>
      {description && (
        <p style={{ color: '#6B6577', maxWidth: 400, marginBottom: 32 }}>{description}</p>
      )}
      <a href="#/" style={{
        padding: '12px 24px', borderRadius: 999,
        background: '#45217A', color: '#FBF7EE',
        fontWeight: 700, fontSize: 15, fontFamily: 'var(--font-body)',
      }}>← Back to home</a>
    </div>
  );
}

// ─── Page router ──────────────────────────────────────────────────
function PageRouter() {
  const { page, id } = useCurrentPage();

  switch (page) {
    case 'home':
      return <HomepageFinal />;

    case 'artists':
      return <ArtistsIndexA />;

    case 'artist-profile':
      // In production: fetch artist by slug from WordPress, then render ProfileArtist.
      // For now, demo both profile types by slug.
      if (id === 'jacob-steinmiller') return <ProfileStudent />;
      return <ProfileMember />;

    case 'events':
      return <EventsIndexB />; // list view is the primary events index

    case 'event-detail':
      // Route by id/slug to the correct template.
      // Drop-in / multi-site Open Studios campaign
      if (id === 'spring-open-studios' || id === 'spring-os' || id === 'fall-os') return <EventDetailDropIn />;
      // Gallery opening / exhibit
      if (id === 'ss-open' || (id && (id.includes('senior') || id.includes('exhibit') || id.includes('gallery') || id.includes('opening')))) {
        return <EventDetailExhibit />;
      }
      // Default: class or concert
      return <EventDetailConcert />;

    case 'news':
      return <NewsIndex />;

    case 'news-article': {
      // Open calls and announcements use the sidebar template
      const announcementIds = ['qw-2027', 'draw-series', 'hours-summer', 'board-spring', 'summer-call', 'students-25'];
      if (id && (announcementIds.includes(id) || id.includes('call') || id.includes('apply') || id.includes('grant'))) {
        return <NewsArticleAnnouncement />;
      }
      return <NewsArticleStory />;
    }

    case 'about':
      return <PageComingSoon
        title="About the Council"
        description="The Council's story, the board, funding sources, and the annual report."
      />;

    case 'contact':
      return <PageComingSoon
        title="Contact us"
        description="A form for general questions, volunteering, press inquiries, commissions, and Annex rentals."
      />;

    default:
      return <PageNotFound />;
  }
}

// ─── App wrapper ──────────────────────────────────────────────────
function AppContent() {
  const { path } = useRouter();

  // Signal loading complete on first mount
  React.useEffect(() => {
    window.dispatchEvent(new CustomEvent('roco:ready'));
  }, []);

  // Re-signal on route changes so analytics can track page views
  React.useEffect(() => {
    window.dispatchEvent(new CustomEvent('roco:navigate', { detail: { path } }));
  }, [path]);

  return (
    <div key={path} className="page-fade">
      <PageRouter />
    </div>
  );
}

function App() {
  return (
    <RouterProvider>
      <AppContent />
      <ToastManager />
    </RouterProvider>
  );
}

// Expose utilities globally so non-React code (push banner buttons, etc.) can use them
Object.assign(window, { showToast, NewsletterForm });

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
