<?php
// Error handling
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Constants and helper functions
const URBAN_DICT_BASE = 'https://www.urbandictionary.com';
const URBAN_API_BASE = 'https://api.urbandictionary.com/v0';
const DOM_OPTIONS = LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD;

function handle_dom($html, $is_pagination = false) {
    if (empty($html)) return $html;
    
    $dom = new DOMDocument();
    @$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'), DOM_OPTIONS);
    $xpath = new DOMXPath($dom);
    
    // Remove all classes
    foreach ($xpath->query('//*[@class]') as $element) {
        $element->removeAttribute('class');
    }
    
    // Handle pagination
    if ($is_pagination && ($div = $xpath->query("//div")[0])) {
        $div->setAttribute('class', 'pagination');
        
        // Fix pagination links for subdirectory
        foreach ($xpath->query("//a[@href]") as $link) {
            $href = $link->getAttribute('href');
            if (str_starts_with($href, '/?')) {
                $link->setAttribute('href', './' . substr($href, 1));
            }
        }
    }
    
    return $dom->saveHTML();
}

function fetch_url($url) {
    static $ch = null;
    if (!$ch) {
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_TIMEOUT => 10,
            CURLOPT_ENCODING => '',
            CURLOPT_USERAGENT => 'Mozilla/5.0 Rural Dictionary',
            CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
            CURLOPT_TCP_FASTOPEN => 1,
        ]);
    }
    curl_setopt($ch, CURLOPT_URL, $url);
    return [
        curl_exec($ch),
        curl_getinfo($ch, CURLINFO_HTTP_CODE),
        curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)
    ];
}

function fetch_thumbs($def_ids) {
    if (empty($def_ids)) return [];
    $response = @file_get_contents(
        URBAN_API_BASE . '/uncacheable?ids=' . implode(',', $def_ids),
        false,
        stream_context_create(['http' => ['timeout' => 5, 'ignore_errors' => true]])
    );
    $data = $response ? json_decode($response, true) : [];
    return isset($data['thumbs']) ? array_column($data['thumbs'], null, 'defid') : [];
}

// Get request info
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$query = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY);
$term = $_GET['term'] ?? '';

// Fetch and handle redirects
[$html, $status_code, $final_url] = fetch_url(URBAN_DICT_BASE . $path . ($query ? "?$query" : ''));
if ($final_url !== URBAN_DICT_BASE . $path . ($query ? "?$query" : '')) {
    header('Location: ' . parse_url($final_url, PHP_URL_PATH) . 
           (($q = parse_url($final_url, PHP_URL_QUERY)) ? "?$q" : ''));
    exit;
}

// Parse HTML
$dom = new DOMDocument();
@$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'), DOM_OPTIONS);
$xpath = new DOMXPath($dom);

$results = [];
$site_description = null;
$pagination = null;

if ($status_code !== 200) {
    $similar_words = array_map(
        fn($word) => handle_dom($dom->saveHTML($word)),
        iterator_to_array($xpath->query("//div[contains(@class, 'try-these')]//li/a"))
    );
    $template = '404';
} else {
    $definitions = $xpath->query("//div[@data-defid]");
    $def_ids = array_map(fn($def) => $def->getAttribute('data-defid'), iterator_to_array($definitions));
    $thumbs_data = fetch_thumbs($def_ids);
    
    foreach ($definitions as $def) {
        $def_id = $def->getAttribute('data-defid');
        $word = $xpath->query(".//a[contains(@class, 'word')]", $def)[0]->textContent;
        $meaning = handle_dom($dom->saveHTML($xpath->query(".//div[contains(@class, 'meaning')]", $def)[0]));
        $example = handle_dom($dom->saveHTML($xpath->query(".//div[contains(@class, 'example')]", $def)[0]));
        $contributor = handle_dom($dom->saveHTML($xpath->query(".//div[contains(@class, 'contributor')]", $def)[0]));
        
        if (!$site_description) {
            $site_description = preg_replace('/\s+/', ' ', strip_tags($meaning));
        }
        
        $thumbs = $thumbs_data[$def_id] ?? [];
        $results[] = [
            $def_id, $word, $meaning, $example, $contributor,
            $thumbs['up'] ?? null, $thumbs['down'] ?? null
        ];
    }
    
    if ($pagination_node = $xpath->query("//div[contains(@class, 'pagination')]")[0]) {
        $pagination = handle_dom($dom->saveHTML($pagination_node), true);
    }
    
    $template = 'index';
}

// Set title
$site_title = 'Rural Dictionary' . 
    ($path === '/' ? ', ' . date('d F') : '') .
    ($path === '/random.php' ? ': Random words' : ($term ? ": $term" : ''));

// Output HTML
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./static/css/main.css">
    <link rel="icon" type="image/png" href="./static/img/favicon.png">
    <title><?= htmlspecialchars($site_title) ?></title>
    <meta name="description" content="<?= htmlspecialchars($site_description ?? '') ?>">
    <meta property="og:url" content="<?= htmlspecialchars($_SERVER['REQUEST_URI']) ?>">
    <meta property="og:type" content="website">
    <meta property="og:title" content="<?= htmlspecialchars($site_title) ?>">
    <meta property="og:description" content="<?= htmlspecialchars($site_description ?? '') ?>">
    <meta property="twitter:domain" content="<?= htmlspecialchars($_SERVER['HTTP_HOST']) ?>">
    <meta property="twitter:url" content="<?= htmlspecialchars($_SERVER['REQUEST_URI']) ?>">
    <meta name="twitter:title" content="<?= htmlspecialchars($site_title) ?>">
    <meta name="twitter:description" content="<?= htmlspecialchars($site_description ?? '') ?>">
</head>
<body>
    <div style="text-align: center">
        <a href="./">
            <img src="./static/img/logo.png" alt="logo">
        </a>
        <form id="search" role="search" method="get" action="./define.php">
            <input
                autocomplete="off"
                type="search"
                id="term"
                name="term"
                placeholder="Search"
                aria-label="Search"
                value="<?= $path === '/define.php' ? htmlspecialchars($term) : '' ?>"
                autofocus
            >
            <button>Go</button>
        </form>
        <a href="./random.php">Random</a>
        <br>
        <a href="https://git.qunn.eu/poesty/rural-dict/src/php-port">Source Code</a>
    </div>
    <br>
    
    <?php if ($template === '404'): ?>
        <div style="text-align: center">
            <h2>Definition not found: <?= htmlspecialchars($term) ?></h2>
            <?php if (!empty($similar_words)): ?>
                <?php foreach ($similar_words as $word): ?>
                    <h3 class="underline-links"><?= $word ?></h3>
                <?php endforeach; ?>
            <?php else: ?>
                <p>There are no similar words. Try correcting your search.</p>
            <?php endif; ?>
        </div>
    <?php else: ?>
        <?php foreach ($results as [$definition_id, $word, $meaning, $example, $contributor, $thumbs_up, $thumbs_down]): ?>
            <div data-id="<?= htmlspecialchars($definition_id) ?>">
                <a href="./define.php?term=<?= urlencode($word) ?>">
                    <h2><?= htmlspecialchars($word) ?></h2>
                </a>
                <div class="underline-links">
                    <p><?= $meaning ?></p>
                    <p><i><?= $example ?></i></p>
                </div>
                <div><?= $contributor ?></div>
                <?php if ($thumbs_up !== null && $thumbs_down !== null): ?>
                    <p>
                        <span title="thumbs up">👍<?= htmlspecialchars($thumbs_up) ?></span>
                        <span title="thumbs down">👎<?= htmlspecialchars($thumbs_down) ?></span>
                    </p>
                <?php endif; ?>
            </div>
            <br>
        <?php endforeach; ?>
        <?php if ($pagination): ?>
            <?= $pagination ?>
        <?php endif; ?>
    <?php endif; ?>
</body>
</html>