<?php

namespace ZenoChatbot\Services\LLMService\AIClient\Support\Handlers;

use ZenoChatbot\Services\HttpClient;

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Handles loading resources from URLs.
 */
class UrlHandler
{
    /**
     * Load content from a URL
     */
    public static function load(string $url, array $options = []): array
    {
        $allow = (array) ($options['allowlist'] ?? []);
        $maxBytes = (int) ($options['max_bytes'] ?? 1024 * 1024);
        $timeout = (int) ($options['timeout'] ?? 10);

        // Check allowlist
        if (!empty($allow) && !static::isAllowed($url, $allow)) {
            return static::emptyResult($url);
        }

        $client = new HttpClient(['timeout' => $timeout]);
        $resp = $client->get($url);

        $body = '';
        $type = 'text/plain';

        if (!empty($resp['success'])) {
            $type = static::extractContentType($resp);
            $raw = is_array($resp['body']) ? json_encode($resp['body']) : (string) $resp['body'];
            $body = substr($raw, 0, $maxBytes);
        }

        return [
            'id' => md5($url),
            'name' => $url,
            'type' => $type,
            'text' => TextHandler::trimText($body, $options),
            'url' => $url,
        ];
    }

    /**
     * Check if URL host is in allowlist
     */
    private static function isAllowed(string $url, array $allowlist): bool
    {
        $host = (string) wp_parse_url($url, PHP_URL_HOST);

        foreach ($allowlist as $domain) {
            $domain = (string) $domain;
            $len = strlen($domain) + 1;
            $tail = substr($host, -$len);

            if ($host === $domain || $tail === '.' . $domain) {
                return true;
            }
        }

        return false;
    }

    /**
     * Extract content type from response headers
     */
    private static function extractContentType(array $resp): string
    {
        if (!is_array($resp['headers']) || empty($resp['headers']['content-type'])) {
            return 'text/plain';
        }

        $contentType = $resp['headers']['content-type'];

        return is_array($contentType) ? $contentType[0] : $contentType;
    }

    /**
     * Return empty result for blocked URLs
     */
    private static function emptyResult(string $url): array
    {
        return [
            'id' => md5($url),
            'name' => $url,
            'type' => 'text/plain',
            'text' => '',
            'url' => $url,
        ];
    }

}

