import { load } from "cheerio";
import { readFile, writeFileSync, mkdirSync, cpSync, rmSync } from "fs";
import process from "child_process";
import stores from "./stores.json" with { type: "json" };

function mkDir(path) {
  try {
    return mkdirSync(path)
  } catch (err) {
    if (err.code !== 'EEXIST') throw err
  }
}

function writeFile(path, content) {
  try {
    writeFileSync(path, content);
  } catch (err) {
    if (err) throw err;
  }
   console.log(`${path} updated.`);
}

function slugify(str) {
  return str
    .toLowerCase()
    .replace(/é/g, "e")
    .replace(/&/g, " and ")
    .replace(/ /g, "-")
    .replace(/[']+/g, "")
    .replace(/[^\w-]+/g, "-")
    .replace(/-+/g, "-")
    .replace(/^-|-$/g, "");
}

function cleanWebsite(str) {
  return str
    .toLowerCase()
    .replace(/^https?:\/\//g, "")
    .replace(/^www./g, "")
    .replace(/\/$/g, "");
}

function metaDescription({ name, meta, description }) {
  if (meta.length > 155) {
    console.log(`warning: meta tag for ${name} is too long: ${meta.length}`)
  }
  return meta || description.length > 155 ? description.slice(0, 153) + "..." : description || "A guide to and map of every independent bookstore in New York City. We have a complete list of community bookstores in NYC with locations and descriptions."
}

function GetRecentChanges() {
  const res = process
    .execSync('git log -15 --pretty=format:"%ct %s"')
    .toString();
  return res.split("\n");
}

function ChangeLog(logs) {
  let res = "\n";
  let i = 0;
  logs.forEach((l) => {
    if (
      i > 3 ||
      l.includes("[skip]") ||
      l.includes("[ignore]") ||
      l.includes("caddy") ||
      l.includes("renovate")
    ) {
      return;
    }
    i++;
    const s = l.split(" ");
    const date = new Date(s[0] * 1000).toLocaleDateString("en-US", {
      year: "numeric",
      month: "long",
      day: "numeric",
    });
    res = res + `<li>${date} - ${s.slice(1).join(" ")}</li>\n`;
  });
  return res;
}

function TableViewTemplate(rows) {
  let table = "<table>";
  rows.forEach((row, key) => {
    row.rowNumber = key;
    table = table + TableRowTemplate(row);
  });
  return table + "</table>";
}

function TableRowTemplate({ rowNumber, name, slug, address, city }) {
  return `
  <tr id="${rowNumber}" class="spotRow">
    <td class="name"><a href="/${slugify(name)}/">${name}</a></td>
    <td><a href="/${slugify(name)}/">${address}, ${city}</a></td>
  </tr>`;
}

function TitleTemplate({ name }) {
  return `${name} | Independent Bookstores in New York City - Best Community Bookstores in NYC`;
}

function SelectedStoreTemplate({
  name,
  address,
  city,
  postcode,
  website,
  events,
  cafe,
  description,
}) {
  return `
    <h2>${name}</h2>
    <p class="address">${address}</p>
    <p></p>
    <p class="address">
      ${city}, NY ${postcode}
    </p>
    <p>
      View in:
      <a
        href="https://maps.google.com/maps?q=${encodeURIComponent(
          name
        )}+${address},${city},NY"
        target="_blank"
        >Google Maps</a
      >
      <a
        href="http://maps.apple.com/?q=${encodeURIComponent(
          name
        )}&address=${address},${city},NY"
        target="_blank"
        >Apple Maps</a
      >
    </p>
    <ul>
      ${
        website
          ? `<li><a href="${website}" target="_blank">${cleanWebsite(
              website
            )}</a></li>`
          : ""
      }
      <li class="storeDetails">Events: ${events}</li>
      <li class="storeDetails">Caf&eacute;: ${cafe}</li>
    </ul>
    ${description ? `<p class="description">${description}</p>` : ""}`;
}


readFile("./index.tmpl.html", function (err, data) {
  const changeList = GetRecentChanges();
  if (err) {
    throw err;
  }
  const $ = load(data);

  stores.sort(function (a, b) {
    var aname = a.name.toLowerCase();
    var bname = b.name.toLowerCase();
    return aname === bname ? 0 : +(aname > bname) || -1;
  });

  $("#Stores").html(TableViewTemplate(stores));
  $("#storeCount").html(stores.length);
  $("#updatedOn").html(
    new Date().toLocaleDateString("en-US", {
      year: "numeric",
      month: "long",
      day: "numeric",
    })
  );
  $("#changesList").html(ChangeLog(changeList));
  const cssurl = $("link[type='text/css']").attr("href").split("?")[0];
  $("link[type='text/css']").attr("href", cssurl + "?" + new Date().getTime());

  rmSync("./build", { recursive: true, force: true });

  mkDir("./build")
  
  writeFile("./build/index.html", $.html())

  cpSync("./site.css", "./build/site.css");
  cpSync("./robots.txt", "./build/robots.txt");
  cpSync("./img", "./build/img", {recursive: true});
  cpSync("./stores.json", "./build/stores.json");

  stores.forEach((store) => {
    $("#selected").html(SelectedStoreTemplate(store));
    $("#info").addClass("hidden");
    let title = TitleTemplate(store);
    $("title").html(title);
    $("meta[name='title']").attr("content", title);
    $("meta[name='description']").attr("content", metaDescription(store));
    mkDir(`./build/${slugify(store.name)}`);
    writeFile(`./build/${slugify(store.name)}/index.html`, $.html());
  });
});