// Top-level App with view routing in state.

const { useState, useEffect } = React;

// LocalStorage helpers (best-effort, silent on private mode failure)
const ls = {
  get(key, def) { try { const v = localStorage.getItem(key); return v ? JSON.parse(v) : def; } catch { return def; } },
  set(key, val) { try { localStorage.setItem(key, JSON.stringify(val)); } catch {} },
  del(key) { try { localStorage.removeItem(key); } catch {} },
};

const DEFAULT_MAPPEN = [
  { id: 'm-default', name: 'Meine Lieblingsbilder', emoji: '⭐', items: [] },
];

function App() {
  const [route, setRoute] = useState({ view: 'home' });
  const [openMobile, setOpenMobile] = useState(false);
  const [search, setSearch] = useState('');
  const [points, setPoints] = useState(() => ls.get('aw.points', 0));

  // Profile state
  const [user, setUser] = useState(() => ls.get('aw.user', null));
  const [authOpen, setAuthOpen] = useState(false);
  const [checkout, setCheckout] = useState({ open: false, cycle: 'monthly' });
  const [settings] = useSettings();

  // Re-render the whole tree whenever the content store changes (admin CRUD),
  // and pull the live catalogue from the backend on first load (production).
  const [, forceData] = React.useReducer(x => x + 1, 0);
  useEffect(() => {
    const h = () => forceData();
    window.addEventListener('aw:data-changed', h);
    if (typeof hydrateFromBackend === 'function') hydrateFromBackend();
    return () => window.removeEventListener('aw:data-changed', h);
  }, []);

  // Per-user mappe storage key
  const mappenKey = (u) => u ? `aw.mappen.${(u.email || '').toLowerCase()}` : 'aw.mappen.guest';
  const activeKey = (u) => u ? `aw.activeMappe.${(u.email || '').toLowerCase()}` : 'aw.activeMappe.guest';

  // Multi-mappe state, keyed by user (loads when user changes)
  const [mappen, setMappen] = useState(() => {
    const u = ls.get('aw.user', null);
    return u ? ls.get(mappenKey(u), DEFAULT_MAPPEN) : DEFAULT_MAPPEN;
  });
  const [activeMappeId, setActiveMappeId] = useState(() => {
    const u = ls.get('aw.user', null);
    return u ? ls.get(activeKey(u), 'm-default') : 'm-default';
  });
  const [mappePanel, setMappePanel] = useState({ open: false, mappeId: null }); // null = list view
  const [picker, setPicker] = useState({ open: false, item: null });

  // User identity key (used in effect deps that need to re-run on sign-in/out)
  const userKey = user ? user.email : '__guest__';

  // Children (for parents who want to organize Mappen per child), keyed per user
  const childrenKey = (u) => u ? `aw.children.${(u.email || '').toLowerCase()}` : 'aw.children.guest';
  const [children, setChildren] = useState(() => {
    const u = ls.get('aw.user', null);
    return u ? ls.get(childrenKey(u), []) : [];
  });
  useEffect(() => {
    if (user) setChildren(ls.get(childrenKey(user), []));
    else setChildren([]);
    // eslint-disable-next-line
  }, [userKey]);
  useEffect(() => { if (user) ls.set(childrenKey(user), children); }, [children, userKey]);

  const addChild = (name) => {
    if (!name) return;
    const emojis = ['🧒','👦','👧','🐻','🦁','🐧','🦊','🐰'];
    const emoji = emojis[children.length % emojis.length];
    setChildren(cs => [...cs, { id: 'c-' + Date.now(), name, emoji }]);
  };
  const renameChild = (id, name) =>
    setChildren(cs => cs.map(c => c.id === id ? { ...c, name } : c));
  const deleteChild = (id) => {
    setChildren(cs => cs.filter(c => c.id !== id));
    // Detach mappen referencing this child
    setMappen(ms => ms.map(m => m.childId === id ? { ...m, childId: null } : m));
  };

  // Reload mappen whenever user identity changes (sign-in / sign-out).
  useEffect(() => {
    if (user) {
      setMappen(ls.get(mappenKey(user), DEFAULT_MAPPEN));
      setActiveMappeId(ls.get(activeKey(user), 'm-default'));
    } else {
      setMappen(DEFAULT_MAPPEN);
      setActiveMappeId('m-default');
    }
    // eslint-disable-next-line
  }, [userKey]);

  // Suggestions submitted by user
  const [suggestions, setSuggestions] = useState(() => ls.get('aw.suggestions', []));

  // Print queue (passes the items into the in-app print page)
  const [printQueue, setPrintQueue] = useState([]);

  // Persist
  useEffect(() => { ls.set('aw.user', user); }, [user]);
  useEffect(() => { if (user) ls.set(mappenKey(user), mappen); }, [mappen, userKey]);
  useEffect(() => { if (user) ls.set(activeKey(user), activeMappeId); }, [activeMappeId, userKey]);
  useEffect(() => { ls.set('aw.suggestions', suggestions); }, [suggestions]);
  useEffect(() => { ls.set('aw.points', points); }, [points]);

  // Listen for cross-component "open auth" events (e.g. from CommentSection)
  useEffect(() => {
    const h = () => setAuthOpen(true);
    window.addEventListener('aw:open-auth', h);
    return () => window.removeEventListener('aw:open-auth', h);
  }, []);

  // Apply favicon + document title from admin settings (live).
  useEffect(() => {
    const apply = () => {
      try {
        const s = loadSettings();
        if (s.favicon) {
          let link = document.querySelector("link[rel='icon']");
          if (!link) { link = document.createElement('link'); link.rel = 'icon'; document.head.appendChild(link); }
          link.href = s.favicon;
        }
        if (s.siteTitle) document.title = `${s.siteTitle} – Kostenlose Ausmalbilder zum Ausdrucken`;
      } catch {}
    };
    apply();
    window.addEventListener('aw:settings-changed', apply);
    return () => window.removeEventListener('aw:settings-changed', apply);
  }, []);

  const navigate = (next) => {
    setRoute(next);
    setOpenMobile(false);
    if (next && next.openMappe) setMappePanel({ open: true, mappeId: null });
    window.scrollTo({ top: 0, behavior: 'instant' });
  };
  const bumpPoints = (n) => setPoints(p => p + n);

  // === Mappe ops ===
  const allItems = mappen.flatMap(m => m.items);
  const totalCount = user ? allItems.length : 0;

  // Items in the *active* mappe only, used for "In Mappe" / "Sammeln" indicator.
  const activeMappeItems = (mappen.find(m => m.id === activeMappeId) || mappen[0])?.items || [];

  const toggleCollect = (item) => {
    // Require auth, open sign-in modal if not signed in.
    if (!user) { setAuthOpen(true); return; }
    let targetId = activeMappeId;
    if (!mappen.some(m => m.id === targetId)) targetId = mappen[0]?.id;
    if (!targetId) return;
    const inActive = activeMappeItems.some(x => x.id === item.id);
    setMappen(ms => ms.map(m => {
      if (m.id !== targetId) return m;
      return inActive
        ? { ...m, items: m.items.filter(x => x.id !== item.id) }
        : (m.items.some(x => x.id === item.id) ? m : { ...m, items: [...m.items, item] });
    }));
  };

  const addToMappe = (mappeId, item) => {
    setMappen(ms => ms.map(m => m.id === mappeId
      ? (m.items.some(x => x.id === item.id) ? m : { ...m, items: [...m.items, item] })
      : m));
    setActiveMappeId(mappeId);
  };
  const removeFromMappe = (mappeId, itemId) =>
    setMappen(ms => ms.map(m => m.id === mappeId ? { ...m, items: m.items.filter(x => x.id !== itemId) } : m));

  // Reorder items inside a mappe (drag&drop). Premium feature, but we don't gate at handler level -
  // the UI in mappe.jsx hides the drag affordance for non-premium users.
  const reorderInMappe = (mappeId, fromIdx, toIdx) => {
    setMappen(ms => ms.map(m => {
      if (m.id !== mappeId) return m;
      const next = [...m.items];
      const [moved] = next.splice(fromIdx, 1);
      next.splice(toIdx, 0, moved);
      return { ...m, items: next };
    }));
  };

  // Assign a mappe to one of the user's children (or null = none).
  const assignChild = (mappeId, childId) => {
    setMappen(ms => ms.map(m => m.id === mappeId ? { ...m, childId } : m));
  };

  const createMappe = (name, emoji = '🎒') => {
    const id = 'm-' + Date.now();
    setMappen(ms => [...ms, { id, name, emoji, items: [] }]);
    setActiveMappeId(id);
    return id;
  };
  const renameMappe = (mappeId, name) =>
    setMappen(ms => ms.map(m => m.id === mappeId ? { ...m, name } : m));
  const deleteMappe = (mappeId) => {
    setMappen(ms => {
      const next = ms.filter(m => m.id !== mappeId);
      return next.length ? next : DEFAULT_MAPPEN;
    });
  };

  const openPrintFor = (mappeId) => {
    const m = mappen.find(x => x.id === mappeId);
    if (!m || m.items.length === 0) return;
    printColoringList(m.items);
  };

  const addSuggestion = (s) => setSuggestions(prev => [s, ...prev]);

  const updateUser = (u) => {
    setUser(u);
    // Also update credentials store so login still works with updated email/name.
    try {
      const creds = JSON.parse(localStorage.getItem('aw.creds') || '{}');
      const oldKey = (user?.email || '').toLowerCase();
      const newKey = (u.email || '').toLowerCase();
      if (oldKey && creds[oldKey]) {
        const stored = creds[oldKey];
        if (oldKey !== newKey) delete creds[oldKey];
        creds[newKey] = { ...stored, name: u.name, bereich: u.bereich, colorIdx: u.colorIdx };
        localStorage.setItem('aw.creds', JSON.stringify(creds));
      }
    } catch {}
  };
  const signIn = (u) => {
    setUser(u);
    setAuthOpen(false);
    // Track login count + last-seen per user (for admin profile insights)
    try {
      const key = (u.email || '').toLowerCase();
      const logins = JSON.parse(localStorage.getItem('aw.logins') || '{}');
      logins[key] = (logins[key] || 0) + 1;
      localStorage.setItem('aw.logins', JSON.stringify(logins));
      const seen = JSON.parse(localStorage.getItem('aw.lastSeen') || '{}');
      seen[key] = new Date().toISOString();
      localStorage.setItem('aw.lastSeen', JSON.stringify(seen));
    } catch {}
  };
  const signOut = () => { setUser(null); navigate({ view: 'home' }); };
  const deleteAccount = () => {
    if (!user) return;
    const email = (user.email || '').toLowerCase();
    try {
      const creds = JSON.parse(localStorage.getItem('aw.creds') || '{}');
      delete creds[email];
      localStorage.setItem('aw.creds', JSON.stringify(creds));
      localStorage.removeItem(`aw.mappen.${email}`);
      localStorage.removeItem(`aw.activeMappe.${email}`);
    } catch {}
    setUser(null);
    navigate({ view: 'home' });
  };
  const grantPremium = (cycle = 'monthly') => {
    if (!user) return;
    // Called ONLY after a payment has completed (see CheckoutModal.onSuccess).
    // 'once' = einmaliger Kauf für genau einen Monat (kein Abo, läuft ab und muss
    // danach erneut aktiv gekauft werden). Abos (monthly/yearly) verlängern sich.
    const now = Date.now();
    let expiresAt = null;
    if (cycle === 'monthly') expiresAt = new Date(now + 30 * 864e5).toISOString();
    if (cycle === 'yearly')  expiresAt = new Date(now + 365 * 864e5).toISOString();
    if (cycle === 'once')    expiresAt = new Date(now + 30 * 864e5).toISOString();
    const next = { ...user, premium: { active: true, cycle, since: new Date().toISOString(), expiresAt, autoRenew: cycle === 'monthly' || cycle === 'yearly' } };
    setUser(next);
    // Sync into creds store too.
    try {
      const creds = JSON.parse(localStorage.getItem('aw.creds') || '{}');
      const k = (user.email || '').toLowerCase();
      if (creds[k]) {
        creds[k] = { ...creds[k], premium: next.premium };
        localStorage.setItem('aw.creds', JSON.stringify(creds));
      }
    } catch {}
  };

  // Premium is NOT granted on click, open the checkout. Premium only activates
  // once the payment completes (CheckoutModal calls grantPremium via onSuccess).
  const beginPurchase = (cycle = 'monthly') => {
    if (!user) { setAuthOpen(true); return; }
    setCheckout({ open: true, cycle });
  };

  const isAdmin = route.view.startsWith('admin');
  const isPrint = route.view === 'print';

  const topTab =
    route.view === 'home' ? 'home'
    : route.view === 'category' || route.view === 'categoryIndex' ? 'category'
    : route.view === 'detail' ? 'category'
    : route.view === 'ranking' ? 'ranking'
    : isAdmin ? 'admin'
    : 'home';

  // Profile tab, keep stable across re-renders
  const [profileTab, setProfileTab] = useState('mappen');
  useEffect(() => {
    if (route.view === 'profile' && route.tab) setProfileTab(route.tab);
  }, [route]);

  // Common props bundle
  const collectProps = { collection: activeMappeItems, toggleCollect };

  let page;
  switch (route.view) {
    case 'home':            page = <HomePage navigate={navigate} search={search} setSearch={setSearch} points={points} bumpPoints={bumpPoints} user={user} {...collectProps}/>; break;
    case 'categoryIndex':   page = <CategoryIndexPage navigate={navigate} search={search} setSearch={setSearch}/>; break;
    case 'category':        page = <CategoryPage slug={route.slug} navigate={navigate} user={user} {...collectProps}/>; break;
    case 'detail':          page = <DetailPage slug={route.slug} navigate={navigate} points={points} bumpPoints={bumpPoints} user={user} {...collectProps}/>; break;
    case 'ranking':         page = <RankingPage navigate={navigate} user={user} {...collectProps}/>; break;
    case 'print':           page = <PrintSheetPage collection={activeMappeItems} navigate={navigate} closePrint={closePrint}/>; break;
    case 'publicProfile':   page = <PublicProfilePage email={route.email} navigate={navigate}/>; break;
    case 'impressum':       page = <ImpressumPage navigate={navigate}/>; break;
    case 'datenschutz':     page = <DatenschutzPage navigate={navigate}/>; break;
    case 'lizenz':          page = <LizenzPage navigate={navigate}/>; break;
    case 'about':           page = <AboutPage navigate={navigate}/>; break;
    case 'profile':
      if (!user) { page = <SignedOutPlaceholder openAuth={() => setAuthOpen(true)} navigate={navigate}/>; break; }
      page = <ProfilePage user={user} mappen={mappen} navigate={navigate}
        tab={profileTab} setTab={setProfileTab}
        createMappe={createMappe} renameMappe={renameMappe} deleteMappe={deleteMappe}
        removeFromMappe={(mappeId, itemId) => removeFromMappe(mappeId, itemId)}
        openMappeFor={(mappeId) => setMappePanel({ open: true, mappeId })}
        openPrintFor={openPrintFor}
        suggestions={suggestions} addSuggestion={addSuggestion}
        updateUser={updateUser} signOut={signOut}
        deleteAccount={deleteAccount} purchasePremium={beginPurchase}/>;
      break;
    case 'adminDashboard':  page = <AdminDashboardPage navigate={navigate}/>; break;
    case 'adminUpload':     page = <AdminUploadPage navigate={navigate}/>; break;
    case 'adminCategories': page = <AdminCategoriesPage navigate={navigate}/>; break;
    case 'adminColorings':  page = <AdminColoringsPage navigate={navigate} categoryFilter={route.category}/>; break;
    case 'adminProfiles':   page = <AdminProfilesPage navigate={navigate}/>; break;
    case 'adminStats':      page = <AdminStatsPage navigate={navigate}/>; break;
    case 'adminSettings':   page = <AdminSettingsPage navigate={navigate} initialTab={route.tab}/>; break;
    default:                page = <HomePage navigate={navigate} search={search} setSearch={setSearch} points={points} bumpPoints={bumpPoints} user={user} {...collectProps}/>;
  }

  return (
    <div data-screen-label={
      route.view === 'home' ? '01 Startseite' :
      route.view === 'categoryIndex' ? '02a Alle Kategorien' :
      route.view === 'category' ? '02 Kategorie ' + (route.slug || '') :
      route.view === 'detail' ? '03 Detailseite' :
      route.view === 'ranking' ? '04 Ranking' :
      route.view === 'profile' ? '09 Profil' :
      route.view === 'adminDashboard' ? '05 Admin Dashboard' :
      route.view === 'adminUpload' ? '06 Admin Upload' :
      route.view === 'adminCategories' ? '07 Admin Kategorien' :
      route.view
    }>
      {!isPrint && (
        <Header current={topTab} navigate={navigate} openMobile={openMobile} setOpenMobile={setOpenMobile}
          collectionCount={totalCount} openMappe={() => setMappePanel({ open: true, mappeId: null })}
          isAdmin={isAdmin}
          user={user} openAuth={() => setAuthOpen(true)} signOut={signOut}
          mappen={mappen} activeMappeId={activeMappeId} setActiveMappeId={setActiveMappeId}/>
      )}
      <div key={route.view + (route.slug || '')} className="page-fade">
        {page}
      </div>
      {!isAdmin && !isPrint && <Footer navigate={navigate}/>}

      <MappePanel
        open={mappePanel.open}
        onClose={() => setMappePanel({ open: false, mappeId: null })}
        mappen={mappen}
        focusMappeId={mappePanel.mappeId}
        setFocusMappeId={(id) => setMappePanel(p => ({ ...p, mappeId: id }))}
        createMappe={createMappe}
        renameMappe={renameMappe}
        deleteMappe={deleteMappe}
        removeFromMappe={removeFromMappe}
        reorderInMappe={reorderInMappe}
        assignChild={assignChild}
        childrenList={children}
        addChild={addChild}
        renameChild={renameChild}
        deleteChild={deleteChild}
        navigate={navigate}
        openPrintFor={openPrintFor}
        user={user}
        openAuth={() => setAuthOpen(true)}
        activeMappeId={activeMappeId}
        setActiveMappeId={setActiveMappeId}/>

      <MappePicker
        open={picker.open}
        onClose={() => setPicker({ open: false, item: null })}
        mappen={mappen}
        onPick={(mappeId) => { addToMappe(mappeId, picker.item); }}
        onCreate={(name) => {
          const id = createMappe(name);
          if (picker.item) addToMappe(id, picker.item);
          setPicker({ open: false, item: null });
        }}/>

      <AuthModal open={authOpen} onClose={() => setAuthOpen(false)} onSignIn={signIn}/>
      <CheckoutModal
        open={checkout.open}
        cycle={checkout.cycle}
        settings={settings}
        user={user}
        onClose={() => setCheckout(c => ({ ...c, open: false }))}
        onSuccess={(cycle) => grantPremium(cycle)}/>
      <CookieBanner/>
    </div>
  );
}

// Tiny stub view shown when user navigates to /profile without an account.
const SignedOutPlaceholder = ({ openAuth, navigate }) => (
  <main className="max-w-3xl mx-auto px-5 sm:px-8 pt-16 pb-24 text-center">
    <div className="text-6xl mb-4 wiggle">🎨</div>
    <h1 className="font-display text-4xl font-extrabold tracking-tight">Erstelle dein Profil</h1>
    <p className="text-inkSoft mt-3 max-w-lg mx-auto leading-relaxed">
      Mit einem Profil kannst du eigene Sammelmappen anlegen, sie pro Anlass speichern und neue Bilder oder Kategorien vorschlagen.
    </p>
    <div className="mt-7 flex flex-wrap items-center justify-center gap-3">
      <Btn size="lg" leading={<IconUser size={18}/>} onClick={openAuth}>Profil erstellen</Btn>
      <Btn size="lg" variant="ghost" onClick={() => navigate({ view: 'home' })}>Zurück zur Startseite</Btn>
    </div>
  </main>
);

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