// Static site generator for artnouveau.in — quiet-luxury editorial design.
// Usage: npm run build  →  regenerates dist/ from src/ + data.
const fs = require('fs');
const path = require('path');

const ROOT = path.join(__dirname, '..');
const SRC = path.join(ROOT, 'src');
const DIST = path.join(ROOT, 'dist');

const site = JSON.parse(fs.readFileSync(path.join(SRC, 'data', 'site.json'), 'utf8'));
const projects = JSON.parse(fs.readFileSync(path.join(SRC, 'data', 'projects.json'), 'utf8'));
const manifest = JSON.parse(fs.readFileSync(path.join(SRC, 'data', 'images.json'), 'utf8'));
const home = JSON.parse(fs.readFileSync(path.join(SRC, 'data', 'home.json'), 'utf8'));
const extra = fs.existsSync(path.join(SRC, 'data', 'images-extra.json'))
  ? JSON.parse(fs.readFileSync(path.join(SRC, 'data', 'images-extra.json'), 'utf8')) : {};

const esc = s => String(s == null ? '' : s)
  .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');

/* ---------- image helpers ---------- */
function entryFor(slug, idx) {
  const list = manifest[slug] || [];
  const e = list[idx];
  return e && e.variants ? e : null;
}
function validIndices(slug) {
  const hidden = (projects.find(p => p.slug === slug) || {}).hiddenIndices || [];
  return (manifest[slug] || []).map((e, i) => (e && e.variants ? i : -1))
    .filter(i => i >= 0 && !hidden.includes(i));
}
function picture(slug, idx, o) {
  const e = entryFor(slug, idx);
  if (!e) return '';
  o = o || {};
  const webps = [], seen = new Set();
  for (const v of e.variants) if (v.format === 'webp' && !seen.has(v.width)) { seen.add(v.width); webps.push(v); }
  const jpg = e.variants.find(v => v.format === 'jpeg');
  const srcset = webps.map(v => `/${v.file} ${v.width}w`).join(', ');
  const attrs = [
    `src="/${jpg.file}"`, `width="${jpg.width}"`, `height="${jpg.height}"`,
    `alt="${esc(o.alt || '')}"`, `decoding="async"`,
    o.eager ? 'fetchpriority="high"' : 'loading="lazy"',
    o.dataAttrs || ''
  ].filter(Boolean).join(' ');
  return `<picture><source type="image/webp" srcset="${srcset}" sizes="${o.sizes || '100vw'}"><img ${attrs}></picture>`;
}
function biggest(slug, idx) {
  const e = entryFor(slug, idx);
  if (!e) return '';
  const w = e.variants.filter(v => v.format === 'webp').sort((a, b) => b.width - a.width)[0];
  return '/' + w.file;
}
function extraPic(key, o) {
  const e = extra[key];
  if (!e || !e.variants) return '';
  o = o || {};
  const webps = [], seen = new Set();
  for (const v of e.variants) if (v.format === 'webp' && !seen.has(v.width)) { seen.add(v.width); webps.push(v); }
  const jpg = e.variants.find(v => v.format === 'jpeg') || webps[0];
  const srcset = webps.map(v => `/${v.file} ${v.width}w`).join(', ');
  return `<picture><source type="image/webp" srcset="${srcset}" sizes="${o.sizes || '100vw'}"><img src="/${jpg.file}" width="${jpg.width}" height="${jpg.height}" alt="${esc(o.alt || '')}" loading="lazy" decoding="async"${o.dataAttrs ? ' ' + o.dataAttrs : ''}></picture>`;
}

/* ---------- shared shell ---------- */
const NAV = [
  ['/projects/', 'projects'], ['/studio/', 'studio'], ['/process/', 'process'],
  [site.tenderUrl, 'tender'], ['/contact/', 'contact'],
];
function navList(current) {
  return NAV.map(([href, label]) => {
    const ext = href.startsWith('http');
    const cur = !ext && href === current ? ' aria-current="page"' : '';
    const rel = ext ? ' rel="noopener"' : '';
    return `<li><a href="${href}"${cur}${rel}>${label}</a></li>`;
  }).join('\n      ');
}
const FAVICON = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23F4F1EA'/%3E%3Cpath d='M8 24 16 8l8 16' fill='none' stroke='%231C1A16' stroke-width='1.5'/%3E%3Ccircle cx='24' cy='24' r='2.5' fill='%237A4A32'/%3E%3C/svg%3E`;

function layout(o) {
  // o: {path, title, desc, body, current, scripts:[], styles:[], jsonld, ogImage}
  const url = site.domain + o.path;
  const og = o.ogImage || (extra.og && '/' + extra.og.variants.find(v => v.format === 'jpeg').file) || '';
  const vendor = ['/assets/vendor/gsap.min.js', '/assets/vendor/ScrollTrigger.min.js', '/assets/vendor/lenis.min.js']
    .concat(o.scripts || []);
  return `<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${esc(o.title)}</title>
<meta name="description" content="${esc(o.desc)}">
<link rel="canonical" href="${url}">
<meta name="theme-color" content="#F4F1EA">
<meta property="og:type" content="website">
<meta property="og:site_name" content="${esc(site.name)}">
<meta property="og:title" content="${esc(o.title)}">
<meta property="og:description" content="${esc(o.desc)}">
<meta property="og:url" content="${url}">
${og ? `<meta property="og:image" content="${site.domain}${og}">` : ''}
<meta name="twitter:card" content="summary_large_image">
<link rel="icon" href="${FAVICON}">
<link rel="preload" href="/assets/fonts/cormorant-normal-300-latin.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/archivo-normal-300-latin.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/css/site.css">
${(o.styles || []).map(h => `<link rel="stylesheet" href="${h}">`).join('\n')}
${o.jsonld ? `<script type="application/ld+json">${o.jsonld}</script>` : ''}
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
<div class="veil-page" aria-hidden="true"></div>

<header class="site" id="hdr">
  <nav class="nav" aria-label="Main">
    <a class="wordmark" href="/">Art<span>.</span>n Architects</a>
    <ul>
      ${navList(o.current)}
    </ul>
    <button class="menu-label" aria-expanded="false" aria-controls="site-menu">menu</button>
  </nav>
</header>

<div class="menu-overlay" id="site-menu" hidden>
  <button class="menu-close" aria-label="Close menu">close</button>
  <nav aria-label="Mobile">
    <a href="/">home</a>
    ${NAV.map(([href, label]) => `<a href="${href}"${href.startsWith('http') ? ' rel="noopener"' : ''}>${label}</a>`).join('\n    ')}
  </nav>
</div>

${o.body}

<footer class="site">
  <div class="wrap">
    <div class="foot-top">
      <p class="wordmark">Art<span>.</span>n Architects</p>
      <p class="eyebrow">Architecture · Interiors · Project Management</p>
    </div>
    <div class="foot-cols">
      <div>
        <span class="eyebrow">Changanacherry</span>
        <p>${site.offices[0].address.map(esc).join('<br>')}<br><a href="${site.offices[0].phoneHref}">${esc(site.offices[0].phone)}</a></p>
      </div>
      <div>
        <span class="eyebrow">Kochi</span>
        <p>${site.offices[1].address.map(esc).join('<br>')}<br><a href="${site.offices[1].phoneHref}">${esc(site.offices[1].phone)}</a></p>
      </div>
      <div>
        <span class="eyebrow">Write</span>
        <p><a href="mailto:${site.email}">${esc(site.email)}</a><br>
        <a href="${site.whatsapp}" rel="noopener">WhatsApp</a></p>
      </div>
      <div>
        <span class="eyebrow">Elsewhere</span>
        <p><a href="${site.instagram}" rel="noopener">Instagram</a><br>
        <a href="${site.facebook}" rel="noopener">Facebook</a><br>
        <a href="${site.tenderUrl}" rel="noopener">Tender portal</a></p>
      </div>
    </div>
    <div class="foot-base">
      <p>© ${esc(site.name)}, est. ${site.established}. All rights reserved.</p>
      <p>Changanacherry · Kochi — Kerala, India</p>
    </div>
  </div>
</footer>

${vendor.map(s => `<script src="${s}" defer></script>`).join('\n')}
<script src="/assets/js/site.js" defer></script>
</body>
</html>`;
}

const ctaBand = (h) => `
<section class="cta">
  <div class="wrap inner">
    <h2 class="reveal">${h || 'A site, a brief, or just a first idea — <em>bring it to the table.</em>'}</h2>
    <div class="actions reveal">
      <a class="btn" href="mailto:${site.email}">write to us</a>
      <a class="btn" href="${site.whatsapp}" rel="noopener">whatsapp</a>
    </div>
  </div>
</section>`;

const bySlug = Object.fromEntries(projects.map(p => [p.slug, p]));
const heroIdxOf = p => {
  const valid = validIndices(p.slug);
  if (!valid.length) return -1;
  return valid.includes(p.heroIndex) ? p.heroIndex : valid[0];
};
const projUrl = p => `/projects/${p.slug}/`;

/* editorial flow tile; slot-position → sizes attr for the 6-slot cycle */
const SLOT_SIZES = ['66vw', '33vw', '42vw', '42vw', '66vw', '42vw'];
const sizesFor = i => `(max-width:860px) 100vw, ${SLOT_SIZES[i % 6]}`;
function piece(p, i, heroOverride) {
  const hi = heroOverride != null ? heroOverride : heroIdxOf(p);
  if (hi < 0) return '';
  return `
    <a class="piece reveal" href="${projUrl(p)}">
      <figure>
        <div class="ph">${picture(p.slug, hi, { sizes: sizesFor(i), alt: p.heroAlt || p.title })}</div>
        <figcaption><span class="name">${esc(p.tileLabel || p.title)}</span>${p.place ? `<span class="where">${esc(p.place)}</span>` : `<span class="where">${esc(p.category || '')}</span>`}</figcaption>
      </figure>
    </a>`;
}

/* ---------- HOME ---------- */
function homePage() {
  const heroP = bySlug[home.hero.slug];
  const featured = [...home.reel.filter(r => r.slug !== home.hero.slug), ...home.grid]
    .filter((v, i, a) => a.findIndex(x => x.slug === v.slug) === i)
    .slice(0, 6);
  const flow = featured.map((g, i) => piece(bySlug[g.slug], i, g.index)).join('');

  const jsonld = JSON.stringify({
    '@context': 'https://schema.org', '@type': 'Organization',
    name: site.name, url: site.domain, email: site.email,
    foundingDate: String(site.established),
    sameAs: [site.instagram, site.facebook],
    address: site.offices.map(of => ({
      '@type': 'PostalAddress', streetAddress: of.address[0],
      addressLocality: of.address[1].split(',')[0], addressRegion: 'Kerala', addressCountry: 'IN'
    }))
  });

  const body = `
<main id="main">
<section class="hero-quiet wrap" aria-label="Art.n Architects">
  <h1>
    <span class="line"><span>Buildings with</span></span>
    <span class="line"><span>a quiet sense</span></span>
    <span class="line"><span>of <em>belonging.</em></span></span>
  </h1>
  <div class="meta">
    <span class="eyebrow">Architecture · Interiors · Project Management</span>
    <span class="eyebrow">Changanacherry &amp; Kochi — since ${site.established}</span>
  </div>
  <p class="hero-scroll eyebrow" aria-hidden="true">scroll</p>
</section>

<section class="panel-full" aria-label="${esc(heroP.title)}">
  <div class="photo">${picture(home.hero.slug, home.hero.index, { sizes: '100vw', eager: true, alt: heroP.heroAlt || heroP.title })}</div>
  <p class="cap">${esc(heroP.tileLabel || heroP.title)}${heroP.place ? ' — ' + esc(heroP.place) : ''}</p>
</section>

<section class="statement wrap">
  <span class="eyebrow reveal">The practice</span>
  <p class="big reveal">Every project begins as a simple intention — a place that is right for its people, its climate and its time. <em>We design it, detail it, and stay until it is delivered.</em></p>
  <div class="sub reveal">
    <p>Art.n Architects is an architecture, interior design and project management
    studio working from Changanacherry and Kochi since ${site.established} — residences,
    hospitality, healthcare and public buildings across Kerala.</p>
    <p><a href="/studio/"><span class="u">Meet the studio</span></a></p>
  </div>
</section>

<section class="wrap" aria-label="Selected work">
  <div class="flow">${flow}
  </div>
  <p class="view-all reveal"><a href="/projects/"><span class="u">See all ${projects.length} projects</span></a></p>
</section>

<section class="threed wrap" id="threed">
  <div class="threed-row">
    <div class="reveal">
      <model-viewer
        src="/assets/3d/massing.glb"
        alt="Conceptual massing model of a Kerala residence"
        camera-controls auto-rotate rotation-per-second="10deg"
        shadow-intensity="1" exposure="1.05"
        data-orbit-scrub
        loading="lazy" reveal="auto">
      </model-viewer>
    </div>
    <div class="reveal">
      <span class="eyebrow" style="display:block;margin-bottom:20px">From the board</span>
      <h3>Walk around the drawing.</h3>
      <p>Drag the model — or simply keep scrolling and watch it turn. This is the
      massing study of a Kerala residence, the stage where every project begins
      before a single wall goes up.</p>
      <p class="note">Signature projects receive their own models here, exported
      straight from the studio's working files.</p>
    </div>
  </div>
</section>

<section class="studio-row wrap">
  <a class="ph reveal" href="/studio/">${picture(home.studio.slug, home.studio.index, { sizes: '(max-width:860px) 100vw, 58vw', alt: 'Inside the Art.n Architects studio', dataAttrs: 'data-inner' })}</a>
  <div class="reveal">
    <span class="eyebrow" style="display:block;margin-bottom:20px">The studio</span>
    <h3>One studio, drawing to handover.</h3>
    <p>Architecture, interiors and project management under one roof — so what is
    designed is what gets built. <a href="/process/"><span class="u">How we work</span></a></p>
    <p class="addr">
      ${site.offices[0].address.map(esc).join(', ')}<br>
      ${site.offices[1].address.map(esc).join(', ')}
    </p>
  </div>
</section>

${ctaBand()}
</main>`;

  return layout({
    path: '/', current: '/', body, jsonld,
    title: 'Art.n Architects — Architecture, Interiors & Project Management, Kerala',
    desc: `Architecture, interior design and project management studio in Changanacherry and Kochi, Kerala, since ${site.established}.`,
    ogImage: (() => { const e = entryFor(home.hero.slug, home.hero.index); return e ? '/' + e.variants.find(v => v.format === 'jpeg').file : null; })()
  });
}

/* ---------- LISTINGS ---------- */
const FILTERS = [
  ['/projects/', 'all work'],
  ['/projects/architecture/', 'architecture'],
  ['/projects/interiors/', 'interiors'],
  ['/projects/pmc/', 'project management'],
];
function listingPage(list, o) {
  const filters = FILTERS.map(([href, label]) =>
    `<a href="${href}"${href === o.path ? ' aria-current="page"' : ''}>${label}</a>`).join('\n      ');
  const flow = list.map((p, i) => piece(p, i)).join('');
  const body = `
<main id="main">
<section class="page-head wrap">
  <span class="eyebrow reveal">${String(list.length).padStart(2, '0')} projects</span>
  <h1 class="reveal">${o.h1}</h1>
  <p class="lede reveal">${o.lede}</p>
  <div class="filters reveal">
      ${filters}
  </div>
</section>
<section class="wrap">
  <div class="flow">${flow}
  </div>
</section>
${ctaBand()}
</main>`;
  return layout({
    path: o.path, current: '/projects/', body,
    title: o.title, desc: o.desc
  });
}

/* ---------- PROJECT PAGE ---------- */
function projectPage(p, prev, next) {
  const hi = heroIdxOf(p);
  const valid = validIndices(p.slug).filter(i => i !== hi);
  const galleryItems = valid.map((idx, n) => `
    <a href="${biggest(p.slug, idx)}" class="glightbox" data-gallery="proj" data-glightbox="title: ${esc(p.title)} — ${String(n + 2).padStart(2, '0')}">
      ${picture(p.slug, idx, { sizes: '(max-width:860px) 100vw, 46vw', alt: `${p.title} — photograph ${n + 2}` })}
    </a>`).join('');
  const spec = [
    ['Category', p.category],
    ['Client', p.client],
    ['Year', p.year],
    ['Place', p.place],
    ['Scope', p.discipline.map(d => ({ architecture: 'Architecture', interior: 'Interiors', pmc: 'Project Management' }[d] || d)).join(' · ')],
  ].filter(([, v]) => v).map(([k, v]) => `<li><span class="k">${k}</span><span class="v">${esc(v)}</span></li>`).join('\n        ');
  const blurb = p.blurb || `${p.title} — a ${(p.category || 'building').toLowerCase()} project by ${site.name}${p.place ? ' in ' + p.place : ''}.`;
  const jsonld = JSON.stringify({
    '@context': 'https://schema.org', '@type': 'BreadcrumbList',
    itemListElement: [
      { '@type': 'ListItem', position: 1, name: 'Projects', item: site.domain + '/projects/' },
      { '@type': 'ListItem', position: 2, name: p.title, item: site.domain + projUrl(p) },
    ]
  });
  const body = `
<main id="main">
<section class="proj-hero wrap">
  <div class="ph">${picture(p.slug, hi, { sizes: '92vw', eager: true, alt: p.heroAlt || p.title })}</div>
</section>
<section class="proj-title wrap">
  <span class="eyebrow">${esc([p.category, p.place].filter(Boolean).join(' — '))}</span>
  <h1>${esc(p.title)}</h1>
</section>
<div class="wrap">
  <div class="proj-cols">
    <ul class="spec reveal">
        ${spec}
    </ul>
    <div class="proj-blurb reveal">
      <p>${esc(blurb)}</p>
    </div>
  </div>
  ${valid.length ? `<div class="gallery">${galleryItems}
  </div>` : ''}
  <nav class="proj-nav" aria-label="More projects">
    <a href="${projUrl(prev)}"><span class="eyebrow">previous</span><span class="name u">${esc(prev.tileLabel || prev.title)}</span></a>
    <a class="next" href="${projUrl(next)}"><span class="eyebrow">next</span><span class="name u">${esc(next.tileLabel || next.title)}</span></a>
  </nav>
</div>
${ctaBand('Planning something like this? <em>Let us draw it with you.</em>')}
</main>`;
  return layout({
    path: projUrl(p), current: '/projects/', body, jsonld,
    title: `${p.title} — ${[p.category, p.place].filter(Boolean).join(', ')} — ${site.name}`,
    desc: blurb.length > 155 ? blurb.slice(0, 152) + '…' : blurb,
    scripts: ['/assets/vendor/glightbox.min.js'],
    styles: ['/assets/vendor/glightbox.min.css'],
    ogImage: (() => { const e = entryFor(p.slug, hi); return e ? '/' + e.variants.find(v => v.format === 'jpeg').file : null; })()
  });
}

/* ---------- STUDIO ---------- */
function studioPage() {
  const team = site.team.map(t => {
    const key = 'team:' + t.name;
    return `
    <figure class="reveal">
      <div class="ph">${extraPic(key, { sizes: '(max-width:860px) 45vw, 12vw', alt: t.name })}</div>
      <figcaption><span class="nm">${esc(t.name)}</span><span class="rl">${esc(t.role)}</span></figcaption>
    </figure>`;
  }).join('');
  const body = `
<main id="main">
<section class="page-head wrap">
  <span class="eyebrow reveal">The studio — est. ${site.established}</span>
  <h1 class="reveal">A practice built on <em>staying with the work.</em></h1>
  <p class="lede reveal">Architecture, interiors and project management under one roof
  in Changanacherry and Kochi — so what is designed is what gets built.</p>
</section>

<section class="wrap story">
  <div class="ph reveal">${extraPic('team-group', { sizes: '(max-width:860px) 100vw, 42vw', alt: 'The Art.n Architects team', dataAttrs: 'data-inner' })}</div>
  <div class="reveal">
    <span class="eyebrow" style="display:block;margin-bottom:20px">Our story</span>
    <h2>Drawing for Kerala since ${site.established}.</h2>
    <p>The practice opened its board in <b>Changanacherry in ${site.established}</b>, working first on
    residences and renovations, and grew project by project into hospitality, healthcare,
    commercial and institutional work. In 2007 a second studio opened in <b>Kochi</b>.</p>
    <p>The name on the door is a position: architecture rooted in Kerala's building
    tradition — climate, courtyard, veranda, roof — drawn with a contemporary hand.
    Vastu informs the plan when clients ask for it; the drawing board decides the rest.</p>
    <p>Today the studio takes projects from the first sketch to the handover key:
    design, detailing, tendering and site supervision by one team.</p>
  </div>
</section>

<section class="wrap people">
  <div class="person">
    <div class="reveal">
      <span class="eyebrow" style="display:block;margin-bottom:20px">Principal</span>
      <h3>${esc(site.principal.name)}</h3>
      <span class="eyebrow role">${esc(site.principal.role)}</span>
      ${site.principal.bio.map(b => `<p>${esc(b)}</p>`).join('\n      ')}
    </div>
    <div class="ph reveal">${extraPic('principal', { sizes: '(max-width:860px) 70vw, 25vw', alt: site.principal.name })}</div>
  </div>
</section>

<section class="team wrap">
  <span class="eyebrow reveal" style="display:block;margin-bottom:40px">The team — ${String(site.team.length + 1).padStart(2, '0')} people</span>
  <div class="team-grid">${team}
  </div>
</section>

${ctaBand('Want this team on your project? <em>Start the conversation.</em>')}
</main>`;
  return layout({
    path: '/studio/', current: '/studio/', body,
    title: `Studio — ${site.name}`,
    desc: `Art.n Architects: an architecture, interiors and project management studio in Changanacherry and Kochi, Kerala, led by principal architect ${site.principal.name} since ${site.established}.`
  });
}

/* ---------- PROCESS ---------- */
function processPage() {
  const steps = [
    ['Brief & site', 'We begin where the project does: walking the land, reading its light, slope and neighbours, and listening to how you intend to live or work in it. The brief is written together — needs, budget and time, stated plainly.'],
    ['Concept', 'The first drawings test the big moves: how the building sits on its site, how rooms gather around light and air, how Kerala’s climate — sun, monsoon, breeze — shapes roof and verandah. We iterate until the plan feels inevitable.'],
    ['Detail & permits', 'The approved concept is drawn through to working detail: structure, materials, joinery, services. Statutory drawings and approvals are handled by the studio, so the project stays on one board.'],
    ['Tender', 'Contractors bid through our own online tender portal — transparent pricing, comparable bids, and a paper trail the client can read. We recommend; you decide.'],
    ['Site & supervision', 'Our engineers and project managers stay on the work: quality checks, bill certification, cost control and the weekly rhythm of site meetings, from foundation to finishes.'],
    ['Handover', 'The building is delivered as it was drawn — snagged, documented and photographed. Most of our work returns as the next project: an interior, an extension, a new site.'],
  ].map(([h, t], i) => `
    <div class="step reveal">
      <span class="no">0${i + 1}</span>
      <h3>${h}</h3>
      <p>${t}</p>
    </div>`).join('');
  const body = `
<main id="main">
<section class="page-head wrap">
  <span class="eyebrow reveal">How we work</span>
  <h1 class="reveal">From the first line <em>to the last key.</em></h1>
  <p class="lede reveal">One studio carries the project the whole way — design,
  detailing, tendering and site supervision. Six stages, one hand on the drawing.</p>
</section>
<section class="wrap steps">${steps}
</section>
${ctaBand('Curious where your project would begin? <em>Ask us.</em>')}
</main>`;
  return layout({
    path: '/process/', current: '/process/', body,
    title: `Process — ${site.name}`,
    desc: 'How Art.n Architects works: brief and site, concept, detail and permits, tendering through our online portal, site supervision, and handover — one studio the whole way.'
  });
}

/* ---------- CONTACT ---------- */
function contactPage() {
  const offices = site.offices.map(of => `
    <div class="office reveal">
      <h2>${esc(of.name)}</h2>
      <p>${of.address.map(esc).join('<br>')}</p>
      <div class="links">
        <a href="${of.phoneHref}">${esc(of.phone)}</a>
        <a href="${of.maps}" rel="noopener" target="_blank"><span class="u">Open in Google Maps</span></a>
      </div>
    </div>`).join('');
  const jsonld = JSON.stringify({
    '@context': 'https://schema.org', '@type': 'ProfessionalService',
    name: site.name, url: site.domain, email: site.email,
    telephone: '+91 ' + site.offices[0].phone,
    address: site.offices.map(of => ({
      '@type': 'PostalAddress', streetAddress: of.address[0],
      addressLocality: of.address[1].split(',')[0], addressRegion: 'Kerala', addressCountry: 'IN'
    }))
  });
  const body = `
<main id="main">
<section class="page-head wrap">
  <span class="eyebrow reveal">Contact</span>
  <h1 class="reveal">A first conversation <em>costs nothing.</em></h1>
  <p class="lede reveal">Bring a site, a brief, or just an idea — it usually starts with a sketch.</p>
</section>
<section class="wrap offices">${offices}
</section>
<section class="wrap reach">
  <a class="reveal" href="mailto:${site.email}">
    <span class="k">email</span>
    <span class="v">${esc(site.email)}</span>
  </a>
  <a class="reveal" href="${site.whatsapp}" rel="noopener">
    <span class="k">whatsapp</span>
    <span class="v">+91 94471 12848</span>
  </a>
  <a class="reveal" href="${site.instagram}" rel="noopener">
    <span class="k">instagram</span>
    <span class="v">@art.n.architects</span>
  </a>
  <a class="reveal" href="${site.tenderUrl}" rel="noopener">
    <span class="k">contractors</span>
    <span class="v">Tender portal</span>
  </a>
</section>
</main>`;
  return layout({
    path: '/contact/', current: '/contact/', body, jsonld,
    title: `Contact — ${site.name}`,
    desc: 'Contact Art.n Architects — Changanacherry 0481 241 2848 · Kochi 0484 234 1067 · artnove@gmail.com · WhatsApp +91 94471 12848.'
  });
}

/* ---------- 404 ---------- */
function notFoundPage() {
  const body = `
<main id="main">
<section class="wrap lost">
  <span class="eyebrow">page not found</span>
  <h1>404</h1>
  <p>This page was never drawn — or it has been filed elsewhere.</p>
  <p><a class="btn" href="/">back to the start</a></p>
</section>
</main>`;
  return layout({
    path: '/404.html', current: '', body,
    title: `Page not found — ${site.name}`, desc: 'Page not found.'
  });
}

/* ---------- writing ---------- */
function write(rel, html) {
  const f = path.join(DIST, rel);
  fs.mkdirSync(path.dirname(f), { recursive: true });
  fs.writeFileSync(f, html);
}
function copy(srcRel, destRel) {
  const s = path.isAbsolute(srcRel) ? srcRel : path.join(ROOT, srcRel);
  const d = path.join(DIST, destRel);
  fs.mkdirSync(path.dirname(d), { recursive: true });
  fs.copyFileSync(s, d);
}

write('index.html', homePage());
write('projects/index.html', listingPage(projects, {
  path: '/projects/', h1: 'Work that <em>stays.</em>', lede:
    'Every project the studio has drawn, detailed and delivered — residences, hospitality, healthcare and public buildings across Kerala.',
  title: `Projects — ${site.name}`,
  desc: `${projects.length} built and ongoing projects by Art.n Architects across Kerala: residences, resorts, hospitals, institutions and offices.`
}));
const disc = (d) => projects.filter(p => p.discipline.includes(d));
write('projects/architecture/index.html', listingPage(disc('architecture'), {
  path: '/projects/architecture/', h1: 'Architecture', lede:
    "Buildings designed from the ground up — concept, statutory drawings and detail for Kerala's climate and way of living.",
  title: `Architecture projects — ${site.name}`,
  desc: 'Architecture portfolio of Art.n Architects: residences, resorts, hospitals and institutional buildings across Kerala.'
}));
write('projects/interiors/index.html', listingPage(disc('interior'), {
  path: '/projects/interiors/', h1: 'Interiors', lede:
    'Interior architecture that carries the building through — homes, restaurants, offices and institutions.',
  title: `Interior design projects — ${site.name}`,
  desc: 'Interior design portfolio of Art.n Architects: homes, restaurants, offices and institutional interiors across Kerala.'
}));
write('projects/pmc/index.html', listingPage(disc('pmc'), {
  path: '/projects/pmc/', h1: 'Project management', lede:
    'Projects where the studio also ran the site — tendering, supervision and cost control from first drawing to handover.',
  title: `Project management — ${site.name}`,
  desc: 'Project management consultancy by Art.n Architects: tendering, site supervision and delivery across Kerala.'
}));
projects.forEach((p, i) => {
  const prev = projects[(i - 1 + projects.length) % projects.length];
  const next = projects[(i + 1) % projects.length];
  write(path.join('projects', p.slug, 'index.html'), projectPage(p, prev, next));
});
write('studio/index.html', studioPage());
write('process/index.html', processPage());
write('contact/index.html', contactPage());
write('404.html', notFoundPage());

/* legacy-URL redirect stubs */
const redirect = (to) => `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="refresh" content="0;url=${to}"><link rel="canonical" href="${site.domain}${to}"><title>Moved</title></head><body><p>Moved to <a href="${to}">${to}</a>.</p></body></html>`;
const legacy = { 'works.html': '/projects/', 'work architecture.html': '/projects/architecture/', 'work interior.html': '/projects/interiors/', 'work pmc.html': '/projects/pmc/', 'about.html': '/studio/', 'contact.html': '/contact/' };
for (const p of projects) legacy[p.sourcePage] = projUrl(p);
for (const [oldName, to] of Object.entries(legacy)) write(oldName, redirect(to));

/* sitemap + robots */
const urls = ['/', '/projects/', '/projects/architecture/', '/projects/interiors/', '/projects/pmc/', '/studio/', '/process/', '/contact/']
  .concat(projects.map(projUrl));
write('sitemap.xml', `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map(u => `  <url><loc>${site.domain}${u}</loc></url>`).join('\n')}
</urlset>
`);
write('robots.txt', `User-agent: *\nAllow: /\nSitemap: ${site.domain}/sitemap.xml\n`);

/* assets */
copy('src/css/site.css', 'assets/css/site.css');
copy('src/js/site.js', 'assets/js/site.js');
for (const f of fs.readdirSync(path.join(SRC, 'fonts'))) if (f.endsWith('.woff2')) copy(path.join('src', 'fonts', f), path.join('assets', 'fonts', f));
if (fs.existsSync(path.join(SRC, '3d', 'massing.glb'))) copy('src/3d/massing.glb', 'assets/3d/massing.glb');
const V = 'node_modules';
copy(`${V}/gsap/dist/gsap.min.js`, 'assets/vendor/gsap.min.js');
copy(`${V}/gsap/dist/ScrollTrigger.min.js`, 'assets/vendor/ScrollTrigger.min.js');
copy(`${V}/lenis/dist/lenis.min.js`, 'assets/vendor/lenis.min.js');
copy(`${V}/@google/model-viewer/dist/model-viewer.min.js`, 'assets/vendor/model-viewer.min.js');
copy(`${V}/glightbox/dist/js/glightbox.min.js`, 'assets/vendor/glightbox.min.js');
copy(`${V}/glightbox/dist/css/glightbox.min.css`, 'assets/vendor/glightbox.min.css');

console.log(`BUILD OK — ${urls.length} pages + ${Object.keys(legacy).length} redirects (quiet edition)`);
