#!/usr/bin/env ts-node
import path from 'path';
import fs from 'fs/promises';
import { gameDB } from "../routes/games/store";

async function main() {
  const gamesDir = path.resolve(__dirname, "../../db/games");
  let files: string[] = [];
  try {
    files = await fs.readdir(gamesDir);
  } catch (e) {
    console.error("Failed to read games dir", gamesDir, e);
    process.exit(2);
  }

  if (!gameDB.db) {
    await gameDB.init();
  }

  let db = gameDB.db;

  if (!db.sequelize) {
    console.error("DB did not expose sequelize; cannot proceed.");
    process.exit(4);
  }

  for (const f of files) {
    // ignore dotfiles and .bk backup files (we don't want to import backups)
    if (f.startsWith(".") || f.endsWith(".bk")) continue;
    const full = path.join(gamesDir, f);
    try {
      const stat = await fs.stat(full);
      if (!stat.isFile()) continue;
      const raw = await fs.readFile(full, "utf8");
      const game = JSON.parse(raw);
      // Derive id from filename (strip .json if present)
      const idStr = f.endsWith(".json") ? f.slice(0, -5) : f;
      const id = isNaN(Number(idStr)) ? idStr : Number(idStr);

      // derive a friendly name from the saved game when present
      const nameCandidate = game && (game.name || game.id) ? String(game.name || game.id) : undefined;

      try {
        if (typeof id === "number") {
          // numeric filename: use the typed helper
          await db.saveGame(game);
          console.log(`Saved game id=${id}`);
          if (nameCandidate) {
            try {
              await db.sequelize.query("UPDATE games SET name=:name WHERE id=:id", {
                replacements: { id, name: nameCandidate },
              });
            } catch (_) {
              // ignore name update failure
            }
          }
        } else {
          // string filename: try to find an existing row by path and save via id;
          // otherwise insert a new row with path and the JSON game.
          let found: any[] = [];
          try {
            found = await db.sequelize.query("SELECT id FROM games WHERE path=:path", {
              replacements: { path: idStr },
              type: db.Sequelize.QueryTypes.SELECT,
            });
          } catch (qe) {
            found = [];
          }

          if (found && found.length) {
            const foundId = found[0].id;
            await db.saveGame(game);
            console.log(`Saved game path=${idStr} -> id=${foundId}`);
            if (nameCandidate) {
              try {
                await db.sequelize.query("UPDATE games SET name=:name WHERE id=:id", {
                  replacements: { id: foundId, name: nameCandidate },
                });
              } catch (_) {
                // ignore
              }
            }
          } else {
            // ensure state column exists before inserting a new row
            try {
              await db.sequelize.query("ALTER TABLE games ADD COLUMN state TEXT");
            } catch (_) {
              // ignore
            }
            const payload = JSON.stringify(game);
            if (nameCandidate) {
              await db.sequelize.query("INSERT INTO games (path, state, name) VALUES(:path, :state, :name)", {
                replacements: { path: idStr, state: payload, name: nameCandidate },
              });
            } else {
              await db.sequelize.query("INSERT INTO games (path, state) VALUES(:path, :state)", {
                replacements: { path: idStr, state: payload },
              });
            }
            console.log(`Inserted game path=${idStr}`);
          }
        }
      } catch (e) {
        console.error("Failed to save game", idStr, e);
      }
    } catch (e) {
      console.error("Failed to read/parse", full, e);
    }
  }

  console.log("Import complete");
  process.exit(0);
}

main();
