<?php
namespace EasyChat\Library\Ai;

use EasyChat\Library\WidgetDomainPolicy;

class SitePageWebGrounding {
    private const MAX_URLS = 4;
    private const MAX_SOURCES = 4;

    private const PRIVATE_PATH_PREFIXES = [
        '/admin',
        '/login',
        '/account',
        '/checkout',
        '/cart',
        '/cabinet',
        '/profile',
        '/order',
        '/orders',
        '/customer',
        '/wp-admin',
        '/bitrix/admin',
    ];

    public function build(array $site_context, array $settings): array {
        if (!$this->shouldUseWebGrounding($site_context, $settings)) {
            return [];
        }

        $policy = new WidgetDomainPolicy((string)($settings[WidgetDomainPolicy::SETTING_BASE_DOMAIN] ?? ''));
        $urls = [];
        $this->appendPageUrl($urls, $site_context['current_page'] ?? [], $policy);
        foreach ((array)($site_context['previous_pages'] ?? []) as $page) {
            $this->appendPageUrl($urls, is_array($page) ? $page : [], $policy);
            if (count($urls) >= self::MAX_URLS) {
                break;
            }
        }

        if (!$urls) {
            return [];
        }

        $base_domain = $policy->baseDomain();
        $payload = [
            'enabled' => 'auto',
            'scope' => 'url_only',
            'mode' => 'grounded',
            'provider' => 'default',
            'urls' => array_values($urls),
            'max_sources' => min(self::MAX_SOURCES, count($urls)),
            'return_sources' => true,
        ];

        if ($base_domain !== '' && !filter_var($base_domain, FILTER_VALIDATE_IP) && $base_domain !== 'localhost') {
            $payload['include_domains'] = [$base_domain];
        }

        return $payload;
    }

    private function shouldUseWebGrounding(array $site_context, array $settings): bool {
        if (empty($site_context['available']) || empty($site_context['current_page'])) {
            return false;
        }

        $provider = strtolower(trim((string)($settings['chat_ai_provider'] ?? 'easytokens')));
        if (!in_array($provider, ['easytokens', ''], true)) {
            return false;
        }

        $auto_enabled = (string)($settings['chat_ai_status'] ?? '0') === '1';
        $suggestions_enabled = (string)($settings['chat_ai_suggestions_status'] ?? '0') === '1';
        if (!$auto_enabled && !$suggestions_enabled) {
            return false;
        }

        $cms_type = strtolower(trim((string)($settings['chat_cms_type'] ?? 'none')));
        if ($cms_type !== '' && $cms_type !== 'none') {
            return false;
        }

         
         
         
        return true;
    }

    private function appendPageUrl(array &$urls, array $page, WidgetDomainPolicy $policy): void {
        $context = is_array($page['context'] ?? null) ? $page['context'] : [];
        $candidates = [
            (string)($context['canonical_url'] ?? ''),
            (string)($page['url'] ?? ''),
            (string)($context['url'] ?? ''),
        ];

        foreach ($candidates as $candidate) {
            $url = $this->normalizePublicUrl($candidate, $policy);
            if ($url === '' || in_array($url, $urls, true)) {
                continue;
            }
            $urls[] = $url;
            return;
        }
    }

    private function normalizePublicUrl(string $url, WidgetDomainPolicy $policy): string {
        $url = trim($url);
        if ($url === '' || !$policy->isUrlAllowed($url)) {
            return '';
        }

        $parts = parse_url($url);
        if (!is_array($parts) || empty($parts['host'])) {
            return '';
        }

        $scheme = strtolower((string)($parts['scheme'] ?? 'https'));
        if (!in_array($scheme, ['http', 'https'], true)) {
            return '';
        }

        $path = (string)($parts['path'] ?? '/');
        if ($this->isPrivatePath($path)) {
            return '';
        }

        $host = WidgetDomainPolicy::normalizeHost((string)$parts['host']);
        $normalized = $scheme . '://' . $host;
        if (!empty($parts['port'])) {
            $normalized .= ':' . (int)$parts['port'];
        }
        $normalized .= $path !== '' ? $path : '/';
        if (!empty($parts['query'])) {
            $normalized .= '?' . (string)$parts['query'];
        }

        return $normalized;
    }

    private function isPrivatePath(string $path): bool {
        $path = '/' . ltrim(strtolower($path), '/');
        foreach (self::PRIVATE_PATH_PREFIXES as $prefix) {
            if ($path === $prefix || strpos($path, $prefix . '/') === 0) {
                return true;
            }
        }
        return false;
    }
}
