// generate.js — Renders home page, state pages, city pages, and sitemap.xml
//
// Usage:  node generate.js
// Output:
//   ./output/index.html                              ← Home page (root)
//   ./output/<state-slug>/index.html                 ← State landing pages
//   ./output/<state-slug>/<city-slug>/index.html     ← City landing pages
//   ./output/sitemap.xml

const fs = require("fs");
const path = require("path");
const data = require("./data");
const { buildStaticPageRenderer } = require("./generate-static");
const buildStaticPagesContent = require("./pages");

const TEMPLATE = fs.readFileSync(path.join(__dirname, "template.html"), "utf8");
const OUTPUT = path.join(__dirname, "output");
const BRAND = "Rapid Water Recovery";

// ── helpers ─────────────────────────────────────────────────
const slugify = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");

const ensureDir = (dir) => fs.mkdirSync(dir, { recursive: true });

const writeFile = (filepath, content) => {
  ensureDir(path.dirname(filepath));
  fs.writeFileSync(filepath, content);
};

const fill = (template, vars) =>
  Object.entries(vars).reduce(
    (out, [key, val]) => out.replaceAll(`{{${key}}}`, val ?? ""),
    template
  );

const escapeHtml = (s) =>
  String(s)
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#39;");

const renderFaqHtml = (faqs) =>
  faqs
    .map(
      (f) => `<details>
  <summary>${escapeHtml(f.q)}<span class="faq-icon" aria-hidden="true"></span></summary>
  <div><p>${escapeHtml(f.a)}</p></div>
</details>`
    )
    .join("\n");

const renderFaqSchema = (faqs) =>
  JSON.stringify(
    {
      "@context": "https://schema.org",
      "@type": "FAQPage",
      mainEntity: faqs.map((f) => ({
        "@type": "Question",
        name: f.q,
        acceptedAnswer: { "@type": "Answer", text: f.a }
      }))
    },
    null,
    2
  );

const renderCitiesHtml = (state, currentCitySlug = null) =>
  state.cities
    .map((city) => {
      const citySlug = slugify(city);
      const isCurrent = citySlug === currentCitySlug;
      const href = `/${state.slug}/${citySlug}/`;
      return `<a href="${href}" class="city-card${isCurrent ? " current" : ""}" aria-current="${isCurrent ? "page" : "false"}"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s-8-7.5-8-13a8 8 0 1 1 16 0c0 5.5-8 13-8 13z"/><circle cx="12" cy="9" r="3"/></svg><span>${escapeHtml(city)}</span></a>`;
    })
    .join("\n");

const renderStatesGridHtml = () =>
  data.states
    .map((s) => {
      const href = `/${s.slug}/`;
      return `<a href="${href}" class="city-card"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s-8-7.5-8-13a8 8 0 1 1 16 0c0 5.5-8 13-8 13z"/><circle cx="12" cy="9" r="3"/></svg><span>${escapeHtml(s.name)}</span></a>`;
    })
    .join("\n");

const renderFooterAreasHtml = () =>
  data.states
    .map((s) => `<li><a href="/${s.slug}/">${escapeHtml(s.name)}</a></li>`)
    .join("\n");

const buildH1 = ({ isCity, city, state }) => {
  if (isCity) {
    return `${escapeHtml(city)}, ${escapeHtml(state.name)}<br/>Water &amp; Fire Damage<br/>Restoration.`;
  }
  return `${escapeHtml(state.name)} Water<br/>&amp; Fire Damage<br/>Restoration.`;
};

const buildHeroSubtitle = ({ isCity, city, state }) => {
  if (isCity) {
    return `Fast 24/7 emergency water, fire, flood, and mold damage restoration for ${escapeHtml(city)} homeowners and businesses. Licensed local crews on-site within 60 minutes.`;
  }
  return state.hero_subtitle;
};

// National FAQ for home page
const NATIONAL_FAQ = [
  { q: "How fast can you arrive after I call?", a: "Typically within 60 minutes in major metros and 90 minutes in smaller communities, 24/7/365. We dispatch immediately the moment you call — water damage doubles within 24 hours and mold can begin within 48 hours, so speed matters." },
  { q: "Where do you operate?", a: "We currently dispatch licensed local restoration crews across 8 states: California, Texas, Florida, New York, Georgia, Tennessee, Virginia, and South Carolina — and we're expanding to additional states. If your state isn't listed yet, call us anyway; we may already have a crew nearby." },
  { q: "Do you work with my insurance?", a: "Yes. Our network contractors are insurance-friendly and bill major carriers directly — State Farm, Allstate, Liberty Mutual, Farmers, Nationwide, Progressive, Travelers, USAA, and many others. You typically only pay your deductible." },
  { q: "Are you the contractor doing the work?", a: "No. Rapid Water Recovery is a private restoration referral service. We connect property owners with independent, licensed local restoration contractors who perform all on-site work. We are not the contractor and do not provide restoration services directly." },
  { q: "What does it cost? Do I pay you?", a: "You don't pay us — our matching service is free for property owners. Most insured losses are billed directly to your carrier; you only pay your deductible. For uninsured work, the contractor will provide a written estimate before starting." },
  { q: "What types of damage do you handle?", a: "Water damage from any source (burst pipes, appliance leaks, roof leaks, flooding), fire and smoke damage, storm and hurricane damage, mold remediation, sewage cleanup, and full structural drying. Most jobs include rebuild and reconstruction coordination." },
  { q: "How fast do I really need to act?", a: "Faster than most people realize. Drywall starts wicking water within an hour. Hardwood floors begin to cup in 12-24 hours. Mold becomes a serious risk between 24 and 48 hours after exposure to moisture. Calling immediately almost always reduces total claim cost." },
  { q: "What about mold? Should I be worried?", a: "Yes — mold can begin growing on wet materials within 24-48 hours. Once established, removal becomes significantly more expensive (containment, HEPA filtration, drywall removal). The single biggest factor in preventing mold is how quickly the structure is dried." },
  { q: "How long does the whole restoration process take?", a: "It depends on severity. Extraction and initial drying typically take 1-3 days. Structural drying continues for 3-5 days. If reconstruction is needed (drywall, flooring, paint), that adds one to several weeks. Major fire, flood, or hurricane restoration: 4-8 weeks." },
  { q: "Is your line really 24/7 — even on holidays?", a: "Yes. Our dispatch line is staffed by live operators 24 hours a day, every day of the year — weekends, overnights, and major holidays included. There are no after-hours surcharges." }
];

// State / city page
const renderPage = ({ state, city = null }) => {
  const isCity = !!city;
  const location = isCity ? `${city}, ${state.name}` : state.name;
  const slug = isCity ? slugify(city) : "";
  const url = isCity
    ? `${data.site.domain}/${state.slug}/${slug}/`
    : `${data.site.domain}/${state.slug}/`;

  const metaTitle = isCity
    ? `Water & Fire Damage Restoration in ${city}, ${state.name} | 24/7 Emergency — ${BRAND}`
    : `Water & Fire Damage Restoration in ${state.name} | 24/7 Emergency — ${BRAND}`;

  const metaDescription = isCity
    ? `24/7 emergency water and fire damage restoration in ${city}, ${state.name}. Licensed, IICRC-certified crews · 60-minute response · insurance billing. Call ${data.site.phone}.`
    : `24/7 emergency water and fire damage restoration in ${state.name}. Licensed, IICRC-certified crews serving ${state.cities.slice(0, 3).join(", ")}, and all of ${state.name}. 60-minute response · insurance billing. Call ${data.site.phone}.`;

  const mapQuery = isCity ? `${city}+${state.name}+USA` : `${state.name}+USA`;

  const vars = {
    LOCATION: escapeHtml(location),
    STATE: escapeHtml(state.name),
    STATE_SLUG: state.slug,
    STATE_ABBR: state.abbr,
    PHONE: data.site.phone,
    PHONE_LINK: data.site.phoneLink,
    LAT: state.coords.lat,
    LNG: state.coords.lng,
    META_TITLE: escapeHtml(metaTitle),
    META_DESCRIPTION: escapeHtml(metaDescription),
    CANONICAL_URL: url,
    AREA_TYPE: isCity ? "City" : "State",
    H1_HTML: buildH1({ isCity, city, state }),
    HERO_SUBTITLE: escapeHtml(buildHeroSubtitle({ isCity, city, state })),
    EMERGENCY_RISKS: escapeHtml(state.emergency_risks),
    STORM_LABEL: escapeHtml(state.storm_label),
    STORM_DESCRIPTION: escapeHtml(state.storm_description),
    MAP_QUERY: encodeURIComponent(mapQuery).replace(/%2B/g, "+"),
    MAP_ZOOM: isCity ? "10" : "6",
    AREAS_TITLE: `Cities We Serve in ${escapeHtml(state.name)}`,
    AREAS_SUBTITLE: `Local crews, fast response, ${escapeHtml(state.name)}-licensed contractors.`,
    AREAS_INTRO: `We dispatch ${escapeHtml(state.name)}-licensed, IICRC-certified crews to these major metro areas and all surrounding communities:`,
    AREAS_CTA_TEXT: "City Not Listed?",
    BRAND_SHOWCASE_HTML: "",
    CITIES_HTML: renderCitiesHtml(state, isCity ? slug : null),
    FAQ_HTML: renderFaqHtml(state.faq),
    FAQ_SCHEMA_JSON: renderFaqSchema(state.faq),
    FOOTER_AREAS_HTML: renderFooterAreasHtml(),
    YEAR: String(new Date().getFullYear())
  };

  return fill(TEMPLATE, vars);
};

// Home page
const renderHome = () => {
  const url = `${data.site.domain}/`;
  const stateNames = data.states.map((s) => s.name).slice(0, 4).join(", ");
  const metaTitle = `24/7 Water & Fire Damage Restoration Across the USA | ${BRAND}`;
  const metaDescription = `Nationwide 24/7 emergency water, fire, flood, and mold damage restoration. Licensed, IICRC-certified local crews · 60-minute response · insurance billing. Serving ${stateNames}, and more. Call ${data.site.phone}.`;
  const heroSubtitle = `From burst pipes to hurricanes and wildfires, we dispatch licensed local crews across ${data.states.length} states. 24/7 emergency response, IICRC-certified contractors, insurance-friendly billing.`;

  const vars = {
    LOCATION: "the USA",
    STATE: "U.S.",
    STATE_SLUG: "",
    STATE_ABBR: "US",
    PHONE: data.site.phone,
    PHONE_LINK: data.site.phoneLink,
    LAT: "39.8283",
    LNG: "-98.5795",
    META_TITLE: escapeHtml(metaTitle),
    META_DESCRIPTION: escapeHtml(metaDescription),
    CANONICAL_URL: url,
    AREA_TYPE: "Country",
    H1_HTML: `Nationwide Water<br/>&amp; Fire Damage<br/>Restoration.`,
    HERO_SUBTITLE: escapeHtml(heroSubtitle),
    EMERGENCY_RISKS: "sewage backup, storm flooding, contaminated water",
    STORM_LABEL: "Storm-Ready",
    STORM_DESCRIPTION: "Hurricane, wildfire, freeze, flood, and tornado — our network has handled them all.",
    MAP_QUERY: encodeURIComponent("United States").replace(/%2B/g, "+"),
    MAP_ZOOM: "4",
    AREAS_TITLE: "Where We Serve",
    AREAS_SUBTITLE: "Local crews. National coverage. Growing every month.",
    AREAS_INTRO: `We dispatch IICRC-certified local crews across ${data.states.length} states and counting. Click your state for local details:`,
    AREAS_CTA_TEXT: "State Not Listed Yet?",
    BRAND_SHOWCASE_HTML: `<section class="brand-showcase" aria-label="Rapid Water Recovery brand">
  <img src="/logo-full.png" alt="Rapid Water Recovery — Water Damage Restoration Experts. Fire & Smoke Restoration." class="brand-showcase-img" width="855" height="401" />
</section>`,
    CITIES_HTML: renderStatesGridHtml(),
    FAQ_HTML: renderFaqHtml(NATIONAL_FAQ),
    FAQ_SCHEMA_JSON: renderFaqSchema(NATIONAL_FAQ),
    FOOTER_AREAS_HTML: renderFooterAreasHtml(),
    YEAR: String(new Date().getFullYear())
  };

  return fill(TEMPLATE, vars);
};

const renderSitemap = (staticPages = []) => {
  const today = new Date().toISOString().split("T")[0];
  const urls = [`${data.site.domain}/`];

  staticPages.forEach((page) => {
    urls.push(`${data.site.domain}/${page.slug}/`);
  });

  data.states.forEach((state) => {
    urls.push(`${data.site.domain}/${state.slug}/`);
    state.cities.forEach((city) => {
      urls.push(`${data.site.domain}/${state.slug}/${slugify(city)}/`);
    });
  });

  return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls
  .map((u) => {
    const segments = u.replace(data.site.domain, "").split("/").filter(Boolean);
    let priority = "0.5";
    if (segments.length === 0) priority = "1.0";
    else if (segments.length === 1) priority = "0.9";
    else if (segments.length === 2) priority = "0.8";
    return `  <url>
    <loc>${u}</loc>
    <lastmod>${today}</lastmod>
    <changefreq>weekly</changefreq>
    <priority>${priority}</priority>
  </url>`;
  })
  .join("\n")}
</urlset>
`;
};

function generate() {
  if (fs.existsSync(OUTPUT)) {
    fs.rmSync(OUTPUT, { recursive: true });
  }
  ensureDir(OUTPUT);

  // Home page
  writeFile(path.join(OUTPUT, "index.html"), renderHome());

  let stateCount = 0;
  let cityCount = 0;

  data.states.forEach((state) => {
    writeFile(path.join(OUTPUT, state.slug, "index.html"), renderPage({ state }));
    stateCount++;

    state.cities.forEach((city) => {
      const citySlug = slugify(city);
      writeFile(path.join(OUTPUT, state.slug, citySlug, "index.html"), renderPage({ state, city }));
      cityCount++;
    });
  });

  // Static pages: about, contact, services, service-areas, privacy, terms
  const { buildPage, escapeHtml } = buildStaticPageRenderer(TEMPLATE, data);
  const staticPages = buildStaticPagesContent({ data, escapeHtml });
  let staticCount = 0;
  staticPages.forEach((page) => {
    writeFile(path.join(OUTPUT, page.slug, "index.html"), buildPage(page));
    staticCount++;
  });

  writeFile(path.join(OUTPUT, "sitemap.xml"), renderSitemap(staticPages));

  console.log(`✅ Generated 1 home + ${staticCount} static pages + ${stateCount} state pages + ${cityCount} city pages + sitemap.xml`);
  console.log(`   Total: ${1 + staticCount + stateCount + cityCount + 1} files in ./output/`);
}

generate();
