<?php
declare(strict_types=1);

// KEEP YOUR PATH - if this file is /api/spotify.php in project root, this is correct.
// If your file is /api/spotify.php then change to: require __DIR__ . '/../../includes/bootstrap.php';
require __DIR__ . '/../includes/bootstrap.php';

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');

function json_out(array $a): void {
  echo json_encode($a, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
  exit;
}

function safe_err(string $code, array $extra = []): void {
  json_out(array_merge(['ok'=>false, 'error'=>$code], $extra));
}

function spotify_refresh_access_token(string $refreshToken): array {
  if (!defined('SPOTIFY_CLIENT_ID') || !defined('SPOTIFY_CLIENT_SECRET')) {
    return ['ok'=>false, 'why'=>'spotify_constants_missing'];
  }
  if (SPOTIFY_CLIENT_ID === '' || SPOTIFY_CLIENT_SECRET === '') {
    return ['ok'=>false, 'why'=>'spotify_client_empty'];
  }

  $ch = curl_init('https://accounts.spotify.com/api/token');
  curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query([
      'grant_type' => 'refresh_token',
      'refresh_token' => $refreshToken,
    ]),
    CURLOPT_HTTPHEADER => [
      'Authorization: Basic ' . base64_encode(SPOTIFY_CLIENT_ID . ':' . SPOTIFY_CLIENT_SECRET),
      'Content-Type: application/x-www-form-urlencoded',
    ],
    CURLOPT_TIMEOUT => 10,
  ]);

  $raw = curl_exec($ch);
  $curlErr = curl_error($ch);
  $http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  $data = is_string($raw) ? json_decode($raw, true) : null;

  if (!is_string($raw)) {
    return ['ok'=>false,'why'=>'curl_failed','curl_error'=>$curlErr ?: 'unknown'];
  }

  if ($http < 200 || $http >= 300) {
    return ['ok'=>false,'why'=>'spotify_token_http','status'=>$http,'spotify'=>$data,'raw'=>$raw];
  }

  if (!is_array($data) || empty($data['access_token'])) {
    return ['ok'=>false,'why'=>'spotify_token_bad_json','status'=>$http,'spotify'=>$data,'raw'=>$raw];
  }

  return ['ok'=>true,'data'=>$data];
}

function spotify_api_get(string $url, string $accessToken): array {
  $ch = curl_init($url);
  curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
      'Authorization: Bearer ' . $accessToken,
      'Accept: application/json',
    ],
    CURLOPT_TIMEOUT => 10,
  ]);

  $raw = curl_exec($ch);
  $curlErr = curl_error($ch);
  $http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  $data = is_string($raw) ? json_decode($raw, true) : null;
  return [$http, $data, $raw, $curlErr];
}

try {
  // sanity: does pdo() exist?
  if (!function_exists('pdo')) safe_err('pdo_function_missing');

  // what DB are we using?
  $dbName = pdo()->query("SELECT DATABASE()")->fetchColumn();
  if (!$dbName) safe_err('no_database_selected');

  // does table exist?
  $stmt = pdo()->query("SHOW TABLES LIKE 'spotify_tokens'");
  $tbl = $stmt ? $stmt->fetchColumn() : null;
  if (!$tbl) safe_err('table_missing', ['db'=>$dbName]);

  // fetch row
  $q = pdo()->query("SELECT refresh_token, access_token, access_expires FROM spotify_tokens WHERE id=1");
  if (!$q) safe_err('query_failed');
  $row = $q->fetch(PDO::FETCH_ASSOC);
  if (!$row) safe_err('row_missing_id_1', ['db'=>$dbName]);

  $refresh = trim((string)($row['refresh_token'] ?? ''));
  $access  = trim((string)($row['access_token'] ?? ''));
  $exp     = (int)($row['access_expires'] ?? 0);

  if ($refresh === '') safe_err('refresh_token_empty_in_db', ['db'=>$dbName]);

  // refresh if needed
  if ($access === '' || $exp <= (time() + 30)) {
    $new = spotify_refresh_access_token($refresh);
    if (empty($new['ok'])) {
      safe_err('refresh_failed', ['detail'=>$new, 'db'=>$dbName]);
    }

    $access = (string)$new['data']['access_token'];
    $exp = time() + (int)($new['data']['expires_in'] ?? 3600);

    $ok = pdo()->prepare("UPDATE spotify_tokens SET access_token=?, access_expires=? WHERE id=1")
              ->execute([$access, $exp]);
    if (!$ok) safe_err('db_update_failed');
  }

  // now playing
  [$http, $data, $raw, $curlErr] = spotify_api_get('https://api.spotify.com/v1/me/player/currently-playing', $access);

  if ($http === 200 && is_array($data) && !empty($data['item'])) {
    $t = $data['item'];
    $artists = [];
    foreach (($t['artists'] ?? []) as $a) $artists[] = (string)($a['name'] ?? '');
    $img = (string)($t['album']['images'][0]['url'] ?? '');

    json_out([
      'ok' => true,
      'mode' => !empty($data['is_playing']) ? 'playing' : 'recent',
      'track' => [
        'title' => (string)($t['name'] ?? ''),
        'artist' => trim(implode(', ', array_filter($artists))),
        'art' => $img,
        'url' => (string)($t['external_urls']['spotify'] ?? ''),
      ],
    ]);
  }

  // fallback: recently played
  [$http2, $data2, $raw2, $curlErr2] = spotify_api_get('https://api.spotify.com/v1/me/player/recently-played?limit=1', $access);
  $item = (is_array($data2) && !empty($data2['items'][0]['track'])) ? $data2['items'][0]['track'] : null;

  if ($http2 === 200 && is_array($item)) {
    $artists = [];
    foreach (($item['artists'] ?? []) as $a) $artists[] = (string)($a['name'] ?? '');
    $img = (string)($item['album']['images'][0]['url'] ?? '');

    json_out([
      'ok' => true,
      'mode' => 'recent',
      'track' => [
        'title' => (string)($item['name'] ?? ''),
        'artist' => trim(implode(', ', array_filter($artists))),
        'art' => $img,
        'url' => (string)($item['external_urls']['spotify'] ?? ''),
      ],
    ]);
  }

  safe_err('no_track', [
    'currently_playing_http' => $http,
    'recent_http' => $http2
  ]);

} catch (Throwable $e) {
  safe_err('exception', [
    'type' => get_class($e),
    'msg'  => $e->getMessage(),
    'file' => $e->getFile(),
    'line' => $e->getLine(),
  ]);
}
