<?php
namespace EasyChat\Library;

class CustomerProfileDetector {
    private const MAX_URL_LENGTH = 512;

    public function detect(string $text): array {
        $text = trim($text);
        if ($text === '') {
            return [];
        }

        preg_match_all('#https?://[^\s<>"\'\]\)]+#iu', $text, $matches);
        $profiles = [];
        $seen = [];
        foreach ($matches[0] ?? [] as $raw_url) {
            $normalized = $this->normalizeUrl($raw_url);
            if (!$normalized) {
                continue;
            }
            $key = $normalized['provider'] . '|' . $normalized['profile_url'];
            if (isset($seen[$key])) {
                continue;
            }
            $seen[$key] = true;
            $profiles[] = $normalized;
        }

        return $profiles;
    }

    public function normalizeUrl(string $url): ?array {
        $url = trim($url);
        $url = trim($url, " \t\n\r\0\x0B.,;:!?)]}");
        if ($url === '' || strlen($url) > self::MAX_URL_LENGTH) {
            return null;
        }

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

        $scheme = strtolower((string)$parts['scheme']);
        if ($scheme !== 'http' && $scheme !== 'https') {
            return null;
        }

        $host = strtolower((string)$parts['host']);
        $host = preg_replace('/^www\./', '', $host);
        $path = isset($parts['path']) ? '/' . ltrim((string)$parts['path'], '/') : '/';
        $path = preg_replace('#/+#', '/', $path);
        $path = rtrim($path, '/');
        $query = isset($parts['query']) ? (string)$parts['query'] : '';

        if ($host === 'telegram.me') {
            $host = 't.me';
        }
        if ($host === 'm.vk.com') {
            $host = 'vk.com';
        }
        if ($host === 'm.avito.ru') {
            $host = 'avito.ru';
        }
        if ($host === 'm.youla.ru') {
            $host = 'youla.ru';
        }

        if ($host === 't.me') {
            $username = ltrim($path, '/');
            if (!preg_match('/^[A-Za-z0-9_]{5,32}$/', $username)) {
                return null;
            }
            return $this->payload('telegram', 'https://t.me/' . $username, $username);
        }

        if ($host === 'vk.com') {
            $slug = ltrim($path, '/');
            if (!preg_match('/^(id[0-9]{1,20}|[A-Za-z0-9_.-]{1,64})$/', $slug)) {
                return null;
            }
            return $this->payload('vk', 'https://vk.com/' . $slug, $slug);
        }

        if ($host === 'max.ru') {
            $segments = array_values(array_filter(explode('/', ltrim($path, '/')), 'strlen'));
            if (count($segments) !== 2 || $segments[0] !== 'u') {
                return null;
            }
            $slug = $segments[1];
            if (!preg_match('/^[A-Za-z0-9_.-]{1,64}$/', $slug)) {
                return null;
            }
            return $this->payload('max', 'https://max.ru/u/' . $slug, $slug);
        }

        if ($host === 'avito.ru') {
            if ($path === '' || $path === '/') {
                return null;
            }
            $normalized = 'https://www.avito.ru' . $path;
            if ($query !== '') {
                $normalized .= '?' . $this->filterAvitoQuery($query);
                $normalized = rtrim($normalized, '?');
            }
            return $this->payload('avito', $normalized, '');
        }

        if ($host === 'youla.ru' || $host === 'youla.io' || $host === 'youla.link') {
            if ($path === '' || $path === '/') {
                return null;
            }
            $normalized = 'https://' . $host . $path;
            return $this->payload('youla', $normalized, '');
        }

        return null;
    }

    public function providerLabel(string $provider): string {
        switch (strtolower($provider)) {
            case 'telegram':
                return 'Telegram';
            case 'avito':
                return 'Авито';
            case 'youla':
                return 'Юла';
            case 'max':
                return 'MAX';
            case 'vk':
                return 'VK';
            default:
                return strtoupper($provider);
        }
    }

    private function payload(string $provider, string $url, string $username): array {
        return [
            'provider' => $provider,
            'provider_label' => $this->providerLabel($provider),
            'profile_url' => $url,
            'profile_url_hash' => hash('sha256', $url),
            'username' => $username,
        ];
    }

    private function filterAvitoQuery(string $query): string {
        parse_str($query, $params);
        $allowed = [];
        foreach (['id', 'user', 'sellerId'] as $key) {
            if (isset($params[$key]) && preg_match('/^[A-Za-z0-9_.:-]{1,80}$/', (string)$params[$key])) {
                $allowed[$key] = (string)$params[$key];
            }
        }
        return http_build_query($allowed, '', '&', PHP_QUERY_RFC3986);
    }
}
