const host = 'https://hvatilo.ru';
// const host = 'https://local.hvatilo.ru:8055';

// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
// as much as it can, without ever going more than once per `wait` duration;
// but if you'd like to disable the execution on the leading edge, pass
// `{leading: false}`. To disable execution on the trailing edge, ditto.
function throttle(func, wait, options) {
    var context, args, result;
    var timeout = null;
    var previous = 0;
    if (!options) options = {};
    var later = function() {
        previous = options.leading === false ? 0 : Date.now();
        timeout = null;
        result = func.apply(context, args);
        if (!timeout) context = args = null;
    };
    return function() {
        var now = Date.now();
        if (!previous && options.leading === false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
        return result;
    };
}

function refreshToken() {
    return fetch(host + '/api/guest/refresh_cookie', {method: 'POST', credentials: 'include'}).then(response => {
        return response.json();
    })
}
function initToken() {
    return fetch(host + '/api/guest/init_cookie?utm_source=hvatilo_promo', {method: 'POST', credentials: 'include'}).then(response => {
        return response.json();
    });
}

const requestWithRefresh = async function(url, options) {
    return fetch(url, {...options, credentials: 'include'})
        .then(async response => response.json())
        .then(async data => {
            if (data.error_message === 'need_refresh') {
                return refreshToken()
                    .then((r) => {
                        console.log('url', url);
                        return fetch(url, {...options, credentials: 'include'}).then(response => response.json());
                    });
            }

            return data;
        })
}

const replaceProduct = (async function(product_name) {
    return requestWithRefresh(host + '/api/promo/replace_item', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({product_name})
    })
        .then(async () => {
            updateCart();
        })
})
const deleteProduct = (async function(product_name) {
    return requestWithRefresh(host + '/api/promo/delete_item', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({product_name})
    })
})
const updateCart = throttle(async function() {
    return requestWithRefresh(host + '/api/promo/get_updates', {headers: {
            'Content-Type': 'application/json'
        }}).then(d => {
        if (d.status !== 'complete') {
            initialData_g.excess = d.payload.excess;
            initialData_g.precision = d.payload.precision;
            if (d.status === 'clear') {
                allProducts = [];
                visibleProducts = [];

                renderProducts();

                allProducts = d.payload.chunk;
                visibleProducts = d.payload.chunk;
            }
            if (d.status === 'data') {
                d.payload.chunk.forEach(addedProduct => {
                    let idx = allProducts.findIndex(p => p.name === addedProduct.name)
                    if (idx === -1) {
                        allProducts.push({...addedProduct, image: addedProduct.image?.replace('{SIZE}', '65,fit')});
                        if (visibleProducts.length === allProducts.length - 1) {
                            visibleProducts = allProducts;
                        }
                    } else {
                        allProducts[idx].n += addedProduct.n;
                        if (idx < visibleProducts.length) {
                            visibleProducts[idx] = allProducts[idx];
                        }
                    }
                })
            }
            console.log(allProducts.length, visibleProducts.length);
            if (d.status !== 'waiting') {
                renderProducts();
            }
            updateCart();
        }
    })
        .catch(() => {
            updateCart();
        })
}, 3000);

const setOption = (key, value) => {
    return requestWithRefresh(host + '/api/promo/set_option', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({[key]: value})
    })
        .then(async d => {
            wholeRender(await loadInitData());
            updateCart();
        })
}

const loadInitData = (async function() {
    return fetch(host + '/api/promo/get_initial_data', {credentials: 'include'})
        .then(async response => {
            const data = await response.json();

            if (response.status === 401 && data.error_message !== 'need_refresh') {
                return await initToken()
                    .then((r) => {
                        return fetch(host + '/api/promo/get_initial_data', {credentials: 'include'})
                            .then(r => r.json());
                    });
            }
            if (response.status === 403 || data.error_message === 'need_refresh') {
                return await refreshToken()
                    .then((r) => {
                        return fetch(host + '/api/promo/get_initial_data', {credentials: 'include'})
                            .then(r => r.json());
                    });
            }
            return data;
        })
        .then((data) => {
            updateCart();
            return data;
        })
        .catch(error => {
            console.log(error);
            return Promise.reject();
        })
});

function debounce(func, delay) {
    let timeoutId;

    return function (...args) {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => {
            func.apply(this, args);
        }, delay);
    };
}

let allProducts;
let visibleProducts;

function renderProduct(item, index) {
    const li = document.createElement('li');
    li.className = 'cart-item';
    const amount = item.unit === 'g' ? item.n + ' г' : item.n + ' шт';
    li.innerHTML = `
                <div class="item-image"><img src="${item.image}" alt=""></div>
                <div class="item-details">
                    <div class="item-name">${item.name}</div>
                    <div class="item-price">${amount} &times; ${Math.round(item.price * 100) / 100} ₽</div>
                </div>
                <div class="menu-btn-wrapper">
                    <button class="menu-btn" data-index="${index}">&#8942;</button>
                    <div class="menu-dropdown">
                        <ul>
                            <li class="menu-replace">Заменить</li>
                            <li class="menu-remove">Удалить</li>
                        </ul>
                    </div>
                </div>
            `;
    return li;
}


let cartList;
let scrollWrapper;
let showMoreBtn;
let remainingSpan;
let initialData_g;

function renderProducts() {
    cartList.innerHTML = '';
    visibleProducts.forEach((item, index) => {
        cartList.appendChild(renderProduct(item, index));
    });

    const remaining = allProducts.length - visibleProducts.length;
    if(remaining > 0) {
        showMoreBtn.classList.remove('hidden');
        remainingSpan.textContent = remaining;
    } else {
        showMoreBtn.classList.add('hidden');
    }
    updateSummaryCount();
    calculateListHeight();
}
function updateSummaryCount() {
    const totalPrice = new Intl.NumberFormat("ru-RU", { style: "currency", currency: "RUB" }).format(
        Math.round(allProducts.reduce((sum, item) => sum + item.total_price, 0) * 100) / 100,
    );
    const x = Math.round(initialData_g.days * initialData_g.excess + initialData_g.days);
    document.getElementById('summary-details').innerHTML = `${allProducts.length} ${declension(allProducts.length, ['товар', 'товара', 'товаров'])} &bull; ${totalPrice} ~ с запасами на ${x} ${declension(x, ['день', 'дня', 'дней'])}, точность ${Math.round(initialData_g.precision * 100)/100}%`;
    document.getElementById('total-price').innerHTML = `${totalPrice}`;
    if(allProducts.length === 0) {
        document.getElementById('summary-details').innerHTML = `0 товаров &bull; ${totalPrice} ₽`;
    }
}
function calculateListHeight() {
    const leftCol = document.querySelector('.col-left');
    if (!leftCol) return;
    const title = leftCol.querySelector('h1');
    const subtitle = leftCol.querySelector('.subtitle');
    const summary = leftCol.querySelector('.cart-summary');
    const footer = leftCol.querySelector('.cart-footer');
    const showMore = leftCol.querySelector('.show-more');

    let fixedHeight = 0;
    if(title) fixedHeight += title.offsetHeight + 6;
    if(subtitle) fixedHeight += subtitle.offsetHeight + 28;
    if(summary) fixedHeight += summary.offsetHeight + 24;
    if(showMore && !showMore.classList.contains('hidden')) fixedHeight += showMore.offsetHeight;
    if(footer) fixedHeight += footer.offsetHeight + 20;

    const paddingY = 60;
    const rect = leftCol.getBoundingClientRect();
    const availHeight = window.innerHeight - rect.top - paddingY - 20;

    const listHeight = availHeight - fixedHeight;
    if(listHeight > 100) {
        scrollWrapper.style.maxHeight = `${listHeight}px`;
        scrollWrapper.style.overflowY = 'auto';
    }
}
function declension(number, titles) {
    const cases = [2, 0, 1, 1, 1, 2];
    const idx = (number % 100 > 4 && number % 100 < 20)
        ? 2
        : cases[Math.min(number % 10, 5)];
    return titles[idx];
}

function wholeRender(initialData) {
    initialData_g = initialData;
    document.querySelector('.summary-days').textContent = `${initialData_g.days} ${declension(initialData_g.days, ['день', 'дня', 'дней'])}`;
    allProducts = (Array.isArray(initialData_g.cart) ? initialData_g.cart : [] ?? []).flat().map(item => {
        return {...item, image: item.image?.replace('{SIZE}', '65,fit')}
    });
    visibleProducts = allProducts.slice(0, visibleProducts ? visibleProducts.length : 5);

    document.querySelectorAll('.days-options .day-btn').forEach(btn => {
        if (btn.innerText.trim() === `${initialData_g.days}`) {
            btn.classList.add('active');
        }
    });

    // Массив людей теперь содержит поля запрещенных и любимых продуктов
    console.log(initialData_g);
    let people = initialData_g.users;

    // --- 1. Рендеринг списка продуктов (Левая часть) ---
    cartList = document.getElementById('cart-list');
    scrollWrapper = document.getElementById('scroll-wrapper');
    showMoreBtn = document.getElementById('show-more-btn');
    remainingSpan = document.getElementById('remaining-count');

    renderProducts();

    // --- 2. Меню (Заменить и Удалить) ---
    document.addEventListener('click', function(e) {
        const menuBtn = e.target.closest('.menu-btn');
        const menuDropdown = e.target.closest('.menu-dropdown');
        const isReplace = e.target.closest('.menu-replace');
        const isRemove = e.target.closest('.menu-remove');
        const isClearAll = e.target.closest('.reorder-btn');

        if(menuBtn) {
            const dropdown = menuBtn.nextElementSibling;
            const isOpen = dropdown.classList.contains('active');
            document.querySelectorAll('.menu-dropdown.active').forEach(el => el.classList.remove('active'));
            if(!isOpen) {
                dropdown.classList.add('active');
            }
            e.stopPropagation();
        } else if(!menuDropdown) {
            document.querySelectorAll('.menu-dropdown.active').forEach(el => el.classList.remove('active'));
        }

        if(isReplace) {
            const wrapper = isReplace.closest('.menu-btn-wrapper');
            const li = wrapper.closest('.cart-item');
            li.classList.add('replacing');
            const index = Array.from(cartList.children).indexOf(li);
            replaceProduct(allProducts[index].name).then(() => {
                li.remove();
                document.querySelectorAll('.menu-dropdown.active').forEach(el => el.classList.remove('active'));
                visibleProducts.splice(index, 1);
                allProducts.splice(index, 1);

                if(visibleProducts.length < allProducts.length) {
                    visibleProducts.push(allProducts[visibleProducts.length]);
                }
                renderProducts();
                calculateListHeight();
            });
        }

        if(isRemove) {
            const wrapper = isRemove.closest('.menu-btn-wrapper');
            const li = wrapper.closest('.cart-item');
            li.classList.add('replacing');
            const index = Array.from(cartList.children).indexOf(li);
            deleteProduct(allProducts[index].name).then(() => {
                li.remove();
                document.querySelectorAll('.menu-dropdown.active').forEach(el => el.classList.remove('active'));
                visibleProducts.splice(index, 1);
                allProducts.splice(index, 1);

                if(visibleProducts.length < allProducts.length) {
                    visibleProducts.push(allProducts[visibleProducts.length]);
                }
                renderProducts();
                calculateListHeight();
            })
        }

        if (isClearAll) {
            requestWithRefresh(host + '/api/guest/clear_cookie', {method: 'POST'})
                .then(r => {document.location.reload()});
        }
    });

    showMoreBtn.addEventListener('click', () => {
        while(visibleProducts.length < allProducts.length) {
            visibleProducts.push(allProducts[visibleProducts.length]);
        }
        renderProducts();
        scrollWrapper.style.maxHeight = '500px';
        calculateListHeight();
    });

    // --- 3. Фиксированная высота ---
    window.addEventListener('resize', calculateListHeight);
    calculateListHeight();

    // --- 4. Аккордеон (активна только одна вкладка) ---
    document.querySelectorAll('.accordion-header').forEach(header => {
        header.addEventListener('click', function() {
            const item = this.closest('.accordion-item');
            const isOpen = item.classList.contains('open');
            document.querySelectorAll('.accordion-item').forEach(el => el.classList.remove('open'));
            if(!isOpen) {
                item.classList.add('open');
            }
        });
    });

    // --- 5. Дни ---
    document.querySelectorAll('.day-btn').forEach(btn => {
        btn.addEventListener('click', function() {
            const parent = this.closest('.days-options');
            parent.querySelectorAll('.day-btn').forEach(b => b.classList.remove('active'));
            this.classList.add('active');
            setOption('days', this.dataset.days);
            document.querySelector('.summary-days').textContent = `${this.dataset.days} ${declension(this.dataset.days, ['день', 'дня', 'дней'])}`;
        });
    });

    // --- 6. Семья с возможностью редактирования ---
    const familyList = document.getElementById('family-list');
    const familyDesc = document.getElementById('family-desc');
    let editingIndex = null;

    function renderPeople() {
        familyList.innerHTML = '';
        people.forEach((person, index) => {
            const avatar = '🥦';
            const div = document.createElement('div');
            div.className = 'family-member';
            div.dataset.index = index;
            div.innerHTML = `
                    <div class="avatar">${avatar}</div>
                    <div class="info">
                        <div class="name">${person.name}</div>
                        <div class="age">${person.age} лет</div>
                    </div>
                    <div class="delete-member" data-index="${index}">×</div>
                `;
            familyList.appendChild(div);
        });

        const count = people.length;
        familyDesc.textContent = `${count} ${declension(count, ['человек', 'человека', 'человек'])}`;
        if(count === 0) familyDesc.textContent = 'Не указаны';

        document.querySelectorAll('.delete-member').forEach(btn => {
            btn.addEventListener('click', function(e) {
                e.stopPropagation();
                const idx = parseInt(this.dataset.index);
                people.splice(idx, 1);
                renderPeople();
                setOption('users', people);
            });
        });
    }
    renderPeople();

    familyList.addEventListener('click', function(e) {
        const member = e.target.closest('.family-member');
        if (!member) return;
        if (e.target.closest('.delete-member')) return;
        const idx = parseInt(member.dataset.index);
        openEditModal(idx);
    });

    // --- 7. Попап (Добавление и Редактирование) + Логика Тегов ---
    const modal = document.getElementById('personModal');
    const addBtn = document.getElementById('addMemberBtn');
    const closeBtn = document.getElementById('closeModalBtn');
    const saveBtn = document.getElementById('savePersonBtn');
    const modalTitle = document.getElementById('modalTitle');
    const genderBtns = document.querySelectorAll('.gender-btn');

    const availableTags = initialData_g.available_groups;

    function openEditModal(index = null) {
        editingIndex = index;

        // Очистка тегов внутри попапа
        document.querySelectorAll('#personModal .tags-wrap').forEach(el => el.innerHTML = '');

        if (editingIndex !== null) {
            modalTitle.textContent = 'Редактировать человека';
            const p = people[editingIndex];
            document.getElementById('inputName').value = p.name;
            document.getElementById('inputAge').value = p.age;
            document.getElementById('inputWeight').value = p.weight;
            document.getElementById('inputHeight').value = p.height;
            genderBtns.forEach(b => {
                b.classList.toggle('active', b.dataset.gender === p.gender);
            });

            // Рендерим сохраненные теги
            if(p.avoid) p.avoid.forEach(tag => addTagToModal(tag, 'avoid', false));
            if(p.favorite) p.favorite.forEach(tag => addTagToModal(tag, 'favorite', false));
        } else {
            modalTitle.textContent = 'Добавить человека';
            document.getElementById('inputName').value = '';
            document.getElementById('inputAge').value = '';
            document.getElementById('inputWeight').value = '';
            document.getElementById('inputHeight').value = '';
            genderBtns.forEach(b => b.classList.remove('active'));
            document.querySelector('.gender-btn[data-gender="m"]').classList.add('active');
        }
        modal.style.display = 'flex';
        calculateListHeight();
    }

    addBtn.addEventListener('click', () => openEditModal(null));

    function closeModal() { modal.style.display = 'none'; }
    closeBtn.addEventListener('click', closeModal);
    modal.addEventListener('click', function(e) {
        if (e.target === this) closeModal();
    });

    genderBtns.forEach(btn => {
        btn.addEventListener('click', function() {
            genderBtns.forEach(b => b.classList.remove('active'));
            this.classList.add('active');
        });
    });

    // Логика добавления тега в попап
    function addTagToModal(text, type, saveToPeople = true) {
        const tagsWrap = document.querySelector(`#personModal .tags-wrap[data-target="${type}"]`);

        // Проверка дубликата в своей группе
        const existingInGroup = tagsWrap.querySelectorAll('.tag');
        for(let t of existingInGroup) {
            if(t.textContent.trim().replace('×','').trim() === text) return;
        }

        // Взаимоисключение: если тег есть в противоположной группе - удалить его оттуда
        const oppositeType = type === 'avoid' ? 'favorite' : 'avoid';
        const oppositeWrap = document.querySelector(`#personModal .tags-wrap[data-target="${oppositeType}"]`);
        const oppositeTags = oppositeWrap.querySelectorAll('.tag');
        for(let t of oppositeTags) {
            if(t.textContent.trim().replace('×','').trim() === text) {
                t.remove();
                break;
            }
        }

        const tag = document.createElement('div');
        tag.className = `tag ${type === 'avoid' ? 'tag-red' : 'tag-green'}`;
        tag.innerHTML = `${text} <span class="tag-close">×</span>`;
        tag.querySelector('.tag-close').addEventListener('click', function() {
            tag.remove();
        });
        tagsWrap.appendChild(tag);
    }

    // Автокомплит для полей в попапе
    document.querySelectorAll('#personModal .pref-input').forEach(input => {
        const type = input.dataset.type;
        const listEl = document.querySelector(`#personModal .autocomplete-list[data-type="${type}"]`);
        const tagsWrap = document.querySelector(`#personModal .tags-wrap[data-target="${type}"]`);

        input.addEventListener('input', function() {
            const val = this.value.toLowerCase();
            listEl.innerHTML = '';

            // Ищем все уже выбранные теги в обеих группах внутри попапа
            const allSelectedTags = new Set();
            document.querySelectorAll('#personModal .tags-wrap .tag').forEach(tagEl => {
                const tagText = tagEl.textContent.trim().replace('×', '').trim();
                if(tagText) allSelectedTags.add(tagText);
            });

            if(val.length > 0) {
                const matches = availableTags.filter(tag =>
                    tag.toLowerCase().includes(val) && !allSelectedTags.has(tag)
                );

                if(matches.length > 0) {
                    listEl.classList.add('active');
                    matches.forEach(match => {
                        const div = document.createElement('div');
                        div.textContent = match;
                        div.addEventListener('click', function() {
                            addTagToModal(match, type);
                            input.value = '';
                            listEl.classList.remove('active');
                        });
                        listEl.appendChild(div);
                    });
                } else {
                    listEl.classList.remove('active');
                }
            } else {
                listEl.classList.remove('active');
            }
        });

        document.addEventListener('click', function(e) {
            if(!input.contains(e.target) && !listEl.contains(e.target)) {
                listEl.classList.remove('active');
            }
        });
    });

    // Сохранение пользователя (сбор тегов из DOM попапа)
    saveBtn.addEventListener('click', () => {
        const name = document.getElementById('inputName').value.trim();
        const age = document.getElementById('inputAge').value.trim();
        const weight = document.getElementById('inputWeight').value.trim();
        const height = document.getElementById('inputHeight').value.trim();
        const gender = document.querySelector('.gender-btn.active').dataset.gender;

        if(!name) { alert('Пожалуйста, введите имя.'); return; }
        if(!age || parseInt(age) < 7) { alert('Возраст должен быть от 7 лет.'); return; }

        // Сбор тегов
        const forbTags = [];
        document.querySelector('#personModal .tags-wrap[data-target="avoid"]').querySelectorAll('.tag').forEach(el => {
            forbTags.push(el.textContent.trim().replace('×', '').trim());
        });
        const favTags = [];
        document.querySelector('#personModal .tags-wrap[data-target="favorite"]').querySelectorAll('.tag').forEach(el => {
            favTags.push(el.textContent.trim().replace('×', '').trim());
        });

        const personData = { name, age, weight, height, gender, avoid: forbTags, favorite: favTags };
        if (editingIndex !== null) {
            people[editingIndex] = personData;
            editingIndex = null;
        } else {
            people.push(personData);
        }
        renderPeople();
        setOption('users', people);
        closeModal();
    });

    // --- 8. Блок: Категории ---
    const categories = initialData_g.available_groups;
    const initialSelected = initialData_g.initial_groups;
    let selectedCategories = [...initialSelected];
    let isCategoriesExpanded = false;
    const maxVisibleCategories = 9;
    const sendUpdatedCategories = debounce(async () => {
        return setOption('categories', selectedCategories);
    }, 1500);

    const categoriesGrid = document.getElementById('categories-grid');
    const toggleBtn = document.getElementById('expand-categories');

    function renderCategories() {
        categoriesGrid.innerHTML = '';
        const dataToShow = isCategoriesExpanded ? categories : categories.slice(0, maxVisibleCategories);

        dataToShow.forEach(cat => {
            const btn = document.createElement('button');
            btn.className = `category-btn ${selectedCategories.includes(cat) ? 'active' : 'inactive'}`;
            btn.textContent = cat;
            btn.dataset.category = cat;
            btn.addEventListener('click', function() {
                const catName = this.dataset.category;
                if (selectedCategories.includes(catName)) {
                    selectedCategories = selectedCategories.filter(c => c !== catName);
                } else {
                    selectedCategories.push(catName);
                }
                renderCategories();
                sendUpdatedCategories();
            });
            categoriesGrid.appendChild(btn);
        });

        if (isCategoriesExpanded) {
            toggleBtn.classList.remove('collapsed');
        } else {
            toggleBtn.classList.add('collapsed');
        }
    }

    toggleBtn.addEventListener('click', function() {
        isCategoriesExpanded = !isCategoriesExpanded;
        renderCategories();
    });
    renderCategories();
}
document.addEventListener('DOMContentLoaded', async () => {
    wholeRender(await loadInitData());
});
document.addEventListener('DOMContentLoaded', function() {
    const popup = document.getElementById('cookie-popup');
    const acceptBtn = document.getElementById('cookie-accept');

    // Проверяем, согласился ли пользователь ранее
    if (!localStorage.getItem('cookie_accepted')) {
        // Небольшая задержка для красоты появления
        setTimeout(() => {
            popup.classList.add('show');
        }, 500);
    }

    // Обработчик нажатия на кнопку "Хорошо"
    acceptBtn.addEventListener('click', function() {
        // Сохраняем согласие в браузер
        localStorage.setItem('cookie_accepted', 'true');

        // Запускаем анимацию исчезновения
        popup.classList.remove('show');
        popup.classList.add('hide');

        // Полностью удаляем из DOM после завершения анимации
        setTimeout(() => {
            popup.style.display = 'none';
        }, 400);
    });
});