// app.jsx — Main app for Book Journal

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "navy",
  "layout": "magazine",
  "brandFont": "Pinyon Script"
} /*EDITMODE-END*/;

function HomePage() {
  const [genre, setGenre] = React.useState('Alle');
  const [sort, setSort] = React.useState('newest');
  const [category, setCategory] = React.useState('Alle Kategorien');
  const [selectedBook, setSelectedBook] = React.useState(null);

  const LIBRARY_CATEGORIES = ['Alle Kategorien', 'Neuzugänge', 'Bücher nach Vibe', 'Was nach dem Lesen bleibt', 'Oldies but Goldies'];

  // First book = Current Read; rest = library
  const allSorted = React.useMemo(() =>
  [...window.BOOKS].sort((a, b) => b.date.localeCompare(a.date)), []);
  const currentRead = allSorted[0];
  const libraryAll = allSorted;

  // Placeholder recommendations — empty cards + empty detail overlay; titles added later
  const recommendations = React.useMemo(() =>
    Array.from({ length: 8 }).map((_, i) => ({
      id: `rec-${i + 1}`,
      title: '', author: '', genre: '', summary: '', series: '', pages: null,
      ...((window.RECOMMENDATIONS || [])[i] || {}),
      id: `rec-${i + 1}`,
    })), []);

  const filtered = React.useMemo(() => {
    let list = libraryAll.filter((b) =>
    genre === 'Alle' ||
    b.genre === genre ||
    genre === 'Krimi / Thriller' && (b.genre === 'Krimi' || b.genre === 'Thriller') ||
    genre === 'Fantasy / Romantasy' && (b.genre === 'Fantasy' || b.genre === 'Romantasy')
    );
    if (sort === 'newest') list = list.sort((a, b) => b.date.localeCompare(a.date));else
    if (sort === 'oldest') list = list.sort((a, b) => a.date.localeCompare(b.date));else
    if (sort === 'title') list = list.sort((a, b) => a.title.localeCompare(b.title, 'de'));
    return list;
  }, [genre, sort, libraryAll]);

  const stats = React.useMemo(() => ({
    total: window.BOOKS.length,
    pages: window.BOOKS.reduce((s, b) => s + b.pages, 0),
    avg: (window.BOOKS.reduce((s, b) => s + b.rating, 0) / window.BOOKS.length).toFixed(1)
  }), []);

  return (
    <main className="page">
      <section className="hero">
        <div className="hero-eyebrow">Lesetagebuch · Buchblog</div>
        <h1>Zwischen den Seiten <em>lebt </em> die Welt</h1>
        <p className="lead">Ein Tagebuch in Buchform. Hier sammle ich gelesene Geschichten, geliebte Sätze und gelegentlich auch Enttäuschungen — ehrlich, langsam, mit Kaffee.</p>
        <div className="ornament-divider" style={{ maxWidth: 400, margin: '20px auto 0' }}>
          <Ornament size={70} />
        </div>
      </section>

      <div className="home-cols">
        <div className="home-col-current">
          <BookCard book={currentRead} hero currentRead photoId={'current-read-photo'} />
        </div>
        <div className="home-col-library">          <div className="library-head">
            <h2>
              <small>Aktuelle Lektüren</small>
              Meine Bibliothek
            </h2>
          </div>

          <div className="library-filterbar">
            {window.GENRES.map((g) =>
            <button key={g} className={`chip ${genre === g ? 'active' : ''}`} onClick={() => {
              setGenre(g);
              const shelf = document.querySelector('.home-col-library .library-scroll');
              if (shelf) {
                const top = shelf.getBoundingClientRect().top + window.scrollY - 120;
                window.scrollTo({ top, behavior: 'smooth' });
              }
            }}>
                {g}
              </button>
            )}
            <span className="filter-spacer" />
            <select className="sort-select" value={sort} onChange={(e) => setSort(e.target.value)} style={{ fontSize: 10, padding: '6px 28px 6px 10px' }}>
              <option value="newest">Neueste</option>
              <option value="oldest">Älteste</option>
              <option value="title">A–Z</option>
            </select>
          </div>

          {filtered.length === 0 ?
          <div className="no-results" style={{ padding: 40, fontSize: 15 }}>Keine Bücher in dieser Auswahl.</div> :

          <div className="library-scroll">
              <Bookshelf books={filtered} onBookClick={setSelectedBook} />
            </div>
          }
        </div>
      </div>

      <HorizontalCarousel
        title=""
        subtitle="Vielleicht auch was für dich"
        books={recommendations}
        onBookClick={setSelectedBook} />

      <BookDetailModal book={selectedBook} onClose={() => setSelectedBook(null)} />
      
    </main>);

}

function AboutPage() {
  return (
    <main className="page about">
      <div className="about-grid">
        <div>
          <Reveal>
            <div className="about-portrait">
              <image-slot
                id="about-portrait-photo"
                shape="rect"
                fit="cover"
                placeholder="Foto hierher ziehen"
                style={{ width: '100%', height: '100%', display: 'block' }}>
              </image-slot>
            </div>
          </Reveal>
        </div>
        <div className="about-intro">
          <Reveal>
            <div style={{ fontFamily: 'var(--font-ui)', fontSize: 11, letterSpacing: '0.4em', textTransform: 'uppercase', color: 'var(--c-gold-deep)', marginBottom: 12 }}>
              Über mich
            </div>
          </Reveal>
          <Reveal delay={120}>
            <p className="about-lead">Hallo und schön, dass du da bist</p>
            <p>Ich lese schon, solange ich denken kann. Manchmal verschlinge ich mehrere Bücher in kürzester Zeit, manchmal ziehe ich mich tagelang zurück, um ganz bewusst nur ein paar wenige Seiten zu genießen. Ich bin keine Leserin, die durch die Seiten hetzt – ich lese gern langsam, entdecke Geschichten mehrfach und liebe es so sehr, dass ich manche Herzensbücher gleich in zwei Sprachen (auf Deutsch und Russisch) in meinem Regal stehen habe.</p>
            <p>Für mich ist ein Buch kein Konsumgut, sondern ein Gefühl. Ich liebe den Zauber, ganz unvoreingenommen durch Buchhandlungen zu stöbern, mich von Farben und Titeln treiben zu lassen.</p>
          </Reveal>
          <Reveal delay={200}>
            <h3 className="about-subhead">Wie alles begann: Das Journal und die App</h3>
            <p>Weil meine Gedanken zu den gelesenen Büchern irgendwann mehr Platz brauchten, habe ich vor rund einem Jahr beschlossen, ihnen ein echtes Zuhause zu geben. So ist mein eigenes, gedrucktes Book Journal entstanden: „My life is all Booked". Da man seine gelesenen Schätze aber auch gerne unterwegs festhalten möchte, ist daraus inzwischen sogar eine eigene kleine App für den Google Play Store gewachsen (und die Version für Apple ist auch schon in Arbeit!).</p>
            <p>Dieser Blog ist nun die logische Fortsetzung davon – mein digitales Lesetagebuch. Ein ruhiger Ort im lauten Internet, an dem ich all die Geschichten sammle, die mich auf die eine oder andere Weise berührt haben. Hier halte ich fest, was mich tief getroffen, was mich vielleicht auch mal gelangweilt hat, und welche Sätze ich am liebsten für immer verewigen möchte.</p>
          </Reveal>
          <Reveal delay={280}>
            <p>Du wirst hier vor allem eine sorgsam ausgewählte Mischung finden:</p>
            <ul className="about-list">
              <li><strong>Fesselnde Thriller &amp; Romantic Suspense</strong> – Geschichten voller Geheimnisse, die mich bis tief in die Nacht wachhalten.</li>
              <li><strong>Vintage-Schätze, magische Welten &amp; Klassiker</strong> – alles, was eine wunderbare Atmosphäre verströmt, Tiefgang hat und nach altem Papier riecht.</li>
            </ul>
            <p>Ich glaube fest daran, dass Bücher uns genau zur richtigen Zeit finden. Wenn du also eine Empfehlung hast, bei der du das Gefühl hattest, die Welt um dich herum zu vergessen: Schreib mir. Ich sammle sie alle.</p>
            <p>Schnapp dir eine Tasse Kaffee und lass uns gemeinsam stöbern.</p>
          </Reveal>
          <Reveal delay={360}>
            <div className="signature-intro">Alles Liebe,</div>
            <div className="signature">— Irina</div>
          </Reveal>
        </div>
      </div>
    </main>);

}

function ContactPage() {
  const [sent, setSent] = React.useState(false);
  return (
    <main className="page contact">
      <Reveal>
        <div style={{ fontFamily: 'var(--font-ui)', fontSize: 11, letterSpacing: '0.4em', textTransform: 'uppercase', color: 'var(--c-gold-deep)', marginBottom: 12 }}>
          Schreib mir
        </div>
        <h2>Eine Nachricht <em style={{ fontFamily: 'var(--font-script)', fontStyle: 'normal', fontSize: '1.2em', color: 'var(--c-gold-deep)' }}>hinterlassen</em></h2>
        <p className="lead">Buchempfehlungen, Korrekturen, Lesezirkel-Einladungen oder einfach ein Hallo — alles willkommen.</p>
      </Reveal>
      <Reveal delay={150}>
        <div className="contact-card">
          {sent ?
          <div style={{ textAlign: 'center', padding: '40px 0' }}>
              <Ornament size={80} />
              <h3 style={{ fontFamily: 'var(--font-display)', fontStyle: 'italic', fontSize: 36, margin: '20px 0 8px' }}>Vielen Dank!</h3>
              <p style={{ fontStyle: 'italic', color: 'var(--c-muted)' }}>Deine Nachricht ist auf dem Weg. Ich antworte, sobald die Teekanne leer ist.</p>
              <button className="send-btn" style={{ marginTop: 24 }} onClick={() => setSent(false)}>Neue Nachricht</button>
            </div> :

          <form onSubmit={(e) => {e.preventDefault();setSent(true);}}>
              <div className="form-row">
                <label>Dein Name</label>
                <input type="text" placeholder="z. B. Helena" required />
              </div>
              <div className="form-row">
                <label>E-Mail</label>
                <input type="email" placeholder="lese@freundin.de" required />
              </div>
              <div className="form-row">
                <label>Buch-Empfehlung oder Nachricht</label>
                <textarea placeholder="Erzähl mir vom letzten Buch, das du nicht weglegen konntest…" required />
              </div>
              <div style={{ textAlign: 'right' }}>
                <button type="submit" className="send-btn">Absenden →</button>
              </div>
            </form>
          }
        </div>
      </Reveal>
      <Reveal delay={300}>
        <div className="contact-channels">
          <a href="#">Instagram</a>
          <a href="#">Goodreads</a>
          <a href="#">Newsletter</a>
        </div>
      </Reveal>
    </main>);

}

function BlogPage() {
  const posts = window.POSTS || [];
  const [openPost, setOpenPost] = React.useState(null);
  return (
    <main className="page blog">
      <Reveal className="blog-intro">
        <div className="eyebrow">Geschrieben & gedacht</div>
        <h2>Aus dem <em>Tagebuch</em></h2>
        <p>Lese-Rituale und Gedanken zwischen den Büchern. Mit Kaffee, mit Notizen & mit dem Gefühl, für einen Moment woanders zu sein.</p>
      </Reveal>

      <div className="blog-list">
        {posts.length === 0 ?
        <div className="blog-post-empty">
            <Ornament size={70} />
            <p>Hier wachsen bald Artikel.</p>
            <p style={{ fontSize: 14 }}>Der erste Eintrag ist noch in der Schublade — bald geht's los.</p>
          </div> :
        posts.map((post, i) => {
          const d = new Date(post.date);
          const day = d.getDate().toString().padStart(2, '0');
          const month = d.toLocaleDateString('de-DE', { month: 'short' });
          const year = d.getFullYear();
          const hasArticle = !!post.body;
          return (
            <Reveal as="article" className="blog-post" key={post.id} delay={i * 80}>
              <div className="blog-post-date">
                <div className="day">{day}</div>
                <div className="month">{month}</div>
                <div className="year">{year}</div>
              </div>
              <div className="blog-post-content">
                <div className="blog-post-cat">{post.category || 'Was nach dem Lesen bleibt'}</div>
                {post.section && <div className="blog-post-section">{post.section}</div>}
                <h3 className={post.section ? 'compact' : ''}>{post.title}</h3>
                <p className="blog-post-excerpt">{post.excerpt}</p>
                <div className="blog-post-meta">
                  <span>{post.readTime} Lesezeit</span>
                  <a className="read-more"
                    href="#"
                    onClick={(e) => {
                      e.preventDefault();
                      if (hasArticle) setOpenPost(post);
                    }}
                    style={{ opacity: hasArticle ? 1 : 0.5, cursor: hasArticle ? 'pointer' : 'default' }}>
                    Weiterlesen →
                  </a>
                </div>
              </div>
            </Reveal>);

        })}
      </div>

      <BlogPostModal post={openPost} onClose={() => setOpenPost(null)} />
    </main>);

}

function slugifyCat(s) {
  return String(s).toLowerCase()
    .replace(/[äàá]/g, 'a').replace(/[öó]/g, 'o').replace(/[üú]/g, 'u').replace(/ß/g, 'ss')
    .replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
}

function CategoryPage({ category, setPage }) {
  const quote = (window.CATEGORY_QUOTES || {})[category] || '';
  const quoteHeading = (window.CATEGORY_QUOTE_HEADINGS || {})[category] || '';
  const heading = (window.CATEGORY_TITLES || {})[category] || category;
  const rawArticles = (window.CATEGORY_ARTICLES || {})[category] || null;
  // Accept both a single article object and an array of articles
  const articles = rawArticles ? (Array.isArray(rawArticles) ? rawArticles : [rawArticles]) : [];
  const isVibe = category === 'Bücher nach Vibe';
  const vibes = window.VIBES || [];

  // Blog posts tagged with this category as their section (newest first)
  const [openPost, setOpenPost] = React.useState(null);
  const [openVibe, setOpenVibe] = React.useState(null);
  React.useEffect(() => { window.scrollTo({ top: 0, behavior: 'smooth' }); }, [openVibe]);
  const linkedPosts = (window.POSTS || [])
    .filter((p) => (p.section || '') === category)
    .sort((a, b) => (b.date || '').localeCompare(a.date || ''));

  const fmtDate = (d) => {
    if (!d) return '';
    const dt = new Date(d);
    if (isNaN(dt)) return d;
    return dt.toLocaleDateString('de-DE', { day: '2-digit', month: 'long', year: 'numeric' });
  };

  return (
    <main className={`page category-page${isVibe ? ' category-page--vibes' : ''}`}>
      <section className="cat-hero">
        <h1 className="cat-hero-title">{openVibe ? openVibe.label : heading}</h1>
        <div className="ornament-divider" style={{ maxWidth: 320, margin: '20px auto 32px' }}>
          <Ornament size={64} />
        </div>

        {!isVibe && quote && (
          <figure className="cat-quote">
            <div className="cat-quote-mark" aria-hidden="true">&ldquo;</div>
            {quoteHeading && <div className="cat-quote-heading">{quoteHeading}</div>}
            <blockquote>{quote}</blockquote>
          </figure>
        )}

        {articles.map((article, ai) => (
          <article className="cat-article" key={`art-${ai}`}>
            {ai > 0 && (
              <div className="ornament-divider cat-article-sep" style={{ maxWidth: 240, margin: '0 auto 36px' }}>
                <Ornament size={48} />
              </div>
            )}
            {article.date && <div className="cat-article-date">{fmtDate(article.date)}</div>}
            <h2 className="cat-article-heading">{article.heading}</h2>
            {article.intro && article.intro.map((p, i) => <p key={`in-${i}`}>{p}</p>)}
            {article.books && article.books.map((b, i) => (
              <div className="cat-article-book" key={`bk-${i}`}>
                <div className="cat-article-book-photo">
                  <image-slot
                    id={`article-${slugifyCat(category)}-${ai + 1}-book-${i + 1}`}
                    shape="rect"
                    fit="cover"
                    placeholder="Cover hierher ziehen"
                    style={{ width: '100%', height: '100%', display: 'block' }}>
                  </image-slot>
                </div>
                <div className="cat-article-book-text">
                  <h3 className="cat-article-book-title">{i + 1}. {b.title} <span>von {b.author}</span></h3>
                  <p className="cat-article-vibe"><strong>Der Vibe:</strong> {b.vibe}</p>
                  <p className="cat-article-why"><strong>Darum durfte es mit:</strong> {b.why}</p>
                </div>
              </div>
            ))}
            {article.films && article.films.map((f, i) => (
              <div className="cat-article-book" key={`fm-${i}`}>
                <div className="cat-article-book-photo">
                  <image-slot
                    id={`article-${slugifyCat(category)}-${ai + 1}-film-${i + 1}`}
                    shape="rect"
                    fit="cover"
                    placeholder="Poster hierher ziehen"
                    style={{ width: '100%', height: '100%', display: 'block' }}>
                  </image-slot>
                </div>
                <div className="cat-article-book-text">
                  <h3 className="cat-article-book-title">{i + 1}. {f.title}</h3>
                  <p className="cat-article-why"><strong>Basiert auf:</strong> {f.basedOn}</p>
                  <p className="cat-article-vibe"><strong>Wo &amp; Wann:</strong> {f.when}</p>
                  <p className="cat-article-why"><strong>Worum geht's kurz &amp; knapp:</strong> {f.plot}</p>
                  <p className="cat-article-why"><strong>Meine Lese-Empfehlung:</strong> {f.rec}</p>
                </div>
              </div>
            ))}
            {article.outro && article.outro.map((p, i) => <p key={`out-${i}`}>{p}</p>)}
            {article.signoff && <p className="cat-article-signoff">{article.signoff}</p>}
            {article.signature && <div className="cat-article-signature">{article.signature}</div>}
            <CommentSection postId={`news-${slugifyCat(category)}-${ai + 1}`} />
          </article>
        ))}

        {linkedPosts.length > 0 && (
          <div className="cat-posts">
            {linkedPosts.map((post) => (
              <article className="cat-post-card" key={post.id}
                onClick={() => setOpenPost(post)}>
                <div className="cat-post-date">{fmtDate(post.date)}</div>
                <h3 className="cat-post-title">{post.title}</h3>
                <p className="cat-post-excerpt">{post.excerpt}</p>
                <span className="cat-post-link">Weiterlesen →</span>
              </article>
            ))}
          </div>
        )}

        {isVibe && !openVibe && (
          <>
            <p className="cat-sub">
              Vier Stimmungen, vier Lesewelten. Such dir aus, wonach dir gerade ist.
            </p>
            <div className="vibe-grid">
              {vibes.map((v) => (
                <article key={v.label} className="vibe-card"
                  style={{
                    '--vbg': v.bg,
                    '--vink': v.ink,
                    '--vaccent': v.accent
                  }}>
                  <div className="vibe-card-glyph" aria-hidden="true">{v.glyph}</div>
                  <h3 className="vibe-card-title">{v.label}</h3>
                  <p className="vibe-card-desc">{v.desc}</p>
                  <a href="#" className="vibe-card-link"
                    onClick={(e) => { e.preventDefault(); setOpenVibe(v); }}>
                    Bücher entdecken →
                  </a>
                </article>
              ))}
            </div>
          </>
        )}

        {isVibe && openVibe && (() => {
          const vslug = slugifyCat(openVibe.label);
          return (
            <div className="vibe-detail" style={{ '--vaccent': openVibe.accent, '--vbg': openVibe.bg, '--vink': openVibe.ink }}>
              <div className="vibe-detail-glyph" aria-hidden="true">{openVibe.glyph}</div>
              <p className="vibe-detail-intro">{openVibe.intro || openVibe.desc}</p>
              <div className="vibe-detail-photo">
                <image-slot
                  id={`vibe-${vslug}-photo`}
                  shape="rect"
                  fit="cover"
                  placeholder="Bild ablegen"
                  style={{ width: '100%', height: '100%', display: 'block' }}>
                </image-slot>
              </div>
              <div className="vibe-detail-label">Darum geht's</div>
              {openVibe.darumTitle && <h3 className="vibe-detail-rec-title">{openVibe.darumTitle}</h3>}
              <p className="vibe-detail-text">{openVibe.darum || ''}</p>
              <CommentSection postId={`vibe-${vslug}`} />
            </div>
          );
        })()}

        <a href="#" className="cat-back"
          onClick={(e) => { e.preventDefault(); if (openVibe) { setOpenVibe(null); } else { setPage('home'); } }}>
          {openVibe ? '← Zurück zu Bücher nach Vibe' : '← Zurück zur Startseite'}
        </a>
      </section>
      <BlogPostModal post={openPost} onClose={() => setOpenPost(null)} />
    </main>
  );
}

function App() {
  const [page, setPage] = React.useState('home');
  const [newsCategory, setNewsCategory] = React.useState(null);
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  React.useEffect(() => {
    document.body.dataset.palette = t.palette;
  }, [t.palette]);

  React.useEffect(() => {
    document.documentElement.style.setProperty('--font-brand-pick', `'${t.brandFont}'`);
  }, [t.brandFont]);

  React.useEffect(() => {
    window.scrollTo({ top: 0, behavior: 'smooth' });
  }, [page]);

  return (
    <div className={`${t.layout}-layout`}>
      <Header page={page} setPage={setPage} setNewsCategory={setNewsCategory} />
      {page === 'home' && <HomePage key="home" />}
      {page === 'about' && <AboutPage key="about" />}
      {page === 'blog' && <BlogPage key="blog" />}
      {page === 'contact' && <ContactPage key="contact" />}
      {page === 'category' && <CategoryPage key={`cat-${newsCategory}`} category={newsCategory} setPage={setPage} />}
      <Footer />
      <TweaksPanel title="Tweaks">
        <TweakSection label="Farbpalette" />
        <TweakColor label="Theme"
        value={
        t.palette === 'navy' ? ['#1a2438', '#f5efe0', '#c9a961'] :
        t.palette === 'burgundy' ? ['#4a1a1f', '#f3e9d8', '#b8924a'] :
        t.palette === 'forest' ? ['#1b3324', '#f0ead7', '#b89352'] :
        t.palette === 'rosetea' ? ['#7a4d56', '#fdf6f0', '#c89a8a'] :
        t.palette === 'sage' ? ['#556a52', '#f8f4ea', '#a89a6e'] :
        t.palette === 'lavender' ? ['#685a7a', '#faf5f0', '#b09c8a'] :
        t.palette === 'linen' ? ['#6a5440', '#fbf5e8', '#b89a6a'] :
        t.palette === 'cocoa' ? ['#5c4332', '#faf2e6', '#b08862'] :
        t.palette === 'white' ? ['#1a2438', '#ffffff', '#c9a961'] :
        ['#594055', '#f9f1ec', '#b08a78']
        }
        options={[
        ['#1a2438', '#f5efe0', '#c9a961'],
        ['#4a1a1f', '#f3e9d8', '#b8924a'],
        ['#1b3324', '#f0ead7', '#b89352'],
        ['#7a4d56', '#fdf6f0', '#c89a8a'],
        ['#556a52', '#f8f4ea', '#a89a6e'],
        ['#685a7a', '#faf5f0', '#b09c8a'],
        ['#6a5440', '#fbf5e8', '#b89a6a'],
        ['#5c4332', '#faf2e6', '#b08862'],
        ['#594055', '#f9f1ec', '#b08a78'],
        ['#1a2438', '#ffffff', '#c9a961']]
        }
        onChange={(v, i) => {
          const order = ['navy', 'burgundy', 'forest', 'rosetea', 'sage', 'lavender', 'linen', 'cocoa', 'twilight', 'white'];
          setTweak('palette', order[i] || 'navy');
        }} />
        
        <TweakSection label="Layout der Buchliste" />
        <TweakRadio label="Stil" value={t.layout}
        options={[
        { value: 'magazine', label: 'Magazin' },
        { value: 'list', label: 'Liste' },
        { value: 'shelf', label: 'Regal' }]
        }
        onChange={(v) => setTweak('layout', v)} />
        
        <TweakSection label="Slogan-Schrift" />
        <TweakSelect label="Schriftart" value={t.brandFont}
        options={['Allura', 'Great Vibes', 'Pinyon Script', 'Parisienne', 'Mrs Saint Delafield', 'Tangerine', 'Alex Brush', 'Italianno']}
        onChange={(v) => setTweak('brandFont', v)} />
        
      </TweaksPanel>
    </div>);

}

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