// app.jsx — gs.town production shell: public browse, login-on-action, live data.

const NAV = [
  { key: 'home', label: 'Home', icon: 'home' },
  { key: 'map', label: 'Peta', icon: 'map' },
  { key: 'report', label: 'Lapor', icon: 'plus', center: true },
  { key: 'cluster', label: 'Cluster', icon: 'shield' },
  { key: 'profile', label: 'Profil', icon: 'user' },
];

function BottomNav({ tab, onTab, onReport }) {
  return (
    <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 50,
      background: 'var(--surface)', borderTop: '1px solid var(--border)', boxShadow: 'var(--sh-up)',
      paddingBottom: 'max(14px, env(safe-area-inset-bottom))', display: 'flex', alignItems: 'flex-start', justifyContent: 'space-around' }}>
      {NAV.map(n => {
        if (n.center) {
          return (
            <button key={n.key} onClick={onReport} style={{ position: 'relative', width: 58, marginTop: -18, border: 'none', background: 'none', cursor: 'pointer',
              display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
              <span style={{ width: 54, height: 54, borderRadius: '50%', background: 'var(--cta)', display: 'grid', placeItems: 'center',
                boxShadow: 'var(--sh-cta)', border: '4px solid var(--surface)' }}>
                <Icon name="plus" size={26} color="#fff" sw={2.6} />
              </span>
              <span style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--cta)' }}>{n.label}</span>
            </button>
          );
        }
        const on = tab === n.key;
        return (
          <button key={n.key} onClick={() => onTab(n.key)} style={{ flex: 1, paddingTop: 11, border: 'none', background: 'none', cursor: 'pointer',
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
            <Icon name={n.icon} size={23} color={on ? 'var(--primary)' : 'var(--text-3)'} sw={on ? 2.4 : 2} />
            <span style={{ fontSize: 10.5, fontWeight: on ? 700 : 600, color: on ? 'var(--primary)' : 'var(--text-3)' }}>{n.label}</span>
          </button>
        );
      })}
    </div>
  );
}

function initials(name) {
  if (!name) return 'GS';
  const p = name.trim().split(/\s+/);
  const a = (p[0] || '')[0] || 'G';
  const b = p[1] ? p[1][0] : '';
  return (a + b).toUpperCase();
}

function GuestProfile({ onLogin }) {
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--bg)' }}>
      <div style={{ paddingTop: SAFE_TOP, padding: '8px 20px 16px', background: 'var(--surface)', borderBottom: '1px solid var(--border)' }}>
        <h2 style={{ fontSize: 24, fontWeight: 800, letterSpacing: '-0.03em', color: 'var(--text-1)' }}>Profil</h2>
      </div>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 30, textAlign: 'center' }}>
        <div style={{ width: 72, height: 72, borderRadius: '50%', background: 'var(--primary-soft)', display: 'grid', placeItems: 'center', marginBottom: 18 }}>
          <Icon name="user" size={34} color="var(--primary)" />
        </div>
        <h3 style={{ fontSize: 19, fontWeight: 800, color: 'var(--text-1)', marginBottom: 8 }}>Gabung warga GS</h3>
        <p style={{ fontSize: 14, color: 'var(--text-2)', maxWidth: 270, marginBottom: 22 }}>Masuk untuk melapor, berkomentar, dukung laporan, dan kumpulkan poin.</p>
        <button onClick={onLogin} style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '14px 28px', borderRadius: 'var(--r-chip)', border: 'none', cursor: 'pointer',
          background: 'var(--primary)', color: '#fff', fontFamily: 'var(--font)', fontWeight: 800, fontSize: 15 }}>
          Masuk / Daftar <Icon name="arrow" size={18} color="#fff" sw={2.4} />
        </button>
      </div>
      <div style={{ height: 96 }} />
    </div>
  );
}

function Profile({ profile, myReports, onSignOut, openReport }) {
  const name = (profile && profile.full_name) || 'Warga GS';
  const lvl = (profile && profile.level) || 'Warga Baru';
  const pts = (profile && profile.points) || 0;
  const stats = [['Laporan', myReports.length], ['Poin', pts], ['Level', lvl]];
  return (
    <div style={{ height: '100%', overflowY: 'auto', background: 'var(--bg)', scrollbarWidth: 'none' }}>
      <div style={{ paddingTop: SAFE_TOP, background: 'var(--surface)', borderBottom: '1px solid var(--border)', paddingBottom: 22 }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '8px 20px 16px' }}>
          <h2 style={{ fontSize: 24, fontWeight: 800, letterSpacing: '-0.03em', color: 'var(--text-1)' }}>Profil</h2>
          <button onClick={onSignOut} style={{ border: '1px solid var(--border)', background: 'var(--surface)', cursor: 'pointer',
            borderRadius: 'var(--r-chip)', padding: '7px 14px', fontFamily: 'var(--font)', fontWeight: 700, fontSize: 12.5, color: 'var(--text-2)' }}>Keluar</button>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '0 20px' }}>
          <div style={{ width: 64, height: 64, borderRadius: '50%', background: 'var(--blue)', display: 'grid', placeItems: 'center', color: '#fff', fontWeight: 800, fontSize: 22 }}>{initials(name)}</div>
          <div>
            <div style={{ fontSize: 18, fontWeight: 800, color: 'var(--text-1)' }}>{name}</div>
            <div style={{ fontSize: 13, color: 'var(--text-2)', display: 'flex', alignItems: 'center', gap: 5, marginTop: 2 }}>
              <Icon name="shield" size={13} color="var(--primary)" /> {lvl}
            </div>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 10, padding: '18px 20px 0' }}>
          {stats.map(([k, v]) => (
            <div key={k} style={{ flex: 1, padding: '12px', borderRadius: 'var(--r-card)', background: 'var(--surface-2)', border: '1px solid var(--border)', textAlign: 'center' }}>
              <div className={k === 'Level' ? '' : 'mono'} style={{ fontSize: k === 'Level' ? 12.5 : 20, fontWeight: 700, color: 'var(--text-1)', lineHeight: 1.6 }}>{v}</div>
              <div style={{ fontSize: 11.5, color: 'var(--text-3)', fontWeight: 600 }}>{k}</div>
            </div>
          ))}
        </div>
      </div>
      <div style={{ padding: '18px 20px 0' }}>
        <h3 style={{ fontSize: 16, fontWeight: 800, color: 'var(--text-1)', marginBottom: 12 }}>Laporan saya</h3>
        {myReports.length === 0 ? (
          <div style={{ padding: '28px 16px', textAlign: 'center', borderRadius: 'var(--r-card)', background: 'var(--surface-2)', border: '1px dashed var(--border-strong)' }}>
            <p style={{ fontSize: 13.5, color: 'var(--text-2)' }}>Belum ada laporan. Mulai lapor untuk dapat poin!</p>
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>
            {myReports.map(r => <FeedCard key={r.id} report={r} onOpen={openReport} onUp={() => {}} upActive={false} />)}
          </div>
        )}
      </div>
      <div style={{ height: 110 }} />
    </div>
  );
}

function App() {
  const t = { showSponsored: true, mapVignette: true };
  const [authed, setAuthed] = React.useState(null);   // null=checking, false=guest, true=member
  const [profile, setProfile] = React.useState(null);
  const [tab, setTab] = React.useState('home');
  const [reports, setReports] = React.useState([]);
  const [places, setPlaces] = React.useState([]);
  const [clusters, setClusters] = React.useState([]);
  const [myUps, setMyUps] = React.useState({});
  const [myReps, setMyReps] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [reportFlow, setReportFlow] = React.useState(null);
  const [detailReport, setDetailReport] = React.useState(null);
  const [detailPlace, setDetailPlace] = React.useState(null);
  const [authPrompt, setAuthPrompt] = React.useState(false);

  React.useEffect(() => { document.documentElement.setAttribute('data-theme', 'light'); }, []);

  React.useEffect(() => {
    gsSupabase.auth.getSession().then(({ data }) => setAuthed(!!data.session));
    const { data: sub } = gsSupabase.auth.onAuthStateChange((_e, session) => setAuthed(!!session));
    return () => sub.subscription.unsubscribe();
  }, []);

  const refreshAll = React.useCallback(async () => {
    setLoading(true);
    const [rep, pl, cl, up, prof, mine] = await Promise.all([
      gsData.loadReports(), gsData.loadPlaces(), gsData.loadClusters(),
      gsData.myUpvotes(), gsData.getProfile(), gsData.myReports(),
    ]);
    setReports(rep); setPlaces(pl); setClusters(cl); setMyUps(up); setProfile(prof); setMyReps(mine);
    setLoading(false);
  }, []);

  // load data for everyone (anon read allowed); re-run when auth flips
  React.useEffect(() => { if (authed !== null) refreshAll(); }, [authed, refreshAll]);

  // realtime reports for all visitors
  React.useEffect(() => {
    const ch = gsSupabase.channel('gst_reports_rt')
      .on('postgres_changes', { event: '*', schema: 'public', table: 'gst_reports' }, () => {
        gsData.loadReports().then(setReports);
      }).subscribe();
    return () => { gsSupabase.removeChannel(ch); };
  }, []);

  const requireAuth = () => { if (!authed) { setAuthPrompt(true); return false; } return true; };

  const onUp = async (id) => {
    if (!requireAuth()) return;
    const newOn = !myUps[id];
    setMyUps(p => ({ ...p, [id]: newOn }));
    setReports(rs => rs.map(r => r.id === id ? { ...r, up: r.up + (newOn ? 1 : -1) } : r));
    const res = await gsData.toggleUpvote(id, newOn);
    if (res && res.error) {
      setMyUps(p => ({ ...p, [id]: !newOn }));
      setReports(rs => rs.map(r => r.id === id ? { ...r, up: r.up + (newOn ? -1 : 1) } : r));
    }
  };

  const go = (k) => { setTab(k); setDetailReport(null); setDetailPlace(null); };
  const openReport = (r) => setDetailReport(r);
  const openPlace = (p) => setDetailPlace(p);
  const startReport = (cat) => { if (!requireAuth()) return; setReportFlow({ cat: typeof cat === 'string' ? cat : null }); };

  if (authed === null && loading) {
    return <div className="gs-app" data-theme="light" style={{ height: '100%', display: 'grid', placeItems: 'center', background: 'var(--surface)' }}><Logo size={30} /></div>;
  }

  let screen;
  if (tab === 'home') screen = <Home t={t} reports={reports} places={places} myUps={myUps} onUp={onUp} loading={loading} go={go} openReport={openReport} openPlace={openPlace} startReport={startReport} profile={profile} />;
  else if (tab === 'map') screen = <MapScreen reports={reports} myUps={myUps} onUp={onUp} startReport={() => startReport()} openReport={openReport} />;
  else if (tab === 'cluster') screen = <ClusterScreen authed={authed} onRequireAuth={() => setAuthPrompt(true)} clusters={clusters} profile={profile} />;
  else if (tab === 'directory') screen = <Directory openPlace={openPlace} t={t} places={places} />;
  else screen = authed ? <Profile profile={profile} myReports={myReps} onSignOut={async () => { await gsData.signOut(); setAuthed(false); }} openReport={openReport} />
                       : <GuestProfile onLogin={() => setAuthPrompt(true)} />;

  return (
    <div className="gs-app" data-theme="light" style={{ position: 'relative', height: '100%', overflow: 'hidden' }}>
      {screen}
      <BottomNav tab={tab} onTab={go} onReport={() => startReport()} />

      {detailPlace && <PlaceSheet place={detailPlace} onClose={() => setDetailPlace(null)} />}
      {detailReport && <ReportDetailSheet report={detailReport} myUps={myUps} onUp={onUp} authed={authed}
        onRequireAuth={() => setAuthPrompt(true)} onClose={() => setDetailReport(null)} />}

      {reportFlow && (
        <div style={{ position: 'absolute', inset: 0, zIndex: 90, animation: 'gsFade 160ms var(--ease)' }}>
          <ReportFlow initialCat={reportFlow.cat} clusters={clusters} onClose={() => setReportFlow(null)}
            onDone={() => { setReportFlow(null); setTab('map'); refreshAll(); }} />
        </div>
      )}

      {authPrompt && (
        <div style={{ position: 'absolute', inset: 0, zIndex: 95, animation: 'gsFade 160ms var(--ease)' }}>
          <LoginScreen onClose={() => setAuthPrompt(false)}
            onAuthed={() => { setAuthPrompt(false); setAuthed(true); refreshAll(); }} />
        </div>
      )}
    </div>
  );
}

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