import "dotenv/config";
import { readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { closeDb, ensureSchema, getDb, getDbPath } from "../server/db.js";
import { lsadPriority, normalizeCityLookupKey, stripPlaceSuffix } from "../server/geocoder.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const DEFAULT_SOURCE = path.resolve(__dirname, "../data/gazetteer-places.txt");
const SOURCE_PATH = path.resolve(process.env.GEOCODER_DATA_PATH || DEFAULT_SOURCE);

function parseRow(line) {
  const cols = line.split("\t");
  if (cols.length < 12) return null;
  const usps = cols[0].trim();
  const geoid = cols[1].trim();
  const fullName = cols[3].trim();
  const lsad = cols[4].trim();
  const latitude = Number(cols[10]);
  const longitude = Number(cols[11]);
  if (!usps || !geoid || !fullName) return null;
  if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) return null;
  const name = stripPlaceSuffix(fullName);
  return {
    id: `${usps}-${geoid}`,
    state_code: usps,
    name,
    full_name: fullName,
    city_key: normalizeCityLookupKey(name),
    full_city_key: normalizeCityLookupKey(fullName),
    lsad,
    lsad_priority: lsadPriority(lsad),
    geoid,
    latitude,
    longitude,
  };
}

function main() {
  console.log(`Source : ${SOURCE_PATH}`);
  console.log(`Target : ${getDbPath()}`);
  const raw = readFileSync(SOURCE_PATH, "utf8");
  const lines = raw.split("\n");
  const docs = [];
  for (let i = 1; i < lines.length; i++) {
    if (!lines[i]) continue;
    const doc = parseRow(lines[i]);
    if (doc) docs.push(doc);
  }
  console.log(`Parsed ${docs.length.toLocaleString()} places`);

  const db = getDb();
  ensureSchema(db);
  db.exec("DELETE FROM gazetteer_places");

  const insert = db.prepare(`
    INSERT INTO gazetteer_places
      (id, state_code, name, full_name, city_key, full_city_key, lsad, lsad_priority, geoid, latitude, longitude)
    VALUES
      (:id, :state_code, :name, :full_name, :city_key, :full_city_key, :lsad, :lsad_priority, :geoid, :latitude, :longitude)
  `);
  db.exec("BEGIN");
  try {
    for (const r of docs) insert.run(r);
    db.exec("COMMIT");
  } catch (err) {
    db.exec("ROLLBACK");
    throw err;
  }

  const count = db.prepare("SELECT COUNT(*) AS n FROM gazetteer_places").get().n;
  console.log(`Inserted ${count.toLocaleString()} rows into gazetteer_places`);
}

try {
  main();
} catch (err) {
  console.error(err);
  process.exitCode = 1;
} finally {
  closeDb();
}
