import $ from 'jquery';
import { JSONRPC } from '@/json-rpc.js';

const FIELD_IDS = {
    storageSelect: 'local-storages-storage-select',
    storageStatus: 'local-storages-storage-status',
    createButton: 'local-storages-create-btn',
    listContainer: 'local-storages-list',
    modalOverlay: 'local-storages-modal',
    modalTitle: 'local-storages-modal-title',
    modalForm: 'local-storages-form',
    nameInput: 'local-storages-name',
    descriptionInput: 'local-storages-description',
    domainsInput: 'local-storages-domains',
    asnInput: 'local-storages-asn',
    subnetsInput: 'local-storages-subnets',
    resolveDomainsCheckbox: 'local-storages-resolve-domains',
    modalStatus: 'local-storages-modal-status',
    modalSaveButton: 'local-storages-save-btn',
    modalCancelButton: 'local-storages-cancel-btn'
};

const SELECTORS = Object.entries(FIELD_IDS).reduce((acc, [key, value]) => {
    acc[key] = `#${value}`;
    return acc;
}, {});

const REFRESH_DELAY_MS = 5000;

let repositories = [];
let availableResources = {};
let selectedRepository = '';
let currentModalMode = 'create';
let currentModalResourceName = '';
let resourcesRequestId = 0;

function escapeHtml(value) {
    return String(value)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;');
}

function splitLines(text) {
    if (!text) {
        return [];
    }
    return text
        .split(/\r?\n/)
        .map(line => line.trim())
        .filter(line => line.length > 0);
}

function joinLines(items) {
    if (!Array.isArray(items)) {
        return '';
    }
    return items.map(item => String(item ?? '').trim()).filter(item => item.length > 0).join('\n');
}

function parseAsn(list) {
    const values = splitLines(list);
    const parsed = [];
    for (const item of values) {
        if (!/^\d+$/.test(item)) {
            return { success: false, error: `Некорректное значение ASN: ${item}` };
        }
        parsed.push(Number(item));
    }
    return { success: true, value: parsed };
}

function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

function getResourceKey(storage, name) {
    return `${storage}:${name}`;
}

function getResourcesForStorage(storage) {
    if (!storage) {
        return [];
    }
    return Object.keys(availableResources)
        .filter(key => key.startsWith(`${storage}:`))
        .map(key => ({
            key,
            name: key.substring(storage.length + 1),
            data: availableResources[key]
        }))
        .sort((a, b) => a.name.localeCompare(b.name, 'ru', { sensitivity: 'base' }));
}

function setStorageStatus(message, type) {
    const $status = $(SELECTORS.storageStatus);
    if (!$status.length) {
        return;
    }
    if (!message) {
        $status.hide().text('').removeClass('error-message success-message');
        return;
    }
    $status
        .text(message)
        .removeClass('success-message error-message')
        .addClass(type === 'success' ? 'success-message' : 'error-message')
        .show();
}

function setModalStatus(message, type) {
    const $status = $(SELECTORS.modalStatus);
    if (!$status.length) {
        return;
    }
    if (!message) {
        $status.hide().text('').removeClass('error-message success-message');
        return;
    }
    $status
        .text(message)
        .removeClass('success-message error-message')
        .addClass(type === 'success' ? 'success-message' : 'error-message')
        .show();
}

function renderStorageOptions() {
    const $select = $(SELECTORS.storageSelect);
    if (!$select.length) {
        return;
    }

    if (!repositories.length) {
        $select
            .html('<option value="">Нет доступных хранилищ</option>')
            .prop('disabled', true);
        $(SELECTORS.createButton).prop('disabled', true);
        renderResourceList();
        return;
    }

    const optionsHtml = repositories
        .map(repo => `<option value="${escapeHtml(repo)}"${repo === selectedRepository ? ' selected' : ''}>${escapeHtml(repo)}</option>`)
        .join('');

    $select
        .html(optionsHtml)
        .prop('disabled', false);

    if (!selectedRepository || !repositories.includes(selectedRepository)) {
        selectedRepository = repositories[0];
    }

    $(SELECTORS.createButton).prop('disabled', false);
}

function renderLoadingList() {
    const $list = $(SELECTORS.listContainer);
    $list.html('<p>Загрузка содержимого...</p>');
}

function renderUpdatingPlaceholder() {
    const $list = $(SELECTORS.listContainer);
    $list.html('<p>Обновление...</p>');
}

function renderResourceList() {
    const $list = $(SELECTORS.listContainer);
    if (!$list.length) {
        return;
    }

    if (!repositories.length) {
        $list.html('<p>Нет локальных хранилищ.</p>');
        return;
    }

    if (!selectedRepository) {
        $list.html('<p>Выберите хранилище, чтобы просмотреть содержимое.</p>');
        return;
    }

    const resources = getResourcesForStorage(selectedRepository);

    if (!resources.length) {
        $list.html('<p>В хранилище нет ресурсов.</p>');
        return;
    }

    const rowsHtml = resources.map(resource => {
        const safeName = escapeHtml(resource.name);
        return `
            <div class="subscription-item" style="display: flex; align-items: center; justify-content: space-between; gap: 12px;">
                <span style="flex-grow: 1;">${safeName}</span>
                <div style="display: flex; gap: 8px;">
                    <button type="button" class="btn-secondary local-storage-edit" data-name="${safeName}">Редактировать</button>
                    <button type="button" class="btn-link local-storage-delete" data-name="${safeName}">Удалить</button>
                </div>
            </div>
        `;
    }).join('');

    $list.html(`
        <div class="subscription-list" style="padding: 0; margin: 0; border: none; background: transparent; display: flex; flex-direction: column; gap: 12px;">${rowsHtml}</div>
    `);
}

async function loadRepositories() {
    try {
        repositories = await JSONRPC.SubscriptionManager.getLocalRepositories();
        if (!Array.isArray(repositories)) {
            repositories = [];
        }
        renderStorageOptions();
        setStorageStatus('', '');
    } catch (error) {
        console.error('Ошибка получения хранилищ:', error);
        repositories = [];
        selectedRepository = '';
        renderStorageOptions();
        setStorageStatus('Не удалось получить список хранилищ.', 'error');
    }
}

async function loadAvailableResources(currentRequestId) {
    try {
        const data = await JSONRPC.SubscriptionManager.getAvailableResources();
        if (currentRequestId !== resourcesRequestId) {
            return;
        }
        availableResources = typeof data === 'object' && data !== null ? data : {};
        renderResourceList();
    } catch (error) {
        if (currentRequestId !== resourcesRequestId) {
            return;
        }
        console.error('Ошибка получения содержимого хранилища:', error);
        availableResources = {};
        const $list = $(SELECTORS.listContainer);
        $list.html('<p class="error-message">Не удалось загрузить содержимое.</p>');
    }
}

function openModal(mode, resourceName = '') {
    currentModalMode = mode;
    currentModalResourceName = resourceName;

    const $overlay = $(SELECTORS.modalOverlay);
    const $title = $(SELECTORS.modalTitle);
    const $nameInput = $(SELECTORS.nameInput);
    const $descriptionInput = $(SELECTORS.descriptionInput);
    const $domainsInput = $(SELECTORS.domainsInput);
    const $asnInput = $(SELECTORS.asnInput);
    const $subnetsInput = $(SELECTORS.subnetsInput);
    const $resolveDomainsCheckbox = $(SELECTORS.resolveDomainsCheckbox);
    const $saveButton = $(SELECTORS.modalSaveButton);

    setModalStatus('', '');

    if (mode === 'edit') {
        const key = getResourceKey(selectedRepository, resourceName);
        const resource = availableResources[key] || {};
        $title.text(`Редактирование ресурса ${resourceName}`);
        $nameInput.val(resourceName).prop('disabled', true);
        $descriptionInput.val(resource.description || '');
        $domainsInput.val(joinLines(resource.domains));
        $asnInput.val(joinLines(resource.ASN));
        $subnetsInput.val(joinLines(resource.subnets));
        $resolveDomainsCheckbox.prop('checked', resource.resolveDomains === true);
    } else {
        $title.text('Создание ресурса');
        $nameInput.val('').prop('disabled', false);
        $descriptionInput.val('');
        $domainsInput.val('');
        $asnInput.val('');
        $subnetsInput.val('');
        $resolveDomainsCheckbox.prop('checked', false);
    }

    $saveButton.prop('disabled', false).text('Сохранить');
    $overlay.css('display', 'flex');
}

function closeModal() {
    const $overlay = $(SELECTORS.modalOverlay);
    const $saveButton = $(SELECTORS.modalSaveButton);
    const $form = $(SELECTORS.modalForm);
    setModalStatus('', '');
    $saveButton.prop('disabled', false).text('Сохранить');
    if ($form.length) {
        $form[0].reset();
    }
    $overlay.hide();
}

function validateName(name) {
    if (!name.trim()) {
        return 'Имя обязательно для заполнения.';
    }
    if (!/^[A-Za-z0-9.-]+$/.test(name)) {
        return 'Допускаются латинские буквы, цифры, точка и дефис.';
    }
    return '';
}

async function handleModalSubmit(event) {
    event.preventDefault();
    if (!selectedRepository) {
        setModalStatus('Выберите хранилище.', 'error');
        return;
    }

    const $saveButton = $(SELECTORS.modalSaveButton);
    const $nameInput = $(SELECTORS.nameInput);
    const $descriptionInput = $(SELECTORS.descriptionInput);
    const $domainsInput = $(SELECTORS.domainsInput);
    const $asnInput = $(SELECTORS.asnInput);
    const $subnetsInput = $(SELECTORS.subnetsInput);
    const $resolveDomainsCheckbox = $(SELECTORS.resolveDomainsCheckbox);

    const nameValue = ($nameInput.val() || '').trim();
    const validationError = validateName(nameValue);
    if (validationError) {
        setModalStatus(validationError, 'error');
        return;
    }

    if (currentModalMode === 'create') {
        const existing = getResourcesForStorage(selectedRepository).some(resource => resource.name === nameValue);
        if (existing) {
            setModalStatus('Ресурс с таким именем уже существует.', 'error');
            return;
        }
    }

    const descriptionValue = ($descriptionInput.val() || '').trim();
    const domainsValue = splitLines($domainsInput.val());
    const subnetsValue = splitLines($subnetsInput.val());
    const parsedAsn = parseAsn($asnInput.val());
    if (!parsedAsn.success) {
        setModalStatus(parsedAsn.error, 'error');
        return;
    }

    $saveButton.prop('disabled', true).text('Сохранение...');
    setModalStatus('', '');

    try {
        await JSONRPC.SubscriptionManager.writeLocalResourceFile(
            nameValue,
            descriptionValue,
            domainsValue,
            parsedAsn.value,
            subnetsValue,
            [],
            $resolveDomainsCheckbox.is(':checked'),
            selectedRepository,
            false
        );
        closeModal();
        setStorageStatus('Изменения успешно сохранены.', 'success');
        renderUpdatingPlaceholder();
        await delay(REFRESH_DELAY_MS);
        await refreshResourceList();
        setTimeout(() => setStorageStatus('', ''), 3000);
    } catch (error) {
        console.error('Ошибка сохранения ресурса:', error);
        setModalStatus('Не удалось сохранить ресурс.', 'error');
        $saveButton.prop('disabled', false).text('Сохранить');
    }
}

async function handleDeleteResource(name) {
    if (!selectedRepository) {
        return;
    }
    const confirmed = window.confirm(`Удалить ресурс "${name}"?`);
    if (!confirmed) {
        return;
    }
    setStorageStatus('', '');
    const nameValue = String(name);
    try {
        await JSONRPC.SubscriptionManager.removeLocalResourceFile(nameValue, selectedRepository);
        setStorageStatus('Ресурс удалён.', 'success');
        renderUpdatingPlaceholder();
        await delay(REFRESH_DELAY_MS);
        await refreshResourceList();
        setTimeout(() => setStorageStatus('', ''), 3000);
    } catch (error) {
        console.error('Ошибка удаления ресурса:', error);
        setStorageStatus('Не удалось удалить ресурс.', 'error');
    }
}

async function refreshResourceList() {
    renderLoadingList();
    resourcesRequestId += 1;
    const requestId = resourcesRequestId;
    await loadAvailableResources(requestId);
}

function attachEventHandlers() {
    $(SELECTORS.storageSelect).on('change', async function () {
        selectedRepository = $(this).val() || '';
        if (!selectedRepository) {
            renderResourceList();
            $(SELECTORS.createButton).prop('disabled', true);
            return;
        }
        $(SELECTORS.createButton).prop('disabled', false);
        await refreshResourceList();
    });

    $(SELECTORS.createButton).on('click', function () {
        if (!selectedRepository) {
            setStorageStatus('Выберите хранилище.', 'error');
            return;
        }
        openModal('create');
    });

    $(SELECTORS.listContainer).on('click', '.local-storage-edit', function () {
        const name = $(this).data('name');
        if (!name) {
            return;
        }
        openModal('edit', name);
    });

    $(SELECTORS.listContainer).on('click', '.local-storage-delete', function () {
        const name = $(this).data('name');
        if (!name) {
            return;
        }
        handleDeleteResource(name);
    });

    $(SELECTORS.modalForm).on('submit', handleModalSubmit);

    $(SELECTORS.modalCancelButton).on('click', function (event) {
        event.preventDefault();
        closeModal();
    });

    $(SELECTORS.modalOverlay).on('click', function (event) {
        if (event.target === this) {
            closeModal();
        }
    });
}

function detachEventHandlers() {
    $(SELECTORS.storageSelect).off('change');
    $(SELECTORS.createButton).off('click');
    $(SELECTORS.listContainer).off('click');
    $(SELECTORS.modalForm).off('submit');
    $(SELECTORS.modalCancelButton).off('click');
    $(SELECTORS.modalOverlay).off('click');
}

function resetState() {
    repositories = [];
    availableResources = {};
    selectedRepository = '';
    currentModalMode = 'create';
    currentModalResourceName = '';
    resourcesRequestId = 0;
}

export const LocalStoragesPage = {
    render: () => `
        <div>
            <h1 class="page-title">Локальные хранилища</h1>
            <div style="display: flex; flex-direction: column; gap: 20px;">
                <div class="card" style="padding: 20px; max-width: 480px;">
                    <div class="form-group" style="margin-bottom: 0;">
                        <label for="${FIELD_IDS.storageSelect}">Репозиторий</label>
                        <select id="${FIELD_IDS.storageSelect}" class="form-control" disabled>
                            <option>Загрузка...</option>
                        </select>
                    </div>
                    <div id="${FIELD_IDS.storageStatus}" class="error-message" style="display: none; margin-top: 16px;"></div>
                </div>
                <div style="display: flex; justify-content: flex-end;">
                    <button type="button" id="${FIELD_IDS.createButton}" class="btn-primary" style="width: auto; padding: 10px 18px;" disabled>Создать</button>
                </div>
                <div id="${FIELD_IDS.listContainer}" class="card" style="padding: 20px;">
                    <p>Загрузка содержимого...</p>
                </div>
            </div>
            <div id="${FIELD_IDS.modalOverlay}" style="display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.6); z-index: 999; align-items: center; justify-content: center;">
                <div class="card" style="max-width: 640px; width: 90%; padding: 24px; position: relative;">
                    <form id="${FIELD_IDS.modalForm}" style="display: flex; flex-direction: column; gap: 16px;">
                        <h2 id="${FIELD_IDS.modalTitle}" style="margin: 0 0 10px 0;">Создание ресурса</h2>
                        <div class="form-group" style="margin-bottom: 0;">
                            <label for="${FIELD_IDS.nameInput}">Имя</label>
                            <input type="text" id="${FIELD_IDS.nameInput}" class="form-control" placeholder="example-resource">
                        </div>
                        <div class="form-group" style="margin-bottom: 0;">
                            <label for="${FIELD_IDS.descriptionInput}">Описание</label>
                            <textarea id="${FIELD_IDS.descriptionInput}" class="form-control" rows="3" placeholder="Описание ресурса"></textarea>
                        </div>
                        <div class="form-group" style="margin-bottom: 0;">
                            <label for="${FIELD_IDS.domainsInput}">Домены (каждый с новой строки)</label>
                            <textarea id="${FIELD_IDS.domainsInput}" class="form-control" rows="4" placeholder="example.com"></textarea>
                        </div>
                        <div class="form-group" style="margin-bottom: 0;">
                            <label for="${FIELD_IDS.asnInput}">ASN (каждый с новой строки)</label>
                            <textarea id="${FIELD_IDS.asnInput}" class="form-control" rows="3" placeholder="12345"></textarea>
                        </div>
                        <div class="form-group" style="margin-bottom: 0;">
                            <label for="${FIELD_IDS.subnetsInput}">Подсети (каждая с новой строки)</label>
                            <textarea id="${FIELD_IDS.subnetsInput}" class="form-control" rows="4" placeholder="192.0.2.0/24"></textarea>
                        </div>
                        <div class="form-group-checkbox" style="margin-bottom: 0;">
                            <label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
                                <input type="checkbox" id="${FIELD_IDS.resolveDomainsCheckbox}">
                                Автоматически получать IP адреса доменов
                            </label>
                        </div>
                        <div id="${FIELD_IDS.modalStatus}" class="error-message" style="display: none;"></div>
                        <div style="display: flex; gap: 12px; justify-content: flex-end; margin-top: 8px;">
                            <button type="button" id="${FIELD_IDS.modalCancelButton}" class="btn-secondary" style="padding: 10px 18px;">Отмена</button>
                            <button type="submit" id="${FIELD_IDS.modalSaveButton}" class="btn-primary" style="width: auto; padding: 10px 18px;">Сохранить</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    `,
    mount: async () => {
        attachEventHandlers();
        await loadRepositories();
        if (repositories.length && !selectedRepository) {
            selectedRepository = repositories[0];
            renderStorageOptions();
        }
        await refreshResourceList();
    },
    unmount: () => {
        detachEventHandlers();
        resetState();
    }
};
