import { Injectable } from '@nestjs/common';
import Database from 'better-sqlite3';
import fs from 'fs';
import path from 'path';

@Injectable()
export class DatasetsService {
  private dbPath: string;

  constructor() {
    // Find project root by traversing up from current directory until we find the root package.json
    let projectRoot = process.cwd();
    while (projectRoot !== path.dirname(projectRoot)) {
      if (fs.existsSync(path.join(projectRoot, 'package.json'))) {
        try {
          const pkg = JSON.parse(
            fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf-8'),
          );
          if (pkg.name === 'watch-finished-turbo') {
            break;
          }
        } catch (e) {
          // ignore
        }
      }
      projectRoot = path.dirname(projectRoot);
    }

    this.dbPath = path.resolve(projectRoot, 'data/database.db');
  }

  /**
   * Returns all enabled dataset paths from the settings.datasets key in the database
   * Only includes paths from datasets that are not explicitly disabled
   */
  getEnabledDatasetPaths(): string[] {
    const db = new Database(this.dbPath, { readonly: true });
    const row = db
      .prepare('SELECT value FROM settings WHERE key = ?')
      .get('datasets') as { value?: string } | undefined;
    db.close();
    if (!row || !row.value) return [];
    let datasets;
    try {
      datasets = JSON.parse(row.value);
    } catch (e) {
      return [];
    }
    // Each dataset (kids, pr0n, tvshows, etc) is an object, each value is a config object
    // Find all paths in all datasets
    const paths: string[] = [];
    for (const datasetName of Object.keys(datasets)) {
      const datasetObj = datasets[datasetName];
      if (typeof datasetObj === 'object' && datasetObj !== null) {
        // Check if dataset is explicitly disabled (handles false, "false", 0, "0", etc.)
        const isDisabled =
          datasetObj.enabled === false ||
          datasetObj.enabled === 'false' ||
          datasetObj.enabled === 0 ||
          datasetObj.enabled === '0';
        if (!isDisabled) {
          for (const pathKey of Object.keys(datasetObj)) {
            if (pathKey !== 'enabled') {
              // Skip the enabled property itself
              paths.push(pathKey);
            }
          }
        }
      }
    }
    return paths;
  }

  /**
   * Returns all dataset names from the settings.datasets key in the database
   * Includes both enabled and disabled datasets
   */
  getAllDatasetNames(): string[] {
    const db = new Database(this.dbPath, { readonly: true });
    const row = db
      .prepare('SELECT value FROM settings WHERE key = ?')
      .get('datasets') as { value?: string } | undefined;
    db.close();
    if (!row || !row.value) return [];
    let datasets;
    try {
      datasets = JSON.parse(row.value);
    } catch (e) {
      return [];
    }
    return Object.keys(datasets);
  }

  /**
   * Returns the full dataset configuration from settings
   */
  getDatasetConfig(): Record<string, any> {
    const db = new Database(this.dbPath, { readonly: true });
    const row = db
      .prepare('SELECT value FROM settings WHERE key = ?')
      .get('datasets') as { value?: string } | undefined;
    db.close();
    if (!row || !row.value) return {};
    try {
      return JSON.parse(row.value);
    } catch (e) {
      return {};
    }
  }
}
