(function(window, document) {
    var state = {
        words: [],
        filtered: [],
        letter: 'all',
        page: 1,
        pageSize: 120
    };

    function endpoint() {
        return ROOT_URL + '/includes/dictionary/dictionary_actions.php';
    }

    function downloadUrl(action) {
        var tenant = typeof TENANT_URL !== 'undefined' ? TENANT_URL : '';
        window.location.href = endpoint() + '?action=' + encodeURIComponent(action) + '&tenant=' + encodeURIComponent(tenant);
    }

    function post(action, data) {
        data = data || {};
        data.action = action;
        data.tenant = typeof TENANT_URL !== 'undefined' ? TENANT_URL : '';

        return fetch(endpoint(), {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body: new URLSearchParams(data)
        }).then(function(response) {
            return response.json().then(function(payload) {
                return {
                    ok: response.ok,
                    payload: payload
                };
            });
        }).then(function(result) {
            if (!result.ok || result.payload.status !== 'success') {
                throw new Error(result.payload.message || 'Dictionary action failed');
            }
            return result.payload;
        });
    }

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

    function render() {
        var grid = document.getElementById('dictionaryGrid');
        var count = document.getElementById('dictionaryCount');
        var summary = document.getElementById('dictionarySummary');
        var pageStatus = document.getElementById('dictionaryPageStatus');
        var prev = document.getElementById('dictionaryPrev');
        var next = document.getElementById('dictionaryNext');
        var search = (document.getElementById('dictionarySearch').value || '').toLowerCase();

        state.filtered = state.words.filter(function(word) {
            var lower = word.toLowerCase();
            var letterMatches = state.letter === 'all' || lower.charAt(0) === state.letter;
            return letterMatches && (!search || lower.indexOf(search) !== -1);
        });

        var totalPages = Math.max(1, Math.ceil(state.filtered.length / state.pageSize));
        if (state.page > totalPages) {
            state.page = totalPages;
        }

        var start = (state.page - 1) * state.pageSize;
        var pageWords = state.filtered.slice(start, start + state.pageSize);

        count.textContent = state.words.length + ' ' + (state.words.length === 1 ? 'word' : 'words');
        summary.textContent = state.filtered.length + ' matching ' + (state.filtered.length === 1 ? 'word' : 'words') + ', showing ' + (pageWords.length ? (start + 1) + '-' + (start + pageWords.length) : '0') + '.';
        pageStatus.textContent = 'Page ' + state.page + ' of ' + totalPages;
        prev.disabled = state.page <= 1;
        next.disabled = state.page >= totalPages;

        renderAlpha();

        if (!pageWords.length) {
            grid.innerHTML = '<div class="dictionary-empty">No dictionary words found</div>';
            return;
        }

        grid.innerHTML = pageWords.map(function(word) {
            return '<div class="dictionary-chip">' +
                '<span class="dictionary-word" title="' + escapeHtml(word) + '">' + escapeHtml(word) + '</span>' +
                '<button type="button" class="btn btn-sm btn-outline-danger dictionary-delete" data-word="' + encodeURIComponent(word) + '" title="Remove word">' +
                '<i class="fad fa-trash"></i>' +
                '</button>' +
                '</div>';
        }).join('');
    }

    function renderAlpha() {
        var alpha = document.getElementById('dictionaryAlpha');
        var counts = {};
        state.words.forEach(function(word) {
            var letter = (word.charAt(0) || '').toLowerCase();
            if (/^[a-z]$/.test(letter)) {
                counts[letter] = (counts[letter] || 0) + 1;
            }
        });

        alpha.innerHTML = ['all'].concat('abcdefghijklmnopqrstuvwxyz'.split('')).map(function(letter) {
            var label = letter === 'all' ? 'All' : letter.toUpperCase();
            var active = state.letter === letter ? 'btn-primary' : 'btn-outline-secondary';
            var disabled = letter !== 'all' && !counts[letter] ? ' disabled' : '';
            return '<button type="button" class="btn btn-sm ' + active + ' dictionary-alpha-btn" data-letter="' + letter + '"' + disabled + '>' + label + '</button>';
        }).join('');
    }

    function loadWords() {
        post('list').then(function(payload) {
            state.words = payload.words || [];
            state.page = 1;
            render();
        }).catch(function(error) {
            showResponse('danger', error.message || 'Unable to load dictionary');
        });
    }

    function addWord() {
        var input = document.getElementById('dictionaryNewWord');
        var word = (input.value || '').trim();

        if (!word) {
            showResponse('warning', 'Enter a word to add');
            return;
        }

        post('add', {
            word: word
        }).then(function() {
            input.value = '';
            showResponse('success', 'Dictionary word added');
            loadWords();
        }).catch(function(error) {
            showResponse('danger', error.message || 'Unable to add dictionary word');
        });
    }

    function requestDelete(word) {
        var body = '<div class="text-center py-3">' +
            '<p class="mb-1">Remove this word from the custom dictionary?</p>' +
            '<h5 class="mb-0">' + escapeHtml(word) + '</h5>' +
            '</div>';

        loadModalContent(body, 'dictionaryConfirmBox', 'modal-md', 1099, 'true', 'Remove Dictionary Word', 'cancelConfirm', function() {
            post('delete', {
                word: word
            }).then(function() {
                killModal('dictionaryConfirmBox');
                showResponse('success', 'Dictionary word removed');
                loadWords();
            }).catch(function(error) {
                showResponse('danger', error.message || 'Unable to remove dictionary word');
            });
        });
    }

    function importModalHtml() {
        return '<div class="dictionary-import-modal">' +
            '<div class="mb-3">' +
            '<label class="form-label" for="dictionaryCsvFile">Dictionary CSV</label>' +
            '<input type="file" class="form-control" id="dictionaryCsvFile" accept=".csv,text/csv">' +
            '</div>' +
            '<div id="dictionaryImportResult"></div>' +
            '<div class="text-end mt-3">' +
            '<button type="button" class="btn btn-secondary me-2" onclick="killModal(\'dictionaryImportBox\')">Close</button>' +
            '<button type="button" class="btn btn-primary" id="dictionaryPreviewImportBtn">Check CSV</button>' +
            '</div>' +
            '</div>';
    }

    function renderImportResult(payload) {
        var target = document.getElementById('dictionaryImportResult');
        var newWords = payload.newWords || [];
        var collisions = payload.collisions || [];
        var invalid = payload.invalid || [];

        var list = function(title, words, tone) {
            if (!words.length) {
                return '';
            }
            return '<h6 class="mt-3">' + escapeHtml(title) + '</h6>' +
                '<div class="dictionary-import-list ' + tone + '">' +
                words.map(function(word) {
                    return '<div>' + escapeHtml(word) + '</div>';
                }).join('') +
                '</div>';
        };

        target.innerHTML = '<div class="dictionary-import-summary">' +
            '<div class="dictionary-import-stat"><strong>' + newWords.length + '</strong>new</div>' +
            '<div class="dictionary-import-stat"><strong>' + collisions.length + '</strong>already exist</div>' +
            '<div class="dictionary-import-stat"><strong>' + invalid.length + '</strong>invalid</div>' +
            '</div>' +
            list('New words to import', newWords, '') +
            list('Collisions already in dictionary', collisions, 'text-muted') +
            list('Invalid rows skipped', invalid, 'text-danger') +
            (newWords.length ? '<div class="text-end mt-3"><button type="button" class="btn btn-success" id="dictionaryCommitImportBtn">Import ' + newWords.length + ' new words</button></div>' : '');

        state.importWords = newWords;

        var commit = document.getElementById('dictionaryCommitImportBtn');
        if (commit) {
            commit.addEventListener('click', commitImport);
        }
    }

    function previewImport() {
        var input = document.getElementById('dictionaryCsvFile');
        if (!input || !input.files || !input.files.length) {
            showResponse('warning', 'Choose a CSV file first');
            return;
        }

        var data = new FormData();
        data.append('action', 'import_preview');
        data.append('tenant', typeof TENANT_URL !== 'undefined' ? TENANT_URL : '');
        data.append('dictionary_csv', input.files[0]);

        fetch(endpoint(), {
            method: 'POST',
            body: data
        }).then(function(response) {
            return response.json().then(function(payload) {
                return {
                    ok: response.ok,
                    payload: payload
                };
            });
        }).then(function(result) {
            if (!result.ok || result.payload.status !== 'success') {
                throw new Error(result.payload.message || 'Unable to preview import');
            }
            renderImportResult(result.payload);
        }).catch(function(error) {
            showResponse('danger', error.message || 'Unable to preview import');
        });
    }

    function commitImport() {
        post('import_commit', {
            words: JSON.stringify(state.importWords || [])
        }).then(function(payload) {
            showResponse('success', (payload.added || 0) + ' dictionary words imported');
            killModal('dictionaryImportBox');
            loadWords();
        }).catch(function(error) {
            showResponse('danger', error.message || 'Unable to import dictionary words');
        });
    }

    function openImportModal() {
        loadModalContent(importModalHtml(), 'dictionaryImportBox', 'modal-lg', 1099, 'true', 'Import Dictionary CSV', '');
        setTimeout(function() {
            var preview = document.getElementById('dictionaryPreviewImportBtn');
            if (preview) {
                preview.addEventListener('click', previewImport);
            }
        }, 100);
    }

    document.addEventListener('DOMContentLoaded', function() {
        var search = document.getElementById('dictionarySearch');
        var addBtn = document.getElementById('dictionaryAddBtn');
        var newWord = document.getElementById('dictionaryNewWord');
        var grid = document.getElementById('dictionaryGrid');
        var alpha = document.getElementById('dictionaryAlpha');
        var pageSize = document.getElementById('dictionaryPageSize');
        var prev = document.getElementById('dictionaryPrev');
        var next = document.getElementById('dictionaryNext');
        var templateBtn = document.getElementById('dictionaryTemplateBtn');
        var importBtn = document.getElementById('dictionaryImportBtn');
        var exportBtn = document.getElementById('dictionaryExportBtn');

        if (!search || !addBtn || !newWord || !grid || !alpha || !pageSize || !prev || !next || !templateBtn || !importBtn || !exportBtn) {
            return;
        }

        search.addEventListener('input', function() {
            state.page = 1;
            render();
        });
        addBtn.addEventListener('click', addWord);
        newWord.addEventListener('keydown', function(event) {
            if (event.key === 'Enter') {
                event.preventDefault();
                addWord();
            }
        });

        alpha.addEventListener('click', function(event) {
            var button = event.target.closest ? event.target.closest('.dictionary-alpha-btn') : null;
            if (!button || button.disabled) {
                return;
            }
            state.letter = button.getAttribute('data-letter') || 'all';
            state.page = 1;
            render();
        });

        pageSize.addEventListener('change', function() {
            state.pageSize = parseInt(pageSize.value, 10) || 120;
            state.page = 1;
            render();
        });

        prev.addEventListener('click', function() {
            if (state.page > 1) {
                state.page--;
                render();
            }
        });

        next.addEventListener('click', function() {
            state.page++;
            render();
        });

        templateBtn.addEventListener('click', function() {
            downloadUrl('template');
        });

        exportBtn.addEventListener('click', function() {
            downloadUrl('export');
        });

        importBtn.addEventListener('click', openImportModal);

        grid.addEventListener('click', function(event) {
            var button = event.target.closest ? event.target.closest('.dictionary-delete') : null;
            if (!button) {
                return;
            }
            requestDelete(decodeURIComponent(button.getAttribute('data-word') || ''));
        });

        loadWords();
    });
})(window, document);
