<?php
// app/controllers/settings.php

declare(strict_types=1);

use ScMedia\Http\Response;
use ScMedia\Http\Router;

final class SettingsController extends BaseController {
  public static function register(Router $router, Container $container): void {
    $self = new self($container);
    $router->add('GET', '/api/settings', fn() => $self->getSettings());
    $router->add('POST', '/api/language', fn() => $self->updateLanguage());
    $router->add('POST', '/api/settings', fn() => $self->saveSettings());
    $router->add('GET', '/api/settings/diagnostics', fn() => $self->getDiagnostics());
    $router->add('GET', '/api/settings/snapshots', fn() => $self->listSnapshots());
    $router->add('POST', '/api/settings/snapshots', fn() => $self->createSnapshot());
    $router->add('POST', '/api/settings/snapshots/restore', fn() => $self->restoreSnapshot());
    $router->add('DELETE', '/api/settings/snapshots/{id}', fn(array $params) => $self->deleteSnapshot($params));
  }

  private function getSettings(): void {
    $all = $this->settings()->getAll();
    Response::json(['ok' => true, 'data' => $all]);
  }

  private function updateLanguage(): void {
    $logger = $this->logger();
    $body = read_json_body();
    $lang = (string)($body['language'] ?? '');
    if (!preg_match('/^[a-z]{2}$/', $lang)) {
      Response::json(['ok' => false, 'error' => ['code' => 'INVALID_LANGUAGE', 'message' => 'Invalid language']], 400);
      return;
    }
    try {
      $newRev = $this->settings()->saveBulk(['general' => ['language' => $lang]]);
      $logger->log('info', 'Language updated', ['language' => $lang, 'revision' => $newRev]);
      Response::json(['ok' => true, 'data' => ['settings_revision' => $newRev]]);
    } catch (Throwable $e) {
      $logger->log('error', 'Language update failed', ['error' => $e->getMessage()]);
      Response::json(['ok' => false, 'error' => ['code' => 'SAVE_FAILED', 'message' => $e->getMessage()]], 400);
    }
  }

  private function saveSettings(): void {
    $logger = $this->logger();
    $body = read_json_body();
    try {
      $newRev = $this->settings()->saveBulk($body);
      $logger->log('info', 'Settings saved', ['revision' => $newRev]);
      Response::json(['ok' => true, 'data' => ['settings_revision' => $newRev]]);
    } catch (Throwable $e) {
      $logger->log('error', 'Settings save failed', ['error' => $e->getMessage()]);
      Response::json(['ok' => false, 'error' => ['code' => 'SAVE_FAILED', 'message' => $e->getMessage()]], 400);
    }
  }

  private function getDiagnostics(): void {
    $db = $this->db();
    $shell = $this->services()['shell'] ?? null;
    $bins = ['mkvmerge', 'mkvpropedit', 'ffmpeg'];
    $binOut = [];
    foreach ($bins as $b) {
      $binOut[$b] = ($shell instanceof \ScMedia\Services\ShellTool) ? ($shell->which($b) ?? '') : '';
    }

    $root = dirname(__DIR__, 2);
    $free = @disk_free_space($root);
    $total = @disk_total_space($root);
    $disk = [
      'path' => $root,
      'free_bytes' => is_int($free) ? $free : null,
      'total_bytes' => is_int($total) ? $total : null,
    ];

    $running = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='running'");
    $queued = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='queued'");
    $errors = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='error'");

    Response::json(['ok' => true, 'data' => [
      'php_version' => PHP_VERSION,
      'disk' => $disk,
      'binaries' => $binOut,
      'jobs' => [
        'running' => (int)($running['c'] ?? 0),
        'queued' => (int)($queued['c'] ?? 0),
        'errors' => (int)($errors['c'] ?? 0),
      ],
    ]]);
  }

  private function listSnapshots(): void {
    $items = $this->settings()->listSnapshots();
    Response::json(['ok' => true, 'data' => ['items' => $items]]);
  }

  private function createSnapshot(): void {
    $logger = $this->logger();
    $body = read_json_body();
    $label = (string)($body['label'] ?? '');
    $user = $this->container->get('auth_user');
    $userId = is_array($user) ? (int)($user['id'] ?? 0) : null;
    $id = $this->settings()->createSnapshot($label, $userId > 0 ? $userId : null);
    $logger->log('info', 'Settings snapshot created', ['id' => $id, 'label' => $label ?: null, 'user_id' => $userId ?: null]);
    Response::json(['ok' => true, 'data' => ['id' => $id]]);
  }

  private function restoreSnapshot(): void {
    $logger = $this->logger();
    $body = read_json_body();
    $id = (int)($body['id'] ?? 0);
    if ($id <= 0) {
      Response::json(['ok' => false, 'error' => ['code' => 'ID_REQUIRED', 'message' => 'Snapshot id required']], 400);
      return;
    }
    $this->settings()->restoreSnapshot($id);
    $logger->log('warn', 'Settings snapshot restored', ['id' => $id]);
    Response::json(['ok' => true]);
  }

  private function deleteSnapshot(array $params): void {
    $id = (int)($params['id'] ?? 0);
    if ($id <= 0) {
      Response::json(['ok' => false, 'error' => ['code' => 'ID_REQUIRED', 'message' => 'Snapshot id required']], 400);
      return;
    }
    $this->settings()->deleteSnapshot($id);
    Response::json(['ok' => true]);
  }
}
