<?php
// app/services/SourcesService.php

declare(strict_types=1);

namespace ScMedia\Services;

final class SourcesService {
  private TransmissionService $transmission;
  private SettingsService $settings;

  public function __construct(TransmissionService $transmission, SettingsService $settings) {
    $this->transmission = $transmission;
    $this->settings = $settings;
  }

  public function list(): array {
    $items = $this->transmission->list();
    return $this->applyFilters($items);
  }

  private function applyFilters(array $items): array {
    $rules = $this->getSourceRules();
    if (count($rules) === 0) return [];

    $out = [];
    foreach ($items as $it) {
      foreach ($rules as $r) {
        if ($this->matchesRule($it, $r)) {
          $out[] = $it;
          break;
        }
      }
    }
    return $out;
  }

  private function getSourceRules(): array {
    $all = $this->settings->getAll();
    $rules = is_array($all['rules'] ?? null) ? $all['rules'] : [];
    $out = [];
    foreach ($rules as $r) {
      if (!is_array($r)) continue;
      if (!empty($r['enabled']) && ($r['type'] ?? '') === 'source_filter') {
        $out[] = $r;
      }
    }
    return $out;
  }

  private function matchesRule(array $item, array $rule): bool {
    $cfg = is_array($rule['config'] ?? null) ? $rule['config'] : [];
    $source = (string)($cfg['source'] ?? '');
    if ($source !== '' && (string)($item['source'] ?? '') !== $source) return false;

    $conditions = is_array($cfg['conditions'] ?? null) ? $cfg['conditions'] : [];
    if (count($conditions) === 0) {
      $conditions = $this->buildLegacyConditions($cfg);
    }

    if (count($conditions) === 0) {
      return true;
    }

    foreach ($conditions as $cond) {
      if (!is_array($cond)) continue;
      if (array_key_exists('enabled', $cond) && !$cond['enabled']) continue;
      if (!$this->matchesCondition($item, $cond)) return false;
    }
    return true;
  }

  private function buildLegacyConditions(array $cfg): array {
    $conditions = [];
    $statuses = [];
    if (isset($cfg['statuses']) && is_array($cfg['statuses'])) {
      $statuses = $cfg['statuses'];
    } elseif (!empty($cfg['status'])) {
      $statuses = [(string)$cfg['status']];
    }
    if (count($statuses) > 0) {
      $conditions[] = ['field' => 'status', 'op' => 'in', 'value' => $statuses];
    }
    if (!empty($cfg['label'])) {
      $conditions[] = ['field' => 'label', 'op' => 'contains', 'value' => (string)$cfg['label']];
    }
    if (!empty($cfg['name_regex'])) {
      $conditions[] = ['field' => 'name_regex', 'op' => 'regex', 'value' => (string)$cfg['name_regex']];
    }
    if (!empty($cfg['path_regex'])) {
      $conditions[] = ['field' => 'path_regex', 'op' => 'regex', 'value' => (string)$cfg['path_regex']];
    }
    if (!empty($cfg['min_size'])) {
      $conditions[] = ['field' => 'min_size', 'op' => '>=', 'value' => (int)$cfg['min_size']];
    }
    return $conditions;
  }

  private function matchesCondition(array $item, array $cond): bool {
    $field = (string)($cond['field'] ?? '');
    $op = (string)($cond['op'] ?? '');
    $value = $cond['value'] ?? null;

    if ($field === 'status') {
      $status = (string)($item['status'] ?? '');
      $vals = is_array($value) ? $value : (is_string($value) ? [$value] : []);
      if ($op === 'not_in') {
        return !in_array($status, $vals, true);
      }
      if (count($vals) === 0) return true;
      return in_array($status, $vals, true);
    }

    if ($field === 'label') {
      $labels = is_array($item['labels'] ?? null) ? $item['labels'] : [];
      $needle = (string)$value;
      if ($needle === '') return true;
      if ($op === 'not_contains') {
        foreach ($labels as $l) {
          if (stripos((string)$l, $needle) !== false) return false;
        }
        return true;
      }
      if ($op === '=' || $op === '!=') {
        $has = in_array($needle, $labels, true);
        return $op === '!=' ? !$has : $has;
      }
      foreach ($labels as $l) {
        if (stripos((string)$l, $needle) !== false) return true;
      }
      return false;
    }

    if ($field === 'name_regex') {
      $name = (string)($item['name'] ?? '');
      if ($value === null || $value === '') return true;
      $ok = @preg_match((string)$value, $name) === 1;
      return ($op === 'not_regex') ? !$ok : $ok;
    }

    if ($field === 'path_regex') {
      $path = (string)($item['path'] ?? '');
      if ($value === null || $value === '') return true;
      $ok = @preg_match((string)$value, $path) === 1;
      return ($op === 'not_regex') ? !$ok : $ok;
    }

    if ($field === 'min_size') {
      $size = (int)($item['size_bytes'] ?? 0);
      $val = (int)($value ?? 0);
      return match ($op) {
        '>' => $size > $val,
        '<' => $size < $val,
        '<=' => $size <= $val,
        '=' => $size === $val,
        '!=' => $size !== $val,
        default => $size >= $val,
      };
    }

    return true;
  }
}
