import { Injectable } from '@nestjs/common';
import { ConfigService } from './config.service';
import { DatasetsService } from './datasets.service';
import { DbService } from './db.service';
import { HandbrakeService } from './handbrake.service';
import { MaintenanceService } from './maintenance.service';
import { TaskQueueService } from './task-queue.service';
import { WatcherService } from './watcher.service';

@Injectable()
export class AppService {
  constructor(
    private readonly db: DbService,
    private readonly watcher: WatcherService,
    private readonly config: ConfigService,
    private readonly maintenance: MaintenanceService,
    private readonly handbrake: HandbrakeService,
    private readonly datasets: DatasetsService,
    private readonly taskQueue: TaskQueueService,
  ) {}

  listDatasets() {
    return this.datasets.getEnabledDatasetPaths();
  }

  listAllDatasets() {
    return this.datasets.getAllDatasetNames();
  }

  getDatasetConfig() {
    return this.datasets.getDatasetConfig();
  }

  getTotalSuccessfulFiles() {
    const datasetNames = this.datasets.getAllDatasetNames();
    let total = 0;
    for (const datasetName of datasetNames) {
      if (datasetName) {
        const files = this.db.getAllFiles(datasetName);
        total += files.length;
      }
    }
    return total;
  }

  getTotalProcessedFiles() {
    const datasetNames = this.datasets.getAllDatasetNames();
    let total = 0;
    for (const datasetName of datasetNames) {
      if (datasetName) {
        const files = this.db.getAllFiles(datasetName);
        total += files.length;
      }
    }
    return total;
  }

  deleteExpiredFiles(days?: number) {
    return this.db.deleteExpiredFiles(days);
  }

  migrateJsonToSqlite(opts?: { datasets?: string[]; dataDir?: string }) {
    return this.db.migrateJsonToSqlite(opts);
  }

  processWithHandbrake(input: string, output: string, preset: string) {
    return this.handbrake.processWithHandbrake(input, output, preset);
  }

  // Task queue methods
  createTask(taskData: {
    dataset: string;
    input: string;
    output: string;
    preset: string;
    priority?: number;
    status?: string;
  }) {
    return this.taskQueue.createTask(taskData);
  }

  getQueueStatus() {
    return this.taskQueue.getQueueStatus();
  }

  getQueueSettings() {
    return this.taskQueue.getQueueSettings();
  }

  updateQueueSettings(settings: any) {
    return this.taskQueue.updateQueueSettings(settings);
  }

  getAllTasks() {
    return this.db.getAllTasks();
  }

  getTaskById(id: number) {
    return this.db.getTaskById(id);
  }

  updateTask(id: number, updates: any) {
    return this.db.updateTask(id, updates);
  }

  deleteTask(id: number) {
    return this.db.deleteTask(id);
  }

  getHandbrakePresets() {
    return this.handbrake.getPresetList();
  }

  cleanup(file: string, dirs: string[]) {
    return this.maintenance.cleanup(file, dirs);
  }

  purge(dirs: string[], dayMs?: number, cleanerMs?: number) {
    return this.maintenance.purge(dirs, dayMs, cleanerMs);
  }

  prune(dirs: string[]) {
    return this.maintenance.prune(dirs);
  }

  getSettings(key?: string, defaultValue?: any) {
    return this.config.getSettings(key, defaultValue);
  }

  setSettings(settings: Record<string, any>) {
    return this.config.setSettings(settings);
  }

  deleteSetting(key: string) {
    return this.config.deleteSetting(key);
  }

  getConfigFile(name: string) {
    return this.config.getConfigFile(name);
  }

  listConfigs() {
    return this.config.listConfigs();
  }

  startWatcher(watches: string[], options?: any) {
    return this.watcher.start(watches, options);
  }

  async stopWatcher() {
    return this.watcher.stop();
  }

  watcherStatus() {
    return this.watcher.status();
  }

  startTaskProcessing() {
    return this.taskQueue.start();
  }

  stopTaskProcessing() {
    return this.taskQueue.stop();
  }

  taskProcessingStatus() {
    return this.taskQueue.getQueueStatus();
  }

  // Task maintenance methods
  cleanupTasksByStatus(status: string, olderThanDays?: number) {
    return this.db.deleteTasksByStatus(status, olderThanDays);
  }

  cleanupOldTasks(days: number) {
    return this.db.deleteTasksOlderThan(days);
  }

  getTaskStats() {
    return this.db.getTaskStats();
  }

  archiveOldTasks(daysOld: number = 30): { changes?: number } {
    return this.db.archiveOldTasks(daysOld);
  }

  // Purge all tasks
  purgeAllTasks() {
    return this.db.purgeAllTasks();
  }

  // Scheduled maintenance
  scheduledTaskCleanup() {
    return this.maintenance.scheduledTaskCleanup();
  }

  getHello(): string {
    return 'Hello World!';
  }

  findFile(dataset: string, file: string) {
    return this.db.findFile(dataset, file);
  }

  setFile(dataset: string, file: string, payload: any) {
    return this.db.setFile(dataset, file, payload);
  }

  removeFile(dataset: string, file: string, soft = true) {
    return this.db.removeFile(dataset, file, soft);
  }

  clearAllFiles() {
    return this.db.clearAllFiles();
  }

  getAllFiles(dataset: string) {
    return this.db.getAllFiles(dataset);
  }

  getDeletedOlderThan(dataset: string, isoDate: string) {
    return this.db.getDeletedOlderThan(dataset, isoDate);
  }
}
