<?php

declare(strict_types=1);

function normalizeCollectedPhone(string $phone): string
{
    $phone = trim($phone);
    $digits = preg_replace('/\D+/', '', $phone) ?? '';
    // An explicit international prefix must never be converted into a Russian number.
    if (str_starts_with($phone, '+') && (!str_starts_with($phone, '+7') || strlen($digits) !== 11)) {
        return '';
    }
    if (strlen($digits) === 10) $digits = '7' . $digits;
    if (strlen($digits) === 11 && $digits[0] === '8') $digits = '7' . substr($digits, 1);
    if (strlen($digits) !== 11 || $digits[0] !== '7') return '';
    return sprintf('+7 (%s) %s-%s-%s', substr($digits, 1, 3), substr($digits, 4, 3), substr($digits, 7, 2), substr($digits, 9, 2));
}

function phoneFromClientText(string $text): string
{
    preg_match_all('/(?<![\d\p{L}])\+?\d[\d ()-]{8,22}\d(?!\d)/u', $text, $matches);
    foreach ($matches[0] as $candidate) {
        $phone = normalizeCollectedPhone($candidate);
        if ($phone !== '') return $phone;
    }
    return '';
}

function isConnectorServiceText(string $text): bool
{
    if (isConnectorPhotoRequest($text)) return false;
    return preg_match('/^\s*(?:\[Системное сообщение\]|Входящий звонок\s*$|Исходящий звонок\s*$|Пропущенный звонок\s*$)/iu', trim(strip_tags($text))) === 1;
}

function isConnectorPhotoRequest(string $text): bool
{
    return preg_match('/^\s*\[Системное сообщение\]\s*(?:Здравствуйте[!.,]?\s*)?Пришлите,?\s*пожалуйста,?\s*дополнительные\s+фото\s+или\s+видео\s+(?:мототехники|водной\s+техники)\.?\s*$/iu', trim(strip_tags($text))) === 1;
}

function isExplicitClientPhoneMessage(string $text): bool
{
    if (preg_match('/(?:артикул|номер\s+(?:заказа|детали|объявления)|vin)/iu', $text)) return false;
    return preg_match('/^[\s+\d()\-]+$/u', $text) === 1
        || preg_match('/(?:телефон|мой\s+номер|позвон|для\s+связи|whatsapp|ватсап|вотсап)/iu', $text) === 1;
}

function clientCityFromExplicitText(string $text, array $items): string
{
    foreach ($items as $item) {
        $city = trim((string) ($item['value'] ?? ''));
        if ($city !== '' && preg_match('/(?:^|[\s,;])(?:г\.\s*|город(?:а|е)?\s+|я\s+из\s+|живу\s+в\s+)' . preg_quote($city, '/') . '(?![\p{L}-])/iu', $text)) {
            return $city;
        }
    }
    return '';
}

function isPickupLocationOnly(string $message): bool
{
    return preg_match('/(?:забра[тл]|зае[хд]|приед|самовывоз)/iu', $message) === 1
        && preg_match('/(?:я\s+из|живу|мой\s+город|город\s+проживания)/iu', $message) !== 1;
}

function conversationAnswerIssues(string $answer, array $contact, string $previous = ''): array
{
    $issues = [];
    $phone = normalizeCollectedPhone((string) ($contact['phone'] ?? ''));
    $city = trim((string) ($contact['city'] ?? ''));
    $asksPhone = preg_match('/(?:остав\p{L}*|напиш\p{L}*|пришл\p{L}*|укаж\p{L}*|сообщ\p{L}*|подскаж\p{L}*|нужен)[^.!?\n]{0,100}(?:номер|телефон)|(?:какой|ваш)\s+(?:номер|телефон)[^.!?\n]*\?/iu', $answer);
    $asksCity = preg_match('/(?:из\s+какого\s+(?:вы\s+)?города|в\s+каком\s+городе|(?:напиш\p{L}*|укаж\p{L}*|подскаж\p{L}*)[^.!?\n]{0,50}(?:ваш\s+город|город\s+проживания))/iu', $answer);
    if ($phone !== '' && $asksPhone) $issues[] = 'Do not request the phone: it is already known.';
    if ($city !== '' && $asksCity) $issues[] = 'Do not request the client city: it is already known.';
    if ($phone === '' && preg_match('/(?:номер|телефон)[^.!?\n]{0,60}(?:зафиксир|получ|запис|переда)|(?:зафиксир|получ|запис)[^.!?\n]{0,40}(?:номер|телефон)/iu', $answer)) {
        $issues[] = 'No accepted phone exists. Do not claim a phone was received, saved or handed over.';
    }
    if (preg_match('/(?:передал[аи]?|передан[аы]?|отправил[аи]?|отправлен[аы]?)\s+[^.!?\n]{0,45}менеджер/iu', $answer)) {
        $issues[] = 'Do not claim a completed handoff to a manager without a confirmed handoff result.';
    }
    if (substr_count($answer, '?') > 1) $issues[] = 'Ask at most one question.';
    preg_match_all('/[^.!?\n]*\?/u', $previous, $questions);
    foreach ($questions[0] as $question) {
        $question = trim($question);
        if ($question !== '' && preg_match('/' . preg_quote($question, '/') . '/iu', $answer)) {
            $issues[] = 'Do not repeat the previous question. Address the latest client message.';
            break;
        }
    }
    return array_values(array_unique($issues));
}

function safeConversationAnswer(string $answer, array $contact, string $previous): string
{
    $parts = preg_split('/(?<=[.!?])\s+|\n+/u', trim($answer)) ?: [];
    $kept = [];
    $questionUsed = false;
    foreach ($parts as $part) {
        if (conversationAnswerIssues($part, $contact, $previous) !== []) continue;
        if (str_contains($part, '?')) {
            if ($questionUsed) continue;
            $questionUsed = true;
        }
        $kept[] = $part;
    }
    return trim(implode(' ', $kept)) ?: 'Для точного ответа потребуется уточнение у менеджера.';
}
