import {readFile,writeFile,mkdir} from 'node:fs/promises';
import {join,relative} from 'node:path';
const root=process.cwd();
const outRoot=process.argv[2]?join(root,process.argv[2]):join(root,'dist');
const posts=JSON.parse(await readFile(join(root,'content/posts.json'),'utf8'));
const config=JSON.parse(await readFile(join(root,'content/site-config.json'),'utf8'));
const tr=JSON.parse(await readFile(join(root,'content/translations.json'),'utf8'));
const fixedPalette="court-contrast",fixedAppearance="dark",themeColour="#000000";
const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
const renderBody=blocks=>blocks.map(b=>b.type==='heading'?`<h2>${esc(b.text)}</h2>`:b.type==='quote'?`<blockquote>${esc(b.text)}</blockquote>`:`<p${b.type==='lead'?' class="lead"':''}>${esc(b.text)}</p>`).join('');
function controls(locale,prefix,altHref){return `<div class="preference-controls"><a class="utility-button language-button" href="${esc(altHref)}" hreflang="${locale==='ja'?'en-GB':'ja'}">${locale==='ja'?'EN':'日本語'}</a></div>`}
function comment(locale){const t=tr[locale];return `<section class="comment-section post-page-comments" aria-labelledby="comment-title"><div class="comment-head"><div><h2 id="comment-title"><span data-comment-count>0</span> <span data-i18n="posts.comments">${esc(t['posts.comments'])}</span></h2></div><div class="comment-controls"><select data-comment-sort aria-label="Sort comments"><option value="newest" data-i18n="comments.newest">${esc(t['comments.newest'])}</option><option value="oldest" data-i18n="comments.oldest">${esc(t['comments.oldest'])}</option></select><button class="button secondary" type="button" data-comment-compose data-i18n="comments.leave">${esc(t['comments.leave'])}</button></div></div><p class="local-notice" data-i18n="comments.local">${esc(t['comments.local'])}</p><div class="comment-list" data-comment-list></div><button class="text-action" type="button" data-comment-load hidden data-i18n="comments.load">${esc(t['comments.load'])}</button><form class="comment-form" data-comment-form hidden novalidate><div class="form-grid"><div class="field"><label for="comment-name" data-i18n="comments.name">${esc(t['comments.name'])}</label><input id="comment-name" name="displayName" maxlength="80" required data-i18n-placeholder="comments.placeholder.name" placeholder="${esc(t['comments.placeholder.name'])}"></div><div class="field"><label for="comment-website" data-i18n="comments.website">${esc(t['comments.website'])}</label><input id="comment-website" name="website" type="url" maxlength="220" data-i18n-placeholder="comments.placeholder.website" placeholder="https://example.com"></div><div class="field field-wide"><label for="comment-body" data-i18n="comments.body">${esc(t['comments.body'])}</label><textarea id="comment-body" name="body" maxlength="1200" required data-i18n-placeholder="comments.placeholder.body" placeholder="${esc(t['comments.placeholder.body'])}"></textarea><small><output data-comment-counter>0</output><span data-i18n="comments.limit">${esc(t['comments.limit'])}</span></small></div></div><label class="check"><input name="consent" type="checkbox" required><span data-i18n="comments.consent">${esc(t['comments.consent'])}</span></label><div class="form-actions"><button class="button primary" type="submit" data-i18n="comments.submit">${esc(t['comments.submit'])}</button><button class="button secondary" type="button" data-comment-cancel data-i18n="close">${esc(t.close)}</button></div><p class="form-status" data-comment-status role="status" aria-live="polite"></p></form></section>`}
for(const post of posts.filter(p=>p.status==='published')){
  for(const locale of ['en','ja']){
    const isJa=locale==='ja',dir=isJa?'ja':'posts',relPrefix=isJa?'../../../':'../../',route=isJa?`ja/posts/${post.slug}`:`posts/${post.slug}`,canonical=`${config.brand.url.replace(/\/$/,'')}/${route}/`,other=isJa?`../../../posts/${post.slug}/`:`../../ja/posts/${post.slug}/`,t=tr[locale];
    const pageDir=join(outRoot,route);await mkdir(pageDir,{recursive:true});
    const related=posts.filter(p=>p.slug!==post.slug&&p.status==='published').slice(0,2).map(p=>`<a class="related-link" href="${isJa?'../../../ja/posts':'..'}/${p.slug}/"><span>${esc(p.section[locale])}</span><strong>${esc(p.title[locale])}</strong></a>`).join('');
    const image=`${relPrefix}${post.image}`,cardUrl=`${config.brand.url.replace(/\/$/,'')}/assets/img/calling-cards/${post.slug}/social-1200x630.png`,modified=post.dateModified!==post.datePublished?`<span>${esc(t['posts.updated'])}: ${esc(new Intl.DateTimeFormat(isJa?'ja-JP':'en-GB',{dateStyle:'long'}).format(new Date(post.dateModified+'T12:00:00Z')))}</span>`:'';
    const html=`<!doctype html><html lang="${isJa?'ja':'en-GB'}" class="no-js" data-palette="${fixedPalette}" data-appearance="${fixedAppearance}" data-theme-edition="${fixedPalette}-${fixedAppearance}" data-locale="${locale}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><meta name="color-scheme" content="${fixedAppearance}"><meta name="theme-color" content="${themeColour}"><title>${esc(post.title[locale])} | ${esc(config.brand.name)}</title><meta name="description" content="${esc(post.excerpt[locale])}"><meta name="robots" content="index,follow,max-image-preview:large"><link rel="canonical" href="${esc(canonical)}"><link rel="alternate" hreflang="en-GB" href="${esc(config.brand.url.replace(/\/$/,'')+'/posts/'+post.slug+'/')}"><link rel="alternate" hreflang="ja" href="${esc(config.brand.url.replace(/\/$/,'')+'/ja/posts/'+post.slug+'/')}"><link rel="alternate" hreflang="x-default" href="${esc(config.brand.url.replace(/\/$/,'')+'/posts/'+post.slug+'/')}"><meta property="og:type" content="article"><meta property="og:title" content="${esc(post.title[locale])}"><meta property="og:description" content="${esc(post.excerpt[locale])}"><meta property="og:url" content="${esc(canonical)}"><meta property="og:image" content="${esc(cardUrl)}"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta property="og:image:alt" content="${esc(post.imageAlt[locale])}"><meta property="article:published_time" content="${post.datePublished}"><meta property="article:modified_time" content="${post.dateModified}"><meta property="article:section" content="${esc(post.section[locale])}"><meta name="twitter:card" content="summary_large_image"><link rel="icon" href="${relPrefix}assets/img/favicon.svg" type="image/svg+xml"><script>(()=>{document.documentElement.classList.replace('no-js','js')})();</script>${['tokens','palettes','base','layout','components','motion','print'].map(n=>`<link rel="stylesheet" href="${relPrefix}assets/css/${n}.css">`).join('')}<script type="application/ld+json">${JSON.stringify({'@context':'https://schema.org','@type':'BlogPosting','headline':post.title[locale],'description':post.excerpt[locale],'datePublished':post.datePublished,'dateModified':post.dateModified,'inLanguage':isJa?'ja':'en-GB','mainEntityOfPage':canonical,'image':[cardUrl,`${config.brand.url.replace(/\/$/,'')}/assets/img/calling-cards/${post.slug}/square-1200.png`,`${config.brand.url.replace(/\/$/,'')}/assets/img/calling-cards/${post.slug}/wide-1600x900.png`],'author':{'@type':'Person','name':post.author[locale]},'publisher':{'@type':'Organization','name':config.brand.name,'url':config.brand.url}})}</script></head><body class="standalone-post-page" data-edition="commercial" data-post-slug="${post.slug}"><a class="skip-link" href="#article" data-i18n="skip">${esc(t.skip)}</a><header class="site-header"><div class="header-inner shell"><a class="brand" href="${relPrefix}index.html#posts"><span class="brand-copy"><strong data-brand-name>${esc(config.brand.name)}<sup>®</sup></strong><small data-brand-descriptor>${esc(config.brand.descriptor)}</small></span></a><nav class="desktop-nav"><a href="${relPrefix}index.html#posts">← ${esc(t['posts.back'])}</a></nav><div class="header-actions">${controls(locale,relPrefix,other)}</div></div></header><main class="post-page-main" id="article"><article class="post-page-article" data-direct-article><figure class="post-hero"><img src="${image}" alt="${esc(post.imageAlt[locale])}" width="1600" height="1000" style="object-position:${post.focalPoint.x*100}% ${post.focalPoint.y*100}%"><figcaption><span data-direct-section>${esc(post.section[locale])}</span><time data-direct-date datetime="${post.datePublished}">${esc(new Intl.DateTimeFormat(isJa?'ja-JP':'en-GB',{dateStyle:'long'}).format(new Date(post.datePublished+'T12:00:00Z')))}</time></figcaption></figure><div class="post-content"><h1>${esc(post.title[locale])}</h1><div class="post-byline"><span>${esc(post.author[locale])}</span><span>${Math.max(1,Math.ceil(post.body[locale].reduce((s,b)=>s+b.text.length,0)/(isJa?500:1000)))} ${esc(t['posts.min'])}</span>${modified}</div><div class="post-page-tools"><button class="button primary" type="button" data-direct-share><span data-i18n="posts.share">${esc(t['posts.share'])}</span></button><button class="button secondary" type="button" data-direct-print><span data-i18n="posts.print">${esc(t['posts.print'])}</span></button><button class="button secondary" type="button" data-direct-copy data-i18n="share.copy">${esc(t['share.copy'])}</button></div><div class="share-options" data-direct-share-panel hidden><a data-share-link="email" target="_blank" rel="noopener"><span>${esc(t['share.email'])}</span></a><a data-share-link="linkedin" target="_blank" rel="noopener"><span>LinkedIn</span></a><a data-share-link="x" target="_blank" rel="noopener"><span>X</span></a><a data-share-link="bluesky" target="_blank" rel="noopener"><span>Bluesky</span></a></div><div class="post-body">${renderBody(post.body[locale])}</div>${comment(locale)}<section class="related-posts"><h2 data-i18n="posts.related">${esc(t['posts.related'])}</h2><div>${related}</div></section></div></article></main><footer class="post-page-footer"><div class="shell"><span>© <span data-year></span> ${esc(config.brand.name)}</span><span>Designed by <a href="https://iusmusic.com" target="_blank" rel="noopener noreferrer">I/US brand</a>.</span></div></footer><div class="print-document" data-print-document></div>${['site-config','projects','posts','translations'].map(n=>`<script src="${relPrefix}assets/js/data/${n}.js" defer></script>`).join('')}${['state','theme','i18n','comments','post-page'].map(n=>`<script src="${relPrefix}assets/js/${n}.js" defer></script>`).join('')}</body></html>`;
    await writeFile(join(pageDir,'index.html'),html);
  }
}
console.log(`Generated ${posts.filter(p=>p.status==='published').length*2} canonical post pages.`);
