/* ═══════════════════════════════════════════════════════════════
   bezirk.live — App Shell
   Routing, tab bar, screen orchestration, coachmarks, push preview
   ═══════════════════════════════════════════════════════════════ */

function App(){
  const [state, setState] = useState(window.AppStore.getState());
  const [route, setRoute] = useState('feed');         // feed | help | inbox | profile
  const [stack, setStack] = useState([]);             // ['detail', post] | ['chat', chatId] | ['settings'] | ['premium']
  const [composeOpen, setComposeOpen] = useState(false);
  const [ratingChat, setRatingChat] = useState(null);
  const [toast, setToast] = useState(null);
  const [notifsOpen, setNotifsOpen] = useState(false);
  const [coachmark, setCoachmark] = useState(null);
  const [pushPreview, setPushPreview] = useState(null);

  // Cloud-aware auth gate
  const cloudEnabled = !!(window.BEZIRKLIVE_CONFIG && window.BEZIRKLIVE_CONFIG.isConfigured());
  const [authUser, setAuthUser] = useState(window.BL?.user || null);
  const [authChecking, setAuthChecking] = useState(cloudEnabled);

  useEffect(() => {
    if (!cloudEnabled) return;
    // Wait briefly for supabase client to init, then settle
    const t = setTimeout(() => setAuthChecking(false), 600);
    const unsub = window.BL?.subscribeAuth ? window.BL.subscribeAuth(u => {
      setAuthUser(u);
      setAuthChecking(false);
    }) : null;
    return () => { clearTimeout(t); if (unsub) unsub(); };
  }, []);

  // subscribe to store
  useEffect(()=>{
    window._appState = state;
    return window.AppStore.subscribe(s=>{
      window._appState = s;
      setState(s);
    });
  },[]);
  useEffect(()=>{ window._appState = state; },[state]);

  // First-run coachmark
  useEffect(()=>{
    if (state.onboarded && !state.coachmarksSeen.feed){
      setTimeout(()=>setCoachmark('feed'), 800);
    }
  },[state.onboarded]);

  // Push notification preview on new notifs
  const lastNotifId = useRef(null);
  useEffect(()=>{
    const latest = state.notifications[0];
    if (latest && latest.id !== lastNotifId.current && lastNotifId.current !== null){
      setPushPreview(latest);
      setTimeout(()=>setPushPreview(null), 4500);
    }
    lastNotifId.current = latest?.id || 'init';
  },[state.notifications]);

  // ═══ ROUTING HELPERS ═══
  const go = (r) => { setRoute(r); setStack([]); };
  const push = (...args) => setStack(s=>[...s, args]);
  const pop = () => setStack(s=>s.slice(0,-1));

  const openDetail = (post) => push('detail', post.id);
  const openChat = (chatId) => push('chat', chatId);
  const openSettings = () => push('settings');
  const openPremium = () => push('premium');
  const openBusiness = () => push('business');

  // ═══ AUTH GATE (cloud mode only) ═══
  if (cloudEnabled){
    if (authChecking){
      return (
        <div style={{height:'100%', display:'flex', alignItems:'center', justifyContent:'center', background:T.bg}}>
          <div style={{width:48, height:48, borderRadius:14, background:`linear-gradient(135deg, ${T.green}, #166435)`, display:'flex', alignItems:'center', justifyContent:'center', color:'#fff', fontFamily:'Fraunces,serif', fontWeight:700, fontSize:22, animation:'pulse 1.4s ease-in-out infinite'}}>b.</div>
          <style>{`@keyframes pulse { 0%,100%{transform:scale(1);opacity:.6} 50%{transform:scale(1.08);opacity:1} }`}</style>
        </div>
      );
    }
    if (!authUser){
      return <AuthScreen onAuthSuccess={(u)=>setAuthUser(u)}/>;
    }
  }

  // ═══ NOT ONBOARDED ═══
  if (!state.onboarded){
    return <OnboardingFlow onComplete={(profile)=>{
      window.AppStore.actions.completeOnboarding(profile);
      // Demo-Posts NUR im Local-Only-Modus (ohne Cloud) laden.
      // Echte User (Cloud konfiguriert) sehen KEINE Fake-Graz-Posts.
      const cloudConfigured = !!(window.BEZIRKLIVE_CONFIG && window.BEZIRKLIVE_CONFIG.isConfigured());
      if (!cloudConfigured && state.posts.length === 0){
        window.SEED_POSTS.forEach(p => window.AppStore.setState(s => ({...s, posts: [...s.posts, p]})));
      }
    }}/>;
  }

  // ═══ STACK SCREENS (overlays over tab) ═══
  const top = stack[stack.length-1];
  let stackScreen = null;
  if (top){
    const [kind, arg] = top;
    if (kind==='detail'){
      const post = state.posts.find(p=>p.id===arg);
      if (post) stackScreen = <DetailScreen post={post} onBack={pop} onChat={openChat}/>;
    } else if (kind==='chat'){
      stackScreen = <ChatScreen chatId={arg} onBack={pop} onOpenRating={(c)=>setRatingChat(c)}/>;
    } else if (kind==='settings'){
      stackScreen = <SettingsScreen onBack={pop}/>;
    } else if (kind==='premium'){
      stackScreen = <PremiumScreen onBack={pop}/>;
    } else if (kind==='business'){
      stackScreen = <BusinessProfileScreen onBack={pop}/>;
    }
  }

  // ═══ TAB SCREEN ═══
  let tabScreen = null;
  if (route==='feed') tabScreen = <FeedScreen onSelect={openDetail} onCompose={()=>setComposeOpen(true)}/>;
  else if (route==='help') tabScreen = <HelpScreen onSelect={openDetail} onCompose={()=>setComposeOpen(true)}/>;
  else if (route==='inbox') tabScreen = <InboxScreen onOpenChat={openChat}/>;
  else if (route==='profile') tabScreen = <ProfileScreen onUpgrade={openPremium} onSettings={openSettings} onSelect={openDetail} onBusiness={openBusiness}/>;

  const unreadChats = Object.values(state.chats).filter(c=>c.unread>0).length;
  const unreadNotifs = state.notifications.filter(n=>!n.read).length;

  return (
    <div style={{height:'100%', display:'flex', flexDirection:'column', position:'relative', overflow:'hidden'}}>
      {/* Top status bar */}
      <div style={{
        position:'absolute', top:0, left:0, right:0, zIndex:50,
        padding:'8px 22px 0', display:'flex', justifyContent:'space-between',
        alignItems:'center', fontSize:13, fontWeight:700, color:T.text,
        pointerEvents:'none',
      }}>
        <span>9:41</span>
        <button onClick={()=>setNotifsOpen(true)} style={{background:'none',border:'none',cursor:'pointer',pointerEvents:'auto',position:'relative',padding:0}}>
          <span style={{fontSize:14}}>🔔</span>
          {unreadNotifs>0 && <div style={{position:'absolute',top:-2,right:-4,width:8,height:8,borderRadius:'50%',background:T.red}}/>}
        </button>
      </div>

      {/* Stack screen pushes over the tab content */}
      <div style={{flex:1, position:'relative', overflow:'hidden', paddingTop:24}}>
        <div style={{position:'absolute', inset:0, display:'flex', flexDirection:'column', visibility: stackScreen?'hidden':'visible'}}>
          {tabScreen}
        </div>
        {stackScreen && (
          <div className="aSlideIn" style={{position:'absolute', inset:0, display:'flex', flexDirection:'column', background:T.bg, zIndex:30}}>
            {stackScreen}
          </div>
        )}
      </div>

      {/* Tab bar (hidden when stack screen is showing chat — keeps focus) */}
      {!stackScreen && (
        <div style={{
          background:'rgba(255,255,255,.96)', backdropFilter:'blur(14px)',
          borderTop:`1px solid ${T.bdr}`, padding:'8px 8px 22px',
          display:'flex', justifyContent:'space-around', alignItems:'center',
          position:'relative',
        }}>
          <TabBtn label="Feed" icon="◇" active={route==='feed'} onClick={()=>go('feed')}/>
          <TabBtn label="Hilfe" icon="🤝" active={route==='help'} onClick={()=>go('help')}/>
          <button onClick={()=>setComposeOpen(true)} style={{
            width:50, height:50, borderRadius:16, background:T.green, color:'#fff',
            border:'none', fontSize:24, fontWeight:300, cursor:'pointer',
            boxShadow:'0 6px 18px rgba(10,74,36,.3)', marginTop:-18,
            display:'flex', alignItems:'center', justifyContent:'center',
          }}>+</button>
          <TabBtn label="Chats" icon="💬" active={route==='inbox'} onClick={()=>go('inbox')} badge={unreadChats}/>
          <TabBtn label="Profil" icon="◉" active={route==='profile'} onClick={()=>go('profile')}/>
        </div>
      )}

      {/* Compose sheet */}
      <ComposeSheet open={composeOpen} onClose={()=>setComposeOpen(false)} onPosted={(id)=>{
        setComposeOpen(false);
        setToast('✓ Post veröffentlicht!');
        const post = window.AppStore.getState().posts.find(p=>p.id===id);
        if (post) push('detail', id);
      }}/>

      {/* Rating modal */}
      <RatingModal chat={ratingChat} onClose={()=>setRatingChat(null)}/>

      {/* Notifications panel */}
      {notifsOpen && <NotificationsPanel onClose={()=>setNotifsOpen(false)} onSelect={(n)=>{
        if (n.postId){ push('detail', n.postId); }
        setNotifsOpen(false);
        window.AppStore.actions.markNotifRead(n.id);
      }}/>}

      {/* Coachmark overlay */}
      {coachmark && <Coachmark which={coachmark} onDismiss={()=>{
        window.AppStore.actions.dismissCoachmark(coachmark);
        setCoachmark(null);
      }}/>}

      {/* Push notification preview (lockscreen-style) */}
      {pushPreview && <PushPreview notif={pushPreview}/>}

      {/* Cloud status indicator (top-right) */}
      <CloudStatus/>

      {/* PWA Install Prompt */}
      <InstallPrompt/>

      {/* Toast */}
      <Toast msg={toast} onClose={()=>setToast(null)}/>

      <style>{`
        .aIn { animation: aIn .25s ease-out; }
        .aSheet { animation: aSheet .28s cubic-bezier(.2,.8,.2,1); }
        .aSlideIn { animation: aSlideIn .28s cubic-bezier(.2,.8,.2,1); }
        @keyframes aIn { from{opacity:0; transform:translateY(6px)} to{opacity:1; transform:translateY(0)} }
        @keyframes aSheet { from{transform:translateY(100%)} to{transform:translateY(0)} }
        @keyframes aSlideIn { from{transform:translateX(30%); opacity:.5} to{transform:translateX(0); opacity:1} }
        @keyframes aUpKf { from{opacity:0; transform:translateY(14px)} to{opacity:1; transform:translateY(0)} }
        .aUp { animation: aUpKf .3s cubic-bezier(.2,.8,.2,1) both; }
        .cp { transition: transform .12s ease, background .12s ease, opacity .12s ease; }
        .cp:active { transform: scale(.97); opacity:.85; }
        button:focus { outline: none; }
      `}</style>
    </div>
  );
}

function TabBtn({label, icon, active, onClick, badge}){
  return (
    <button onClick={onClick} style={{
      flex:1, display:'flex', flexDirection:'column', alignItems:'center', gap:2,
      background:'none', border:'none', cursor:'pointer', padding:'4px 0',
      color: active?T.text:T.muted, position:'relative',
    }}>
      <div style={{fontSize:18, lineHeight:1}}>{icon}</div>
      <div style={{fontSize:10, fontWeight:700, letterSpacing:'.2px'}}>{label}</div>
      {badge>0 && <div style={{position:'absolute', top:0, right:'30%', minWidth:16, height:16, borderRadius:8, background:T.red, color:'#fff', fontSize:9.5, fontWeight:800, display:'flex', alignItems:'center', justifyContent:'center', padding:'0 4px'}}>{badge}</div>}
    </button>
  );
}

function NotificationsPanel({onClose, onSelect}){
  const state = window._appState;
  const A = window.AppStore.actions;
  return (
    <div onClick={onClose} style={{position:'fixed', inset:0, background:'rgba(0,0,0,.4)', zIndex:88, display:'flex', justifyContent:'flex-end'}}>
      <div onClick={e=>e.stopPropagation()} className="aSheet" style={{width:'88%', maxWidth:380, background:'#fff', height:'100%', overflowY:'auto', boxShadow:'-10px 0 40px rgba(0,0,0,.15)', animation:'aSlideIn .25s ease-out'}}>
        <div style={{padding:'18px 20px', display:'flex', justifyContent:'space-between', alignItems:'center', borderBottom:`1px solid ${T.bdr}`}}>
          <div style={{fontFamily:'Fraunces, serif', fontSize:22, fontWeight:700, letterSpacing:'-.4px'}}>Mitteilungen</div>
          <button onClick={()=>A.markAllNotifsRead()} style={{background:'none',border:'none',color:T.green,fontSize:12,fontWeight:700,cursor:'pointer'}}>Alle gelesen</button>
        </div>
        {state.notifications.length===0 ? (
          <Empty icon="🔔" title="Alles gelesen" sub="Hier erscheinen neue Mitteilungen."/>
        ) : (
          <div>
            {state.notifications.map(n=>(
              <div key={n.id} onClick={()=>onSelect(n)} style={{padding:'14px 18px', borderBottom:`1px solid ${T.bdr}`, cursor:'pointer', background: n.read?'#fff':T.greenL, display:'flex', gap:11}}>
                <div style={{width:34, height:34, borderRadius:10, background:T.bdrSoft, display:'flex',alignItems:'center',justifyContent:'center',fontSize:16, flexShrink:0}}>
                  {n.type==='welcome'?'👋':n.type==='post'?'📝':n.type==='upgrade'?'✦':n.type==='rate'?'⭐':n.type==='rating'?'⭐':'🔔'}
                </div>
                <div style={{flex:1, minWidth:0}}>
                  <div style={{fontSize:13, fontWeight:700, color:T.text, marginBottom:2}}>{n.title}</div>
                  <div style={{fontSize:12, color:T.sec, fontWeight:500, lineHeight:1.4}}>{n.body}</div>
                  <div style={{fontSize:10.5, color:T.muted, fontWeight:600, marginTop:4}}>{timeAgo(n.t)}</div>
                </div>
                {!n.read && <div style={{width:8, height:8, borderRadius:'50%', background:T.green, flexShrink:0, marginTop:6}}/>}
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function Coachmark({which, onDismiss}){
  const M = {
    feed: {
      pos: {bottom:80, right:20},
      arrow: 'down-right',
      title: 'Tipp: Erstelle deinen ersten Post',
      body: 'Mit dem +-Button kannst du Hilfe anfragen, Angebote einstellen oder Fragen an deine Nachbarn stellen.',
    }
  };
  const m = M[which]; if (!m) return null;
  return (
    <div onClick={onDismiss} style={{position:'fixed', inset:0, background:'rgba(0,0,0,.55)', zIndex:80, animation:'aIn .3s ease-out'}}>
      <div onClick={e=>e.stopPropagation()} style={{position:'absolute', bottom:m.pos.bottom, right:m.pos.right, maxWidth:240, background:'#fff', padding:'14px 16px', borderRadius:14, boxShadow:'0 12px 40px rgba(0,0,0,.3)'}}>
        <div style={{fontSize:13, fontWeight:800, marginBottom:5, color:T.green}}>💡 {m.title}</div>
        <div style={{fontSize:12, color:T.sec, lineHeight:1.5, fontWeight:500, marginBottom:10}}>{m.body}</div>
        <Btn kind="success" size="sm" onClick={onDismiss}>Verstanden</Btn>
      </div>
    </div>
  );
}

function PushPreview({notif}){
  return (
    <div className="aPushIn" style={{
      position:'absolute', top:24, left:14, right:14, zIndex:75,
      background:'rgba(245,245,245,.92)', backdropFilter:'blur(20px) saturate(180%)',
      WebkitBackdropFilter:'blur(20px) saturate(180%)',
      borderRadius:16, padding:'10px 12px', display:'flex', gap:11, alignItems:'center',
      boxShadow:'0 8px 28px rgba(0,0,0,.15)',
    }}>
      <div style={{width:32, height:32, borderRadius:8, background:`linear-gradient(135deg, ${T.green}, #166435)`, display:'flex', alignItems:'center', justifyContent:'center', color:'#fff', fontFamily:'Fraunces, serif', fontWeight:700, fontSize:14, flexShrink:0}}>b.</div>
      <div style={{flex:1, minWidth:0}}>
        <div style={{display:'flex', justifyContent:'space-between'}}>
          <div style={{fontSize:11, fontWeight:600, color:'#000'}}>bezirk.live</div>
          <div style={{fontSize:10, color:'#666', fontWeight:500}}>jetzt</div>
        </div>
        <div style={{fontSize:13, fontWeight:700, color:'#000', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{notif.title}</div>
        <div style={{fontSize:12, color:'#222', fontWeight:500, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{notif.body}</div>
      </div>
      <style>{`@keyframes aPushIn { from{transform:translateY(-200%)} to{transform:translateY(0)} } .aPushIn{animation:aPushIn .35s cubic-bezier(.2,.8,.2,1)}`}</style>
    </div>
  );
}

Object.assign(window, { App });

// ─── CLOUD STATUS PILL (live/offline indicator) ───────────────────
function CloudStatus(){
  const [status, setStatus] = useState(window.Cloud?.state || 'idle');
  const [visible, setVisible] = useState(true);
  useEffect(() => {
    const onChange = e => setStatus(e.detail);
    window.addEventListener('cloud:status', onChange);
    return () => window.removeEventListener('cloud:status', onChange);
  }, []);
  useEffect(() => {
    if (status === 'live'){
      setVisible(true);
      const t = setTimeout(() => setVisible(false), 2200);
      return () => clearTimeout(t);
    } else {
      setVisible(true);
    }
  }, [status]);
  // Only show when configured AND something to communicate
  if (!window.BEZIRKLIVE_CONFIG?.isConfigured()) return null;
  if (status === 'idle') return null;
  if (!visible) return null;
  const map = {
    hydrating: { bg:'#FEF2DC', c:T.amber, t:'sync…' },
    live:      { bg:T.greenL,  c:T.green, t:'● live' },
    offline:   { bg:T.redL,    c:T.red,   t:'offline' },
  };
  const m = map[status]; if (!m) return null;
  return (
    <div style={{
      position:'absolute', top:8, right:50, zIndex:55,
      padding:'3px 9px', borderRadius:9, background:m.bg, color:m.c,
      fontSize:10, fontWeight:800, letterSpacing:'.3px',
      pointerEvents:'none', boxShadow:'0 2px 8px rgba(0,0,0,.06)',
    }}>{m.t}</div>
  );
}

Object.assign(window, { CloudStatus });

// ─── PWA INSTALL PROMPT ────────────────────────────────────────────
function InstallPrompt(){
  const [deferred, setDeferred] = useState(null);
  const [show, setShow] = useState(false);
  const [isIOS, setIsIOS] = useState(false);

  useEffect(() => {
    // Schon installiert? (standalone mode) → nie zeigen
    const standalone = window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone;
    if (standalone) return;

    // Schon weggeklickt in dieser Session/Woche?
    try {
      const dismissed = localStorage.getItem('bl.install.dismissed');
      if (dismissed && Date.now() - parseInt(dismissed) < 7*24*3600*1000) return;
    } catch(e){}

    // iOS Safari: kein beforeinstallprompt → eigener Hinweis
    const ios = /iphone|ipad|ipod/i.test(navigator.userAgent) && !window.MSStream;
    if (ios){
      setIsIOS(true);
      const t = setTimeout(()=>setShow(true), 4000);
      return ()=>clearTimeout(t);
    }

    // Android/Desktop: beforeinstallprompt abfangen
    const handler = (e) => {
      e.preventDefault();
      setDeferred(e);
      setTimeout(()=>setShow(true), 3000);
    };
    window.addEventListener('beforeinstallprompt', handler);
    return ()=>window.removeEventListener('beforeinstallprompt', handler);
  }, []);

  function dismiss(){
    setShow(false);
    try { localStorage.setItem('bl.install.dismissed', String(Date.now())); } catch(e){}
  }
  async function install(){
    if (!deferred) return;
    deferred.prompt();
    const { outcome } = await deferred.userChoice;
    setDeferred(null);
    setShow(false);
    if (outcome !== 'accepted') dismiss();
  }

  if (!show) return null;

  return (
    <div className="aUp" style={{
      position:'absolute', bottom:88, left:14, right:14, zIndex:78,
      background:'#fff', borderRadius:16, padding:'14px 16px',
      boxShadow:'0 12px 40px rgba(0,0,0,.22)', border:`1px solid ${T.bdr}`,
      display:'flex', alignItems:'center', gap:13,
    }}>
      <div style={{width:46, height:46, borderRadius:12, background:`linear-gradient(135deg, ${T.green}, #166435)`, color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', fontFamily:'Fraunces,serif', fontWeight:700, fontSize:22, flexShrink:0}}>b.</div>
      <div style={{flex:1, minWidth:0}}>
        <div style={{fontSize:13.5, fontWeight:800, color:T.text, marginBottom:2}}>bezirklive am Handy</div>
        <div style={{fontSize:11.5, color:T.sec, fontWeight:500, lineHeight:1.4}}>
          {isIOS
            ? <>Tippe <strong style={{color:T.text}}>Teilen ⬆️</strong> → <strong style={{color:T.text}}>„Zum Home-Bildschirm"</strong></>
            : 'Installiere die App für schnellen Zugriff & Vollbild.'}
        </div>
      </div>
      {!isIOS && <button onClick={install} style={{padding:'9px 15px', background:T.green, color:'#fff', border:'none', borderRadius:10, fontSize:12.5, fontWeight:700, cursor:'pointer', fontFamily:'inherit', flexShrink:0}}>Installieren</button>}
      <button onClick={dismiss} style={{background:'none', border:'none', fontSize:18, color:T.muted, cursor:'pointer', padding:'0 2px', flexShrink:0}}>×</button>
    </div>
  );
}

Object.assign(window, { InstallPrompt });
