const sqlite3 = require('sqlite3').verbose();
const path = require('path');
const fs = require('fs');
const logger = require('../utils/logger');

class LocalDatabase {
  constructor() {
    this.db = null;
    this.dbPath = null;
  }

  async initialize() {
    try {
      // Create data directory if it doesn't exist
      const dataDir = path.join(__dirname, '../../data');
      if (!fs.existsSync(dataDir)) {
        fs.mkdirSync(dataDir, { recursive: true });
        logger.info(`[LOCAL DB] Created data directory: ${dataDir}`);
      }
      
      this.dbPath = path.join(dataDir, 'mods.db');
      
      logger.info(`[LOCAL DB] Initializing database at: ${this.dbPath}`);
      
      // Create database connection
      this.db = new sqlite3.Database(this.dbPath, (err) => {
        if (err) {
          logger.error('[LOCAL DB] Error opening database:', err.message);
          throw err;
        } else {
          logger.info('[LOCAL DB] Database connected successfully');
        }
      });

      // Enable foreign keys
      await this.run('PRAGMA foreign_keys = ON');
      
      // Create tables
      await this.createTables();
      
      logger.info('[LOCAL DB] Database initialized successfully');
      return true;
    } catch (error) {
      logger.error('[LOCAL DB] Failed to initialize database:', error);
      throw error;
    }
  }

  async createTables() {
    const tables = [
      // Mods table
      `CREATE TABLE IF NOT EXISTS mods (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL UNIQUE,
        version TEXT NOT NULL,
        author TEXT NOT NULL,
        description TEXT,
        enabled INTEGER DEFAULT 1,
        installed_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        file_path TEXT NOT NULL,
        checksum TEXT,
        dependencies TEXT,
        config TEXT
      )`,
      
      // Mod assets table
      `CREATE TABLE IF NOT EXISTS mod_assets (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        mod_id INTEGER NOT NULL,
        asset_type TEXT NOT NULL, -- 'ship', 'item', 'quest', etc.
        asset_id TEXT NOT NULL,
        asset_data TEXT NOT NULL, -- JSON data
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (mod_id) REFERENCES mods (id) ON DELETE CASCADE,
        UNIQUE(mod_id, asset_type, asset_id)
      )`,
      
      // Server mod preferences table
      `CREATE TABLE IF NOT EXISTS server_mod_preferences (
        key TEXT PRIMARY KEY,
        value TEXT NOT NULL,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
      )`,
      
      // Mod load order table
      `CREATE TABLE IF NOT EXISTS mod_load_order (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        mod_id INTEGER NOT NULL,
        load_order INTEGER NOT NULL,
        FOREIGN KEY (mod_id) REFERENCES mods (id) ON DELETE CASCADE,
        UNIQUE(mod_id)
      )`
    ];

    for (const table of tables) {
      await this.run(table);
    }

    logger.info('[LOCAL DB] All tables created successfully');
  }

  // Helper method to run SQL commands
  run(sql, params = []) {
    return new Promise((resolve, reject) => {
      this.db.run(sql, params, function(err) {
        if (err) {
          logger.error('[LOCAL DB] SQL Error:', err.message);
          reject(err);
        } else {
          resolve({ id: this.lastID, changes: this.changes });
        }
      });
    });
  }

  // Helper method to get single row
  get(sql, params = []) {
    return new Promise((resolve, reject) => {
      this.db.get(sql, params, (err, row) => {
        if (err) {
          logger.error('[LOCAL DB] SQL Error:', err.message);
          reject(err);
        } else {
          resolve(row);
        }
      });
    });
  }

  // Helper method to get multiple rows
  all(sql, params = []) {
    return new Promise((resolve, reject) => {
      this.db.all(sql, params, (err, rows) => {
        if (err) {
          logger.error('[LOCAL DB] SQL Error:', err.message);
          reject(err);
        } else {
          resolve(rows);
        }
      });
    });
  }

  // Close database connection
  close() {
    return new Promise((resolve, reject) => {
      if (this.db) {
        this.db.close((err) => {
          if (err) {
            logger.error('[LOCAL DB] Error closing database:', err.message);
            reject(err);
          } else {
            logger.info('[LOCAL DB] Database closed');
            resolve();
          }
        });
      } else {
        resolve();
      }
    });
  }

  // Get database instance
  getDatabase() {
    return this.db;
  }

  // Get database path
  getDatabasePath() {
    return this.dbPath;
  }
}

module.exports = new LocalDatabase();
