<?php

declare(strict_types=1);

if (PHP_SAPI !== 'cli') {
    http_response_code(403);
    echo "This script can be run only from CLI.\n";
    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';

$options = getopt('', ['field-name::', 'field-code::', 'help']);
if (isset($options['help'])) {
    echo "Usage: php tools/add_prompt_openline_fields.php [--field-name=\"ID открытой линии\"] [--field-code=OPEN_LINE_ID]\n";
    exit(0);
}

$fieldName = trim((string) ($options['field-name'] ?? 'ID открытой линии'));
$fieldCode = trim((string) ($options['field-code'] ?? 'OPEN_LINE_ID'));

if ($fieldName === '' || $fieldCode === '') {
    fwrite(STDERR, "Field name and field code must not be empty.\n");
    exit(1);
}

try {
    $system = ensurePromptOpenLineField((string) config('SYSTEM_PROMPTS_LIST_CODE'), $fieldName, $fieldCode);
    $correction = ensurePromptOpenLineField((string) config('CORRECTION_PROMPTS_LIST_CODE'), $fieldName, $fieldCode);

    $result = [
        'system' => $system,
        'correction' => $correction,
        'env' => [
            'SYSTEM_PROMPT_OPEN_LINE_PROPERTY' => $system['field_id'],
            'CORRECTION_PROMPT_OPEN_LINE_PROPERTY' => $correction['field_id'],
        ],
    ];

    echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . PHP_EOL;

    echo PHP_EOL . "Add this to .env.php:" . PHP_EOL;
    echo "'SYSTEM_PROMPT_OPEN_LINE_PROPERTY' => '" . $system['field_id'] . "'," . PHP_EOL;
    echo "'CORRECTION_PROMPT_OPEN_LINE_PROPERTY' => '" . $correction['field_id'] . "'," . PHP_EOL;
} catch (Throwable $exception) {
    fwrite(STDERR, $exception->getMessage() . PHP_EOL);
    exit(1);
}

function ensurePromptOpenLineField(string $listCode, string $fieldName, string $fieldCode): array
{
    if ($listCode === '') {
        throw new RuntimeException('Prompt list code is empty.');
    }

    $list = findBitrixListByCode($listCode);
    if ($list === null) {
        throw new RuntimeException('Bitrix list not found: ' . $listCode);
    }

    $iblockTypeId = (string) ($list['_IBLOCK_TYPE_ID'] ?? 'lists');
    $iblockId = (int) ($list['ID'] ?? 0);
    if ($iblockId <= 0) {
        throw new RuntimeException('Bitrix list ID is empty: ' . $listCode);
    }

    $existingFieldId = findPromptOpenLineFieldId($iblockTypeId, $iblockId, $fieldCode, $fieldName);
    if ($existingFieldId !== '') {
        return [
            'list_code' => $listCode,
            'iblock_type_id' => $iblockTypeId,
            'iblock_id' => $iblockId,
            'field_id' => $existingFieldId,
            'created' => false,
        ];
    }

    $response = bitrixCall('lists.field.add', [
        'IBLOCK_TYPE_ID' => $iblockTypeId,
        'IBLOCK_ID' => $iblockId,
        'FIELDS' => [
            'NAME' => $fieldName,
            'TYPE' => 'S',
            'CODE' => $fieldCode,
            'IS_REQUIRED' => 'N',
            'MULTIPLE' => 'N',
            'SORT' => '500',
            'SETTINGS' => [
                'SHOW_ADD_FORM' => 'Y',
                'SHOW_EDIT_FORM' => 'Y',
                'ADD_READ_ONLY_FIELD' => 'N',
                'EDIT_READ_ONLY_FIELD' => 'N',
                'SHOW_FIELD_PREVIEW' => 'Y',
            ],
        ],
    ]);

    $fieldId = normalizeBitrixListFieldId($response['result'] ?? '');
    if ($fieldId === '') {
        throw new RuntimeException('Bitrix returned empty field id for list: ' . $listCode);
    }

    return [
        'list_code' => $listCode,
        'iblock_type_id' => $iblockTypeId,
        'iblock_id' => $iblockId,
        'field_id' => $fieldId,
        'created' => true,
    ];
}

function findPromptOpenLineFieldId(string $iblockTypeId, int $iblockId, string $fieldCode, string $fieldName): string
{
    $response = bitrixCallRaw('lists.field.get', [
        'IBLOCK_TYPE_ID' => $iblockTypeId,
        'IBLOCK_ID' => $iblockId,
    ]);

    foreach ((array) ($response['result'] ?? []) as $fieldId => $field) {
        $field = (array) $field;
        $code = trim((string) ($field['CODE'] ?? ''));
        $name = trim((string) ($field['NAME'] ?? ''));

        if ($code === $fieldCode || $name === $fieldName) {
            return normalizeBitrixListFieldId($fieldId);
        }
    }

    return '';
}

function normalizeBitrixListFieldId($fieldId): string
{
    $fieldId = trim((string) $fieldId);
    if ($fieldId === '') {
        return '';
    }

    if (ctype_digit($fieldId)) {
        return 'PROPERTY_' . $fieldId;
    }

    return $fieldId;
}
