<?php

declare(strict_types=1);

if (PHP_SAPI !== 'cli') {
    http_response_code(403);
    exit(1);
}

require_once __DIR__ . '/../src/config.php';
require_once __DIR__ . '/../src/logger.php';
require_once __DIR__ . '/../src/storage.php';
require_once __DIR__ . '/../src/bitrix.php';
require_once __DIR__ . '/../src/prompts.php';

$listCode = trim((string) config('FOLLOWUP_SETTINGS_LIST_CODE', 'darex_ai_followups'));

try {
    $list = ensureFollowupList($listCode);
    $fields = ensureFollowupFields($list);
    $elements = ensureFollowupElements($list, $fields);
    $cacheFile = (string) config(
        'FOLLOWUP_SETTINGS_CACHE_FILE',
        __DIR__ . '/../storage/cache/followups.json'
    );
    if (is_file($cacheFile)) {
        unlink($cacheFile);
    }

    echo json_encode([
        'ok' => true,
        'list' => $list,
        'fields' => $fields,
        'elements' => $elements,
        'cache_cleared' => !is_file($cacheFile),
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . PHP_EOL;
} catch (Throwable $exception) {
    fwrite(STDERR, $exception->getMessage() . PHP_EOL);
    exit(1);
}

function ensureFollowupList(string $listCode): array
{
    $existing = findBitrixListByCode($listCode);
    if ($existing !== null) {
        return $existing + ['created' => false];
    }

    $response = bitrixCall('lists.add', [
        'IBLOCK_TYPE_ID' => 'lists',
        'IBLOCK_CODE' => $listCode,
        'FIELDS' => [
            'NAME' => 'Darex AI: догоняющие сообщения',
            'DESCRIPTION' => 'Тексты и задержки отправки догоняющих сообщений AI-бота.',
            'SORT' => 520,
            'BIZPROC' => 'N',
        ],
        'MESSAGES' => [
            'ELEMENTS_NAME' => 'Этапы сообщений',
            'ELEMENT_NAME' => 'Этап сообщения',
            'ELEMENT_ADD' => 'Добавить этап',
            'ELEMENT_EDIT' => 'Изменить этап',
            'ELEMENT_DELETE' => 'Удалить этап',
        ],
    ]);
    $iblockId = (int) ($response['result'] ?? 0);
    if ($iblockId <= 0) {
        throw new RuntimeException('Bitrix returned an empty followup list ID.');
    }

    return [
        'ID' => $iblockId,
        'CODE' => $listCode,
        '_IBLOCK_TYPE_ID' => 'lists',
        'created' => true,
    ];
}

function ensureFollowupFields(array $list): array
{
    $type = (string) ($list['_IBLOCK_TYPE_ID'] ?? 'lists');
    $id = (int) ($list['ID'] ?? 0);
    $response = bitrixCall('lists.field.get', ['IBLOCK_TYPE_ID' => $type, 'IBLOCK_ID' => $id]);
    $existing = [];
    foreach ((array) ($response['result'] ?? []) as $fieldId => $field) {
        $field = (array) $field;
        $code = trim((string) ($field['CODE'] ?? ''));
        if ($code !== '') {
            $existing[$code] = normalizeFollowupPropertyId($fieldId);
        }
    }

    $definitions = [
        'STAGE_NUMBER' => ['NAME' => 'Номер попытки', 'TYPE' => 'N', 'SORT' => 100],
        'DELAY_MINUTES' => ['NAME' => 'Задержка, минут', 'TYPE' => 'N', 'SORT' => 200],
        'MESSAGE' => ['NAME' => 'Общее сообщение', 'TYPE' => 'S', 'SORT' => 300],
        'MESSAGE_NEED_CITY' => ['NAME' => 'Если не получен город', 'TYPE' => 'S', 'SORT' => 400],
        'MESSAGE_NEED_PHONE' => ['NAME' => 'Если не получен телефон', 'TYPE' => 'S', 'SORT' => 500],
    ];

    foreach ($definitions as $code => $definition) {
        if (isset($existing[$code])) {
            continue;
        }

        $fieldResponse = bitrixCall('lists.field.add', [
            'IBLOCK_TYPE_ID' => $type,
            'IBLOCK_ID' => $id,
            'FIELDS' => $definition + [
                'CODE' => $code,
                'IS_REQUIRED' => in_array($code, ['STAGE_NUMBER', 'DELAY_MINUTES'], true) ? 'Y' : 'N',
                'MULTIPLE' => 'N',
                'SETTINGS' => [
                    'SHOW_ADD_FORM' => 'Y',
                    'SHOW_EDIT_FORM' => 'Y',
                    'SHOW_FIELD_PREVIEW' => 'Y',
                ],
            ],
        ]);
        $existing[$code] = normalizeFollowupPropertyId($fieldResponse['result'] ?? '');
    }

    return $existing;
}

function ensureFollowupElements(array $list, array $fields): array
{
    $type = (string) ($list['_IBLOCK_TYPE_ID'] ?? 'lists');
    $id = (int) ($list['ID'] ?? 0);
    $response = bitrixCall('lists.element.get', ['IBLOCK_TYPE_ID' => $type, 'IBLOCK_ID' => $id]);
    $existingCodes = [];
    foreach ((array) ($response['result'] ?? []) as $element) {
        $element = (array) $element;
        $code = trim((string) ($element['CODE'] ?? ''));
        if ($code !== '') {
            $existingCodes[$code] = (string) ($element['ID'] ?? '');
        }
    }

    $offsets = normalizeSetupOffsets(config('FOLLOWUP_OFFSETS_SECONDS', [3600, 10800, 86400, 172800]));
    $generic = (array) config('FOLLOWUP_MESSAGES', []);
    $needCity = (array) config('FOLLOWUP_MESSAGES_NEED_CITY', []);
    $needPhone = (array) config('FOLLOWUP_MESSAGES_NEED_PHONE', []);
    $created = [];

    foreach ($offsets as $index => $seconds) {
        $number = $index + 1;
        $code = 'followup_' . $number;
        if (isset($existingCodes[$code])) {
            $created[] = ['code' => $code, 'id' => $existingCodes[$code], 'created' => false];
            continue;
        }

        $fieldsPayload = [
            'NAME' => 'Попытка ' . $number,
            'ACTIVE' => 'Y',
            'SORT' => $number * 100,
            $fields['STAGE_NUMBER'] => $number,
            $fields['DELAY_MINUTES'] => (int) round($seconds / 60),
            $fields['MESSAGE'] => trim((string) ($generic[$index] ?? '')),
            $fields['MESSAGE_NEED_CITY'] => trim((string) ($needCity[$index] ?? '')),
            $fields['MESSAGE_NEED_PHONE'] => trim((string) ($needPhone[$index] ?? '')),
        ];
        $elementResponse = bitrixCall('lists.element.add', [
            'IBLOCK_TYPE_ID' => $type,
            'IBLOCK_ID' => $id,
            'ELEMENT_CODE' => $code,
            'FIELDS' => $fieldsPayload,
        ]);
        $created[] = ['code' => $code, 'id' => (string) ($elementResponse['result'] ?? ''), 'created' => true];
    }

    return $created;
}

function normalizeFollowupPropertyId($value): string
{
    $value = trim((string) $value);
    if ($value === '') {
        throw new RuntimeException('Bitrix returned an empty followup field ID.');
    }

    return str_starts_with($value, 'PROPERTY_') ? $value : 'PROPERTY_' . $value;
}

function normalizeSetupOffsets($value): array
{
    if (is_string($value)) {
        $value = array_map('trim', explode(',', $value));
    }

    $result = [];
    foreach ((array) $value as $seconds) {
        $seconds = (int) $seconds;
        if ($seconds > 0) {
            $result[] = $seconds;
        }
    }

    return $result;
}
