<?php

require __DIR__ . "/Classes/ApiHandler.php";

use App\Classes\ApiHandler;
use GuzzleHttp\Client;

class BookImportHandler extends ApiHandler
{
  protected string $postgrestUrl;
  protected string $postgrestApiKey;

  private string $bookImportToken;

  public function __construct()
  {
    parent::__construct();
    $this->ensureCliAccess();
    $this->loadEnvironment();
  }

  private function loadEnvironment(): void
  {
    $this->postgrestUrl = $_ENV["POSTGREST_URL"] ?? getenv("POSTGREST_URL");
    $this->postgrestApiKey =
      $_ENV["POSTGREST_API_KEY"] ?? getenv("POSTGREST_API_KEY");
    $this->bookImportToken =
      $_ENV["BOOK_IMPORT_TOKEN"] ?? getenv("BOOK_IMPORT_TOKEN");
  }

  public function handleRequest(): void
  {
    $input = json_decode(file_get_contents("php://input"), true);

    if (!$input) $this->sendErrorResponse("Invalid or missing JSON body", 400);

    $providedToken = $input["token"] ?? null;
    $isbn = $input["isbn"] ?? null;

    if (!$providedToken || $providedToken !== $this->bookImportToken) $this->sendErrorResponse("Unauthorized access", 401);

    if (!$isbn) $this->sendErrorResponse("isbn parameter is required", 400);

    try {
      $bookData = $this->fetchBookData($isbn);
      $this->processBook($bookData);

      $this->sendResponse("Book imported successfully", 200);
    } catch (Exception $e) {
      $this->sendErrorResponse("Error: " . $e->getMessage(), 500);
    }
  }

  private function fetchBookData(string $isbn): array
  {
    $client = new Client();
    $response = $client->get("https://openlibrary.org/api/books", [
      "query" => [
        "bibkeys" => "ISBN:{$isbn}",
        "format" => "json",
        "jscmd" => "data",
      ],
      "headers" => ["Accept" => "application/json"],
    ]);

    $data = json_decode($response->getBody(), true);
    $bookKey = "ISBN:{$isbn}";

    if (empty($data[$bookKey])) throw new Exception("Book data not found for ISBN: {$isbn}");

    return $data[$bookKey];
  }

  private function processBook(array $bookData): void
  {
    $isbn =
      $bookData["identifiers"]["isbn_13"][0] ??
      ($bookData["identifiers"]["isbn_10"][0] ?? null);
    $title = $bookData["title"] ?? null;
    $author = $bookData["authors"][0]["name"] ?? null;
    $description = $bookData["description"] ?? ($bookData["notes"] ?? "");

    if (!$isbn || !$title || !$author) throw new Exception("Missing essential book data (title, author, or ISBN).");

    $existingBook = $this->getBookByISBN($isbn);

    if ($existingBook) throw new Exception("Book with ISBN {$isbn} already exists.");

    $bookPayload = [
      "isbn" => $isbn,
      "title" => $title,
      "author" => $author,
      "description" => $description,
      "read_status" => "want to read",
      "slug" => "/books/" . $isbn,
    ];

    $this->saveBook($bookPayload);
  }

  private function saveBook(array $bookPayload): void
  {
    $this->fetchFromPostgREST("books", "", "POST", $bookPayload);
  }

  private function getBookByISBN(string $isbn): ?array
  {
    $query = "isbn=eq." . urlencode($isbn);
    $response = $this->fetchFromPostgREST("books", $query, "GET");

    return $response[0] ?? null;
  }
}

$handler = new BookImportHandler();
$handler->handleRequest();