<?php
// app/controllers/tasks.php

declare(strict_types=1);

use ScMedia\Http\Router;

final class TasksController extends BaseController {
  public static function register(Router $router, Container $container): void {
    $self = new self($container);
    $router->add('POST', '/api/tasks/pending/list', fn() => $self->listPending());
    $router->add('POST', '/api/tasks/pending', fn() => $self->savePending());
    $router->add('POST', '/api/tasks/pending/delete', fn() => $self->deletePending());
    $router->add('POST', '/api/tasks/approve', fn() => $self->approvePending());
    $router->add('POST', '/api/tasks/list', fn() => $self->listTasks());
    $router->add('POST', '/api/tasks/run', fn() => $self->runTask());
  }

  private function listPending(): void {
    $settings = $this->settings();
    [$page, $perPage, $sort, $dir, $filters] = table_body_params(50, 200);
    $data = $settings->getAll();
    $pending = is_array($data['pending_tasks'] ?? null) ? $data['pending_tasks'] : [];
    $items = array_values(array_filter($pending, fn($t) => is_array($t)));
    $items = apply_filters_array($items, $filters, [
      'name' => 'name',
      'type' => 'type',
      'status' => 'status',
    ]);
    [$slice, $total] = paginate_array($items, $page, $perPage);
    json_response(['ok' => true, 'data' => [
      'items' => $slice,
      'total' => $total,
      'page' => $page,
      'per_page' => $perPage,
    ]]);
  }

  private function savePending(): void {
    $settings = $this->settings();
    $body = read_json_body();
    $task = is_array($body['task'] ?? null) ? $body['task'] : null;
    if (!$task) {
      json_response(['ok' => false, 'error' => 'task required'], 400);
    }
    $id = (string)($task['id'] ?? '');
    if ($id === '') {
      $id = 'pending_' . time() . '_' . bin2hex(random_bytes(2));
      $task['id'] = $id;
    }
    $data = $settings->getAll();
    $pending = is_array($data['pending_tasks'] ?? null) ? $data['pending_tasks'] : [];
    $pending = array_values(array_filter($pending, fn($t) => is_array($t)));
    $pending = array_values(array_filter($pending, fn($t) => (string)($t['id'] ?? '') !== $id));
    $pending[] = $task;
    $settings->saveBulk(['pending_tasks' => $pending]);
    json_response(['ok' => true, 'data' => ['id' => $id]]);
  }

  private function deletePending(): void {
    $settings = $this->settings();
    $body = read_json_body();
    $id = (string)($body['id'] ?? '');
    if ($id === '') {
      json_response(['ok' => false, 'error' => 'id required'], 400);
    }
    $data = $settings->getAll();
    $pending = is_array($data['pending_tasks'] ?? null) ? $data['pending_tasks'] : [];
    $pending = array_values(array_filter($pending, fn($t) => (string)($t['id'] ?? '') !== $id));
    $settings->saveBulk(['pending_tasks' => $pending]);
    json_response(['ok' => true, 'data' => ['id' => $id]]);
  }

  private function approvePending(): void {
    $settings = $this->settings();
    $body = read_json_body();
    $id = (string)($body['id'] ?? '');
    if ($id === '') {
      json_response(['ok' => false, 'error' => 'id required'], 400);
    }
    $data = $settings->getAll();
    $pending = is_array($data['pending_tasks'] ?? null) ? $data['pending_tasks'] : [];
    $tasks = is_array($data['tasks'] ?? null) ? $data['tasks'] : [];
    $task = null;
    $pending = array_values(array_filter($pending, function($t) use ($id, &$task) {
      if ((string)($t['id'] ?? '') === $id) {
        $task = $t;
        return false;
      }
      return true;
    }));
    if (!$task) {
      json_response(['ok' => false, 'error' => 'task not found'], 404);
    }
    $tasks[] = $task;
    $settings->saveBulk(['pending_tasks' => $pending, 'tasks' => $tasks]);
    json_response(['ok' => true, 'data' => ['id' => $id]]);
  }

  private function listTasks(): void {
    $settings = $this->settings();
    $data = $settings->getAll();
    [$page, $perPage] = table_body_params(50, 200);
    $tasks = is_array($data['tasks'] ?? null) ? $data['tasks'] : [];
    $out = [];
    foreach ($tasks as $t) {
      if (!is_array($t)) continue;
      if (empty($t['enabled'])) continue;
      $out[] = [
        'id' => (string)($t['id'] ?? ''),
        'name' => (string)($t['name'] ?? ''),
        'sources' => is_array($t['sources'] ?? null) ? $t['sources'] : [],
        'actions' => is_array($t['actions'] ?? null) ? $t['actions'] : [],
        'enabled' => !empty($t['enabled']),
      ];
    }
    [$slice, $total] = paginate_array($out, $page, $perPage);
    json_response(['ok' => true, 'data' => [
      'items' => $slice,
      'total' => $total,
      'page' => $page,
      'per_page' => $perPage,
    ]]);
  }

  private function runTask(): void {
    $settings = $this->settings();
    /** @var \ScMedia\Services\JobsService $jobs */
    $jobs = $this->services()['jobs'];
    $body = read_json_body();
    $id = (string)($body['id'] ?? '');
    if ($id === '') {
      json_response(['ok' => false, 'error' => 'id required'], 400);
    }

    $data = $settings->getAll();
    $tasks = is_array($data['tasks'] ?? null) ? $data['tasks'] : [];
    $task = null;
    foreach ($tasks as $t) {
      if (!is_array($t)) continue;
      if ((string)($t['id'] ?? '') === $id) {
        $task = $t;
        break;
      }
    }
    if (!$task) {
      json_response(['ok' => false, 'error' => 'task not found'], 404);
    }

    $title = 'Task: ' . (string)($task['name'] ?? $id);
    $jobId = $jobs->create('task', $title, ['task_id' => $id]);
    $jobs->start($jobId);
    $jobs->log($jobId, 'info', 'Task execution queued');
    $jobs->log($jobId, 'warn', 'Task execution not wired to pipeline yet');
    $jobs->finish($jobId);
    json_response(['ok' => true, 'data' => ['job_id' => $jobId]]);
  }
}
