package ru.kayashov.bar.bot.domain.keyboards.inline;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboard;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboardButton;

import java.util.ArrayList;
import java.util.List;

/**
 * Класс методов для создания инлайн клавиатур
 */
@Component
@RequiredArgsConstructor
public class InlineKeyboardMarker {

    /**
     * Преобразование списка кнопок в блок основных кнопок
     *
     * @param sizeRow                 опциональный размер строки
     * @param abstractKeyboardButtons список кнопок для блока
     * @return блок основных кнопок
     */
    public List<List<AbstractKeyboardButton>> getMainButtons(Integer sizeRow, List<AbstractKeyboardButton> abstractKeyboardButtons) {
//        int rowSize = PaginationUtil.getRowSize(sizeRow);
        int rowSize = sizeRow;
        int rowCountInPage = getRowCount(abstractKeyboardButtons.size(), rowSize);
        List<List<AbstractKeyboardButton>> buttons = new ArrayList<>();

        for (int row = 0; row < rowCountInPage; row++) {
            List<AbstractKeyboardButton> rowButtons = new ArrayList<>(rowSize);
            for (int i = 0; i < rowSize; i++) {
                int index = (row * rowSize) + i;
                if (index >= abstractKeyboardButtons.size()) {
                    break;
                }
                rowButtons.add(abstractKeyboardButtons.get(index));
            }
            buttons.add(rowButtons);
        }

        return buttons;
    }


    /**
     * Запрос количества строк для основных кнопок
     *
     * @param elementsOnPage элементов на странице или общее количество
     * @param rowSize        количество элементов в строке
     * @return число строк основных кнопок
     */
    private int getRowCount(int elementsOnPage, int rowSize) {
        return elementsOnPage / rowSize + (elementsOnPage % rowSize == 0 ? 0 : 1);
    }

    /**
     * Метод создания кнопок пагинации
     *
     * @return ряд кнопок для пагинации
     */
    public List<AbstractKeyboardButton> getPaginationButtons(int index, int total) {
        List<AbstractKeyboardButton> buttons = new ArrayList<>();

        String pageName = "⏪";
        String callback = index != 0 ? "Cocktail:get:" + (index - 1) : "null";
        buttons.add(getButtonForPage(callback, pageName));

        buttons.add(AbstractKeyboardButton.builder().text(index + 1 + "/" + total).callbackData("null").build());

        pageName = "⏩";
        callback = index < total - 1 ? "Cocktail:get:" + (index + 1) : "null";
        buttons.add(getButtonForPage(callback, pageName));

        return buttons;
    }

    /**
     * Метод создания кнопки
     *
     * @param callBack данные, возвращаемые на сервер
     * @param text     текст, видимый пользователю
     * @return кнопка для вставки в текст
     */
    public AbstractKeyboardButton getButtonForPage(String callBack, String text) {
        return AbstractKeyboardButton.builder()
                .text(text)
                .callbackData(callBack)
                .build();
    }

    public static class builder {
        private final List<List<AbstractKeyboardButton>> buttons = new ArrayList<>();
        private List<List<AbstractKeyboardButton>> mainButtons;
        private List<AbstractKeyboardButton> pagination;
        private List<AbstractKeyboardButton> back;
        private List<AbstractKeyboardButton> hideButton;
        private List<AbstractKeyboardButton> stop;

        public builder() {
        }

        public builder buttons(List<List<AbstractKeyboardButton>> buttons) {
            this.mainButtons = buttons;
            return this;
        }

        public builder pagination(List<AbstractKeyboardButton> buttons) {
            this.pagination = buttons;
            return this;
        }

        public builder backButton(AbstractKeyboardButton button) {
            if (button != null)
                this.back = List.of(button);
            return this;
        }

        public builder hidden(boolean isActive) {
            if (isActive) {
                AbstractKeyboardButton button = AbstractKeyboardButton.builder()
                        .text("Скрыть")
                        .callbackData("hide:")
                        .build();
                this.hideButton = List.of(button);
            }
            return this;
        }

        public builder stopList(boolean isActive, Long cocktailId) {
            if (isActive) {
                AbstractKeyboardButton button = AbstractKeyboardButton.builder()
                        .text("Стоп-лист")
                        .callbackData("Cocktail:stop:" + cocktailId)
                        .build();
                this.stop = List.of(button);
            }
            return this;
        }

        public AbstractKeyboard build() {
            if (mainButtons != null)
                buttons.addAll(mainButtons);
            if (pagination != null)
                buttons.add(pagination);
            if (back != null)
                buttons.add(back);
            if (hideButton != null)
                buttons.add(hideButton);
            if (stop != null)
                buttons.add(stop);

            return AbstractKeyboard.builder().keyboard(buttons).build();
        }
    }
}
