const { addUser, findByUsername } = require("../../repository/userRepository");
const {
  addRoleIfNotExists,
} = require("../../repository/rolesPermissionRepository");
const {
  addStateIfNotExists,
  checkTableExistence,
} = require("../../repository/stateRepository");
const {
  addInvolvementTypeIfNotExists,
  addInvolvementIfNotExists,
  checkInvolvementTypeTableExistence,
  checkInvolvementLookupTableExistence,
} = require("../../repository/involvementRepository");

/*
Class responsible for populating the database 
when the server starts with necessary lookup tables and 
users.
*/
class DatabaseInitializer {
  constructor(pool) {
    this.pool = pool;
  }

  /*
  Method for ensuring database is accessible.
  */
  async testDBConnection() {
    try {
      const [results] = await this.pool.query("SELECT 1");
      console.log("Database connection test successful. Results:", results);
    } catch (err) {
      console.error("Error testing database connection:", err);
      throw err;
    }
  }

  /*
  Method for creating the possible user roles and 
  their descriptions.
  */
  async initializeRoles() {
    console.log("initializing roles...");

    try {
      await addRoleIfNotExists(1, "guest", "Guest access");
      await addRoleIfNotExists(2, "admin", "Admin access");
      console.log("Roles initialized successfully.");
    } catch (error) {
      console.log("error initializing roles: ", error);
      throw error;
    }
  }

  /*
  Creates all of us as test users with admin roles.
  */
  async initializeTestUsers() {
    const testUsers = ["fhurtado14", "laylah", "sushant20", "kainguyen"];
    for (const user of testUsers) {
      try {
        const foundUser = await findByUsername(user);
        if (foundUser) {
          console.log("user already exists: ", user);
          continue;
        }

        // add user with admin privilages
        await addUser(user, 2);
        console.log("successfully added test user: ", user);
      } catch (error) {
        console.log("Error adding test user: ", user);
        console.log("Error was: ", error);
      }
    }
  }

  /*
  Creates all the states
  */
  async initializeStates() {
    checkTableExistence();

    const states = [
      "AL",
      "AK",
      "AZ",
      "AR",
      "CA",
      "CO",
      "CT",
      "DE",
      "FL",
      "GA",
      "HI",
      "ID",
      "IL",
      "IN",
      "IA",
      "KS",
      "KY",
      "LA",
      "ME",
      "MD",
      "MA",
      "MI",
      "MN",
      "MS",
      "MO",
      "MT",
      "NE",
      "NV",
      "NH",
      "NJ",
      "NM",
      "NY",
      "NC",
      "ND",
      "OH",
      "OK",
      "OR",
      "PA",
      "RI",
      "SC",
      "SD",
      "TN",
      "TX",
      "UT",
      "VT",
      "VA",
      "WA",
      "WV",
      "WI",
      "WY",
    ];
    for (const state of states) {
      await addStateIfNotExists(state);
    }
  }

  /*
  Creates all the involvement types
  */
  async initializeInvolvementTypes() {
    await checkInvolvementTypeTableExistence(); // Ensure the table exists

    const involvementTypes = [
      "Asian American Cadet Organization",
      "Black Cadet Organization",
      "Cadet Alumni Team",
      "Cadet Language Organization",
      "Cadets for a Cause",
      "Coast Guard Auxiliary",
      "Color Guard",
      "Conrad Cavalry",
      "Corps Marksmanship Team",
      "Eagle Scout Association",
      "EMT Staff",
      "Esprit de Corps",
      "Executive Committee",
      "Fenix (Latin Cadets)",
      "Gregory Guard",
      "Growley Team",
      "Hall Council",
      "Helping Educate Regarding Orientation (HERO)",
      "Historian Staff",
      "Honor Court",
      "Inspector General Staff",
      "Men's Basketball",
      "O-Course Committee",
      "Ordinance Staff",
      "Rappelling Tower Committee",
      "Recruiting Staff",
      "Sash and Saber Honor Society",
      "Signal Corps",
      "Skipper Crew",
      "Society of American Military Engineers",
      "VPI Battalion",
      "VTCC Cyber Team",
      "Women's Basketball",
    ];

    for (const type of involvementTypes) {
      await addInvolvementTypeIfNotExists(type); // Add each involvement type
    }
  }

  /*
  Creates all the involvement lookups directly based on the defined involvement types
  */
  async initializeInvolvementLookups() {
    await checkInvolvementLookupTableExistence(); // Ensure the lookup table exists

    // Define lookup entries with type IDs (these IDs should correspond to your actual involvement type IDs)
    const involvementLookups = [
      { involvementTypeId: 1 }, // Asian American Cadet Organization
      { involvementTypeId: 2 }, // Black Cadet Organization
      { involvementTypeId: 3 }, // Cadet Alumni Team
      { involvementTypeId: 4 }, // Cadet Language Organization
      { involvementTypeId: 5 }, // Cadets for a Cause
      { involvementTypeId: 6 }, // Coast Guard Auxiliary
      { involvementTypeId: 7 }, // Color Guard
      { involvementTypeId: 8 }, // Conrad Cavalry
      { involvementTypeId: 9 }, // Corps Marksmanship Team
      { involvementTypeId: 10 }, // Eagle Scout Association
      { involvementTypeId: 11 }, // EMT Staff
      { involvementTypeId: 12 }, // Esprit de Corps
      { involvementTypeId: 13 }, // Executive Committee
      { involvementTypeId: 14 }, // Fenix (Latin Cadets)
      { involvementTypeId: 15 }, // Gregory Guard
      { involvementTypeId: 16 }, // Growley Team
      { involvementTypeId: 17 }, // Hall Council
      { involvementTypeId: 18 }, // Helping Educate Regarding Orientation (HERO)
      { involvementTypeId: 19 }, // Historian Staff
      { involvementTypeId: 20 }, // Honor Court
      { involvementTypeId: 21 }, // Inspector General Staff
      { involvementTypeId: 22 }, // Men’s Basketball
      { involvementTypeId: 23 }, // O-Course Committee
      { involvementTypeId: 24 }, // Ordinance Staff
      { involvementTypeId: 25 }, // Rappelling Tower Committee
      { involvementTypeId: 26 }, // Recruiting Staff
      { involvementTypeId: 27 }, // Sash and Saber Honor Society
      { involvementTypeId: 28 }, // Signal Corps
      { involvementTypeId: 29 }, // Skipper Crew
      { involvementTypeId: 30 }, // Society of American Military Engineers
      { involvementTypeId: 31 }, // VPI Battalion
      { involvementTypeId: 32 }, // VTCC Cyber Team
      { involvementTypeId: 33 }, // Women’s Basketball
    ];

    for (const entry of involvementLookups) {
      await addInvolvementIfNotExists(entry.involvementTypeId); // Add entry to involvementLookup
    }
  }


  async initializeAll() {
    await this.testDBConnection();
    await this.initializeRoles();
    await this.initializeTestUsers();
    await this.initializeStates();
    await this.initializeInvolvementTypes();
    await this.initializeInvolvementLookups();

    console.log("database init completed.");
  }
}

module.exports = DatabaseInitializer;