<?php
 
declare(strict_types=1);
 
error_reporting(E_ALL);
ini_set('display_errors', '1');
 
session_start();
 
header('Content-Type: application/json; charset=utf-8');
 
class HttpClient
{
    private string $url;
    private array $headers;
    private string $cookieString;
 
    public function __construct(string $url)
    {
        $this->url = $url;
        $this->headers = [
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
            'Accept-Language: en-US,en;q=0.9',
            'Cache-Control: max-age=0',
            'Connection: keep-alive',
            'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
        ];
        $this->cookieString = 'language=tr_TR.UTF-8; w3p=1943251136.20480.0000; _uid=1740222152-6371b0c0-9419-485e-abf4-f1a4d9de5c3b; ridbb=WyI4MjE2YjU0YWRkN2YxOTkwNDU2NmZjMzgzZTIzZGRmZGQ1MTVmYmIxZTIiXQ%3D%3D; TURKIYESESSIONID=ppvh79th8g07afbs5f9geuvefd; TS01c2accc=015c1cbb6d1a639504e1b29b05b98286d479274aaf94c82d859307282d1c86808d72742a98623567bf8f57c330e2ce30a706ea5e64; _lastptts=1740223200';
    }
 
    public function get(string $url): string
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
        curl_setopt($ch, CURLOPT_COOKIE, $this->cookieString);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
 
    public function post(string $url, array $postData): string
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
        curl_setopt($ch, CURLOPT_COOKIE, $this->cookieString);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        
        $response = curl_exec($ch);
        
        if ($response === false) {
            $error = curl_error($ch);
            curl_close($ch);
            throw new Exception("cURL error: $error");
        }
        
        curl_close($ch);
        return $response;
    }
 
    public function getUrl(): string
    {
        return $this->url;
    }
}
 
class PharmacyScraper
{
    private HttpClient $client;
 
    public function __construct(HttpClient $client)
    {
        $this->client = $client;
    }
 
    public function fetchToken(): ?string
    {
        $response = $this->client->get($this->client->getUrl());
        preg_match('/<input type="hidden" name="token" value="([^"]+)"/', $response, $matches);
        return $matches[1] ?? null;
    }
 
    public function submitSearchForm(string $token, string $plateCode, string $date): void
    {
        $postData = [
            'plakaKodu' => $plateCode,
            'nobetTarihi' => $date,
            'token' => $token,
            'btn' => 'Sorgula'
        ];
        $this->client->post($this->client->getUrl() . '?submit', $postData);
    }
 
    public function fetchPharmacies(): array
    {
        $response = $this->client->get($this->client->getUrl() . '?nobetci=Eczaneler');
        $dom = new DOMDocument();
        libxml_use_internal_errors(true);
        $dom->loadHTML($response);
        libxml_clear_errors();
 
        $table = $dom->getElementById('searchTable');
        if (!$table) return [];
 
        $rows = $table->getElementsByTagName('tr');
        $pharmacies = [];
 
        foreach ($rows as $row) {
            $cols = $row->getElementsByTagName('td');
            if ($cols->length > 0) {
                $pharmacies[] = [
                    'name' => trim($cols->item(0)->textContent),
                    'district' => trim($cols->item(1)->textContent),
                    'phone' => trim(str_replace("Ara", "", $cols->item(2)->textContent)),
                    'address' => trim($cols->item(3)->textContent)
                ];
            }
        }
        return $pharmacies;
    }
}
 
try {
    $time_left = 5 - (time() - $_SESSION['last_request']);
    if (isset($_SESSION['last_request']) && $time_left > 0) {
        throw new Exception("Rate limit exceeded. Please wait $time_left seconds before trying again.");
    }
    $_SESSION['last_request'] = time();
 
    $plateCode = filter_input(INPUT_GET, 'plateCode', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $date = filter_input(INPUT_GET, 'date', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?: date('d/m/Y');
 
    if (!$plateCode || !is_numeric($plateCode)) {
        throw new Exception('City/Plate code invalid!');
    }
    if (!preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $date)) {
        throw new Exception('Date format is invalid (ex: 22/02/2025)');
    }
 
    $client = new HttpClient("https://turkiye.gov.tr/saglik-titck-nobetci-eczane-sorgulama");
    $scraper = new PharmacyScraper($client);
 
    $token = $scraper->fetchToken();
    if (!$token) {
        throw new Exception('Failed to access the verification token!');
    }
 
    $scraper->submitSearchForm($token, $plateCode, $date);
    $pharmacies = $scraper->fetchPharmacies();
 
    echo json_encode(['status' => true, 'data' => $pharmacies], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
    echo json_encode(['status' => false, 'error' => $e->getMessage()], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}