<?php

declare(strict_types=1);

function chatHistoryKey(array $context): string
{
    $dialogId = trim((string) ($context['dialog_id'] ?? ''));
    if ($dialogId !== '') {
        return 'dialog:' . $dialogId;
    }

    $chatId = trim((string) ($context['chat_id'] ?? ''));
    if ($chatId !== '') {
        return 'chat:' . $chatId;
    }

    return 'default';
}

function getChatHistory(array $context): array
{
    $history = readJsonFile((string) config('CHAT_HISTORY_FILE'), ['chats' => []]);
    $key = chatHistoryKey($context);
    $messages = $history['chats'][$key]['messages'] ?? [];

    return is_array($messages) ? $messages : [];
}

function appendChatHistory(array $context, string $role, string $content): void
{
    $role = $role === 'assistant' ? 'assistant' : 'user';
    $content = trim($content);
    if ($content === '') {
        return;
    }

    $file = (string) config('CHAT_HISTORY_FILE');
    $history = readJsonFile($file, ['chats' => []]);
    $key = chatHistoryKey($context);

    if (!isset($history['chats'][$key]) || !is_array($history['chats'][$key])) {
        $history['chats'][$key] = [
            'context' => $context,
            'messages' => [],
        ];
    }

    $history['chats'][$key]['context'] = $context;
    $history['chats'][$key]['updated_at'] = date('c');

    if ($role === 'user') {
        unset($history['chats'][$key]['followup_sent_at']);
        unset($history['chats'][$key]['followup_for_message_at']);
        unset($history['chats'][$key]['followup_started_at']);
        unset($history['chats'][$key]['followups']);
        unset($history['chats'][$key]['no_response_marked_at']);
    }

    $history['chats'][$key]['messages'][] = [
        'role' => $role,
        'content' => $content,
        'created_at' => date('c'),
    ];

    $maxMessages = max(2, (int) config('CHAT_HISTORY_MAX_MESSAGES', 20));
    $history['chats'][$key]['messages'] = array_slice($history['chats'][$key]['messages'], -$maxMessages);

    writeJsonFile($file, $history);
}

function mergeChatContactData(array $context, array $contact): array
{
    $file = (string) config('CHAT_HISTORY_FILE');
    $history = readJsonFile($file, ['chats' => []]);
    $key = chatHistoryKey($context);

    if (!isset($history['chats'][$key]) || !is_array($history['chats'][$key])) {
        $history['chats'][$key] = [
            'context' => $context,
            'messages' => [],
        ];
    }

    $stored = (array) ($history['chats'][$key]['contact'] ?? []);
    foreach (['phone', 'city', 'full_name', 'interest_group'] as $field) {
        $value = trim((string) ($contact[$field] ?? ''));
        if ($value !== '') {
            $stored[$field] = $value;
        }
    }

    $stored += [
        'phone' => '',
        'city' => '',
        'full_name' => '',
        'interest_group' => '',
    ];

    $history['chats'][$key]['contact'] = $stored;
    $history['chats'][$key]['context'] = array_filter($context, static fn ($value): bool => $value !== null && $value !== '');
    $history['chats'][$key]['updated_at'] = date('c');

    writeJsonFile($file, $history);

    return $stored;
}

function getChatContactData(array $context): array
{
    $history = readJsonFile((string) config('CHAT_HISTORY_FILE'), ['chats' => []]);
    $key = chatHistoryKey($context);
    $contact = (array) ($history['chats'][$key]['contact'] ?? []);

    return [
        'phone' => trim((string) ($contact['phone'] ?? '')),
        'city' => trim((string) ($contact['city'] ?? '')),
        'full_name' => trim((string) ($contact['full_name'] ?? '')),
        'interest_group' => normalizeInterestGroup($contact['interest_group'] ?? ''),
    ];
}

function normalizeInterestGroup($value): string
{
    $value = trim((string) $value);
    if ($value === '') {
        return '';
    }

    $value = function_exists('mb_strtolower')
        ? mb_strtolower($value, 'UTF-8')
        : strtolower($value);

    return in_array($value, ['техника', 'запчасти', 'сервис', 'другое'], true) ? $value : '';
}

function isContactDataComplete(array $contact): bool
{
    return trim((string) ($contact['phone'] ?? '')) !== ''
        && trim((string) ($contact['city'] ?? '')) !== '';
}

function markChatAwaitingClientReply(array $context): void
{
    $file = (string) config('CHAT_HISTORY_FILE');
    $history = readJsonFile($file, ['chats' => []]);
    $key = chatHistoryKey($context);

    if (!isset($history['chats'][$key]) || !is_array($history['chats'][$key])) {
        $history['chats'][$key] = [
            'context' => $context,
            'messages' => [],
        ];
    }

    $history['chats'][$key]['context'] = array_filter($context, static fn ($value): bool => $value !== null && $value !== '');
    if (trim((string) ($history['chats'][$key]['followup_started_at'] ?? '')) === '') {
        $history['chats'][$key]['followup_started_at'] = date('c');
    }

    if (!isset($history['chats'][$key]['followups']) || !is_array($history['chats'][$key]['followups'])) {
        $history['chats'][$key]['followups'] = [
            'sent' => [],
        ];
    }

    writeJsonFile($file, $history);
}

function clearChatAwaitingClientReply(array $context): void
{
    $file = (string) config('CHAT_HISTORY_FILE');
    $history = readJsonFile($file, ['chats' => []]);
    $key = chatHistoryKey($context);

    if (!isset($history['chats'][$key]) || !is_array($history['chats'][$key])) {
        return;
    }

    unset($history['chats'][$key]['followup_started_at']);
    unset($history['chats'][$key]['followups']);
    unset($history['chats'][$key]['followup_sent_at']);
    unset($history['chats'][$key]['followup_for_message_at']);
    unset($history['chats'][$key]['no_response_marked_at']);

    writeJsonFile($file, $history);
}

function clearChatHistory(?string $dialogId = null, ?string $chatId = null): array
{
    $file = (string) config('CHAT_HISTORY_FILE');
    $history = readJsonFile($file, ['chats' => []]);

    if ($dialogId === null && $chatId === null) {
        writeJsonFile($file, ['chats' => []]);

        return ['cleared' => 'all'];
    }

    $context = [];
    if ($dialogId !== null && $dialogId !== '') {
        $context['dialog_id'] = $dialogId;
    }
    if ($chatId !== null && $chatId !== '') {
        $context['chat_id'] = $chatId;
    }

    $key = chatHistoryKey($context);
    unset($history['chats'][$key]);
    writeJsonFile($file, $history);

    return ['cleared' => $key];
}

function listChatHistories(): array
{
    return readJsonFile((string) config('CHAT_HISTORY_FILE'), ['chats' => []]);
}

function markChatFollowupSent(string $chatKey, int $stageIndex, string $message): void
{
    $file = (string) config('CHAT_HISTORY_FILE');
    $history = readJsonFile($file, ['chats' => []]);

    if (!isset($history['chats'][$chatKey]) || !is_array($history['chats'][$chatKey])) {
        return;
    }

    if (!isset($history['chats'][$chatKey]['followups']) || !is_array($history['chats'][$chatKey]['followups'])) {
        $history['chats'][$chatKey]['followups'] = [
            'sent' => [],
        ];
    }

    $history['chats'][$chatKey]['followup_sent_at'] = date('c');
    $history['chats'][$chatKey]['followups']['sent'][(string) $stageIndex] = [
        'sent_at' => date('c'),
        'message' => $message,
    ];

    writeJsonFile($file, $history);
}

function markChatNoResponseMarked(string $chatKey, array $crmResult): void
{
    $file = (string) config('CHAT_HISTORY_FILE');
    $history = readJsonFile($file, ['chats' => []]);

    if (!isset($history['chats'][$chatKey]) || !is_array($history['chats'][$chatKey])) {
        return;
    }

    $history['chats'][$chatKey]['no_response_marked_at'] = date('c');
    $history['chats'][$chatKey]['no_response_crm_result'] = $crmResult;

    writeJsonFile($file, $history);
}

function hasPhoneWorkflowStarted(array $context, string $phone): bool
{
    $phone = trim($phone);
    if ($phone === '') {
        return false;
    }

    $history = readJsonFile((string) config('CHAT_HISTORY_FILE'), ['chats' => []]);
    $key = chatHistoryKey($context);
    $workflow = (array) ($history['chats'][$key]['phone_workflow'] ?? []);

    return trim((string) ($workflow['phone'] ?? '')) === $phone
        && trim((string) ($workflow['started_at'] ?? '')) !== '';
}

function markPhoneWorkflowStarted(array $context, string $phone, array $workflowResult): void
{
    $phone = trim($phone);
    if ($phone === '') {
        return;
    }

    $file = (string) config('CHAT_HISTORY_FILE');
    $history = readJsonFile($file, ['chats' => []]);
    $key = chatHistoryKey($context);

    if (!isset($history['chats'][$key]) || !is_array($history['chats'][$key])) {
        $history['chats'][$key] = [
            'context' => $context,
            'messages' => [],
        ];
    }

    $history['chats'][$key]['phone_workflow'] = [
        'phone' => $phone,
        'started_at' => date('c'),
        'result' => $workflowResult,
    ];

    writeJsonFile($file, $history);
}
