<?php
// app/services/metadata/TvdbProvider.php

declare(strict_types=1);

namespace ScMedia\Services\Metadata;

use ScMedia\Services\HttpClient;
use ScMedia\Services\LogService;

final class TvdbProvider implements MetadataProvider {
  private HttpClient $http;
  private ?LogService $logger;

  public function __construct(HttpClient $http, ?LogService $logger = null) {
    $this->http = $http;
    $this->logger = $logger;
  }

  public function id(): string {
    return 'tvdb';
  }

  public function label(): string {
    return 'TVDB';
  }

  public function supportsType(string $type): bool {
    return in_array($type, ['movie','series'], true);
  }

  public function buildUrl(string $externalId): string {
    return $externalId !== '' ? ('https://thetvdb.com/?tab=series&id=' . $externalId) : '';
  }

  public function search(string $query, string $type, ?int $year, string $lang, array $config): array {
    $apiKey = (string)($config['api_key'] ?? '');
    if ($apiKey === '') {
      $this->logger?->log('warn', 'TVDB API key missing');
      return [];
    }
    $token = $this->login($apiKey, (string)($config['pin'] ?? ''));
    if ($token === '') {
      $this->logger?->log('warn', 'TVDB login failed');
      return [];
    }

    $q = [
      'query' => $query,
      'type' => ($type === 'movie') ? 'movie' : 'series',
    ];
    if ($year !== null && $year > 1800 && $year < 2100) {
      $q['year'] = (string)$year;
    }
    $url = 'https://api4.thetvdb.com/v4/search?' . http_build_query($q);
    $this->logger?->log('debug', 'TVDB search request', ['url' => $this->sanitizeUrl($url)]);
    $headers = [
      'Authorization: Bearer ' . ($this->shouldLogKeys() ? $token : 'DUMMY'),
      'Accept-Language: ' . $lang,
    ];
    $res = $this->http->getJson($url, $headers);
    if (empty($res['ok']) || !is_array($res['data'])) {
      $this->logger?->log('error', 'TVDB search failed', [
        'status' => $res['status'] ?? null,
        'error' => $res['error'] ?? null,
      ]);
      return [];
    }
    $items = is_array($res['data']['data'] ?? null) ? $res['data']['data'] : [];
    $out = [];
    foreach ($items as $it) {
      if (!is_array($it)) continue;
      $id = (string)($it['tvdb_id'] ?? $it['id'] ?? '');
      $title = (string)($it['name'] ?? $it['title'] ?? '');
      $yr = null;
      if (isset($it['year']) && is_numeric($it['year'])) {
        $yr = (int)$it['year'];
      } else if (isset($it['firstAired']) && preg_match('/\d{4}/', (string)$it['firstAired'], $m)) {
        $yr = (int)$m[0];
      }
      $image = (string)($it['image_url'] ?? $it['image'] ?? '');
      $out[] = [
        'provider' => $this->id(),
        'provider_name' => $this->label(),
        'provider_id' => $id,
        'provider_url' => $this->buildUrl($id),
        'title_map' => [$lang => $title],
        'original_title' => $title,
        'year' => $yr,
        'poster' => $image,
        'type' => (string)($it['type'] ?? $type),
      ];
    }
    return $out;
  }

  private function login(string $apiKey, string $pin): string {
    $payload = ['apikey' => $apiKey];
    if ($pin !== '') $payload['pin'] = $pin;
    if ($this->logger) {
      $safe = $payload;
      if (!$this->shouldLogKeys()) {
        $safe['apikey'] = 'DUMMY';
        if (isset($safe['pin'])) $safe['pin'] = 'DUMMY';
      }
      $this->logger->log('debug', 'TVDB login request', ['payload' => $safe]);
    }
    $res = $this->http->postJson('https://api4.thetvdb.com/v4/login', $payload);
    if (empty($res['ok']) || !is_array($res['data'])) {
      $this->logger?->log('error', 'TVDB login request failed', [
        'status' => $res['status'] ?? null,
        'error' => $res['error'] ?? null,
      ]);
      return '';
    }
    $token = (string)($res['data']['data']['token'] ?? '');
    return $token;
  }

  private function shouldLogKeys(): bool {
    return filter_var(getenv('DEBUG_KEYS') ?: 'false', FILTER_VALIDATE_BOOLEAN);
  }

  private function sanitizeUrl(string $url): string {
    return $url;
  }
}
