const INK = '#16233F';
const cfg = window.PUBLIC_CONFIG || {};
const blogDb = window.supabase && cfg.SUPABASE_URL && cfg.SUPABASE_ANON_KEY
  ? window.supabase.createClient(cfg.SUPABASE_URL, cfg.SUPABASE_ANON_KEY) : null;

function formatDate(value) {
  if (!value) return '';
  return new Date(value).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
}

function readingTime(content) {
  const words = String(content || '').trim().split(/\s+/).filter(Boolean).length;
  return Math.max(1, Math.ceil(words / 220)) + ' min read';
}

function setArticleMeta(post) {
  document.title = post ? (post.seo_title || post.title) + ' | Audit Me' : 'Blog | Audit Me';
  const desc = post && (post.seo_description || post.excerpt);
  if (desc) document.querySelector('meta[name="description"]').setAttribute('content', desc);
  const canonical = document.querySelector('link[rel="canonical"]');
  if (canonical && post) canonical.href = 'https://www.auditmeshow.com/blog?post=' + encodeURIComponent(post.slug);
  const existingSchema = document.getElementById('article-json-ld');
  if (existingSchema) existingSchema.remove();
  if (post && post.schema_json) {
    try {
      const parsed = typeof post.schema_json === 'string' ? JSON.parse(post.schema_json) : post.schema_json;
      const script = document.createElement('script');
      script.id = 'article-json-ld'; script.type = 'application/ld+json';
      script.textContent = JSON.stringify(parsed).replace(/</g, '\\u003c');
      document.head.appendChild(script);
    } catch (_) { /* Invalid legacy schema is ignored rather than breaking the article. */ }
  }
}

function RichText({ text }) {
  if (/<\/?(?:p|h[23]|ul|ol|li|blockquote|strong|em|a|div|br)\b/i.test(String(text || ''))) {
    const doc = new DOMParser().parseFromString('<div>' + String(text || '') + '</div>', 'text/html');
    const root = doc.body.firstElementChild;
    const allowed = new Set(['P','BR','HR','H2','H3','STRONG','B','EM','I','U','S','STRIKE','UL','OL','LI','BLOCKQUOTE','A','IMG','DIV']);
    Array.from(root.querySelectorAll('*')).forEach((node) => {
      if (!allowed.has(node.tagName)) { node.replaceWith(...Array.from(node.childNodes)); return; }
      Array.from(node.attributes).forEach((attr) => { const href=node.tagName==='A'&&attr.name==='href'&&/^https?:\/\//i.test(attr.value), linkAttr=node.tagName==='A'&&['target','rel'].includes(attr.name), imageAttr=node.tagName==='IMG'&&((attr.name==='src'&&/^https?:\/\//i.test(attr.value))||['alt','loading'].includes(attr.name)), align=attr.name==='style'&&/^text-align:\s*(left|center|right|justify);?$/i.test(attr.value); if(!href&&!linkAttr&&!imageAttr&&!align)node.removeAttribute(attr.name); });
      if (node.tagName === 'A') { node.target = '_blank'; node.rel = 'noopener noreferrer'; }
      if (node.tagName === 'IMG') node.loading = 'lazy';
    });
    return <div dangerouslySetInnerHTML={{__html:root.innerHTML}}/>;
  }
  const lines = String(text || '').replace(/\r/g, '').split('\n');
  const nodes = [];
  let list = [], listType = 'ul';
  const inline = (value) => {
    const parts = String(value).split(/(\*\*[^*]+\*\*|\*[^*]+\*|\[[^\]]+\]\(https?:\/\/[^)]+\))/g);
    return parts.map((part, i) => {
      const bold = part.match(/^\*\*(.+)\*\*$/);
      if (bold) return <strong key={i}>{bold[1]}</strong>;
      const italic = part.match(/^\*([^*]+)\*$/);
      if (italic) return <em key={i}>{italic[1]}</em>;
      const link = part.match(/^\[([^\]]+)\]\((https?:\/\/[^)]+)\)$/);
      if (link) return <a key={i} href={link[2]} target="_blank" rel="noopener noreferrer">{link[1]}</a>;
      return part;
    });
  };
  const flush = () => { if (list.length) { const items=list.map((x,i)=><li key={i}>{inline(x)}</li>); nodes.push(listType==='ol'?<ol key={'ol'+nodes.length}>{items}</ol>:<ul key={'ul'+nodes.length}>{items}</ul>); list = []; } };
  lines.forEach((line, i) => {
    if (/^[-*] /.test(line)) { if(list.length&&listType!=='ul')flush();listType='ul';list.push(line.slice(2));return; }
    if (/^\d+\. /.test(line)) { if(list.length&&listType!=='ol')flush();listType='ol';list.push(line.replace(/^\d+\. /,''));return; }
    flush();
    if (!line.trim()) return;
    if (line.startsWith('## ')) nodes.push(<h2 key={i}>{inline(line.slice(3))}</h2>);
    else if (line.startsWith('### ')) nodes.push(<h3 key={i}>{inline(line.slice(4))}</h3>);
    else if (line.startsWith('> ')) nodes.push(<blockquote key={i}>{inline(line.slice(2))}</blockquote>);
    else {
      const aligned=line.match(/^\[(left|center|right|justify)\]([\s\S]*)\[\/\1\]$/);
      nodes.push(<p key={i} style={aligned?{textAlign:aligned[1]}:undefined}>{inline(aligned?aligned[2]:line)}</p>);
    }
  });
  flush();
  return <>{nodes}</>;
}

function Header() {
  return <header className="blog-header">
    <a href="/"><img src="assets/logo.png" alt="Audit Me" /></a>
    <nav className="blog-nav" aria-label="Main navigation"><a href="/blog">Blog</a><a className="blog-apply" href="/#apply">Apply now</a></nav>
  </header>;
}

function Footer() {
  return <footer className="blog-footer"><a href="/"><img src="assets/logo.png" alt="Audit Me" /></a><p>Real stories, sharp audits, and honest conversations.</p></footer>;
}

function PostCard({ post }) {
  return <a className="post-card" href={'/blog?post=' + encodeURIComponent(post.slug)}>
    <div className="post-image">{post.cover_image ? <img src={post.cover_image} alt={post.cover_image_alt || ''} /> : <div className="post-image-fallback">Audit this.</div>}</div>
    <div className="post-card-body">
      <div className="post-meta"><span>{post.category || 'The Audit'}</span><span>•</span><span>{formatDate(post.published_at)}</span></div>
      <h3>{post.title}</h3><p>{post.excerpt}</p><span className="read-more">Read the full audit →</span>
    </div>
  </a>;
}

function Blog() {
  const [state, setState] = React.useState({ loading: true, posts: [], error: '' });
  const slug = new URLSearchParams(window.location.search).get('post');
  React.useEffect(() => {
    if (!blogDb) { setState({ loading: false, posts: [], error: 'Blog configuration is missing.' }); return; }
    let query = blogDb.from('blog_posts').select('*').eq('status', 'published');
    query = slug ? query.eq('slug', slug).limit(1) : query.order('published_at', { ascending: false });
    query.then(({ data, error }) => setState({ loading: false, posts: data || [], error: error ? error.message : '' }));
  }, [slug]);
  if (state.loading) return <div className="blog-shell"><Header/><main className="blog-loading">Loading the audit…</main></div>;
  if (state.error) return <div className="blog-shell"><Header/><main className="blog-error">We couldn't load the blog.<br/><small>{state.error}</small></main></div>;
  if (slug) {
    const post = state.posts[0];
    if (!post) return <div className="blog-shell"><Header/><main className="blog-empty"><h1>Post not found.</h1><p><a href="/blog">Return to the blog</a></p></main></div>;
    setArticleMeta(post);
    return <div className="blog-shell article"><Header/>
      <article><div className="article-hero"><div className="article-hero-inner"><span className="eyebrow">{post.category || 'The Audit'}</span><h1>{post.title}</h1><p className="article-dek">{post.excerpt}</p><div className="article-byline">By {post.author || 'Audit Me'} · Published {formatDate(post.published_at)}{post.updated_at&&post.updated_at!==post.published_at?' · Updated '+formatDate(post.updated_at):''} · {readingTime(post.content)}</div></div></div>
      {post.cover_image && <div className="article-cover"><img src={post.cover_image} alt={post.cover_image_alt || post.title}/></div>}
      <div className="article-body"><RichText text={post.content}/>{(post.author_bio||post.author_image||post.author_role)&&<aside className="article-author">{post.author_image?<img src={post.author_image} alt={post.author||'Article author'}/>:<div className="author-fallback">{String(post.author||'AM').split(/\s+/).map(x=>x[0]).join('').slice(0,2)}</div>}<div><span>Written by</span><h3>{post.author||'Audit Me'}</h3>{post.author_role&&<strong>{post.author_role}</strong>}{post.author_bio&&<p>{post.author_bio}</p>}</div></aside>}<a className="article-back" href="/blog">← Back to all stories</a></div></article><Footer/>
    </div>;
  }
  setArticleMeta(null);
  return <div className="blog-shell"><Header/><section className="blog-hero"><div className="blog-hero-inner"><span className="eyebrow">Notes from the show</span><h1>Money gets personal.</h1><p>Sharp, honest stories about money, habits, work, and the choices that shape a life—before, during, and after the audit.</p></div></section>
    <main className="blog-main"><div className="blog-section-head"><h2>Latest stories</h2><span className="blog-count">{state.posts.length} {state.posts.length === 1 ? 'story' : 'stories'}</span></div>
    {state.posts.length ? <div className="post-grid">{state.posts.map((p)=><PostCard key={p.id} post={p}/>)}</div> : <div className="blog-empty"><h2>The first story is being audited.</h2><p>Check back soon.</p></div>}</main><Footer/></div>;
}

ReactDOM.createRoot(document.getElementById('blog-root')).render(<Blog/>);
