/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.bausystem.world;

import de.steamwar.bausystem.BauSystem;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class PredefinedBook {

    private static final FileConfiguration configuration;
    private static List<PredefinedBook> bookCache;

    static {
        configuration = YamlConfiguration.loadConfiguration(new File(BauSystem.getPlugin().getDataFolder(), "books.yml"));
    }

    public static List<PredefinedBook> getBooks() {
        if (bookCache != null)
            return bookCache;
        List<PredefinedBook> books = new ArrayList<>();
        for (String book : configuration.getKeys(false)) {
            ConfigurationSection section = Objects.requireNonNull(configuration.getConfigurationSection(book));
            books.add(new PredefinedBook(section));
        }
        bookCache = books;
        return books;
    }

    public static int getBookCount() {
        return configuration.getKeys(false).size();
    }

    private List<String> lines;
    private List<String> lore;
    private String author;
    private String name;
    private ItemStack finishedBook;

    PredefinedBook(ConfigurationSection section) {
        this.lines = section.getStringList("lines");
        this.lore = section.getStringList("lore");
        this.author = section.getString("author", "§8Steam§eWar");
        this.name = section.getName();
    }

    public ItemStack toItemStack() {
        if (finishedBook != null)
            return finishedBook;
        ItemStack book = new ItemStack(getBookMat());
        BookMeta meta = (BookMeta) book.getItemMeta();
        meta.setPages(getPages());
        meta.setDisplayName(name);
        meta.setTitle(name);
        meta.setAuthor(author);
        meta.setGeneration(BookMeta.Generation.ORIGINAL);
        meta.setLore(lore);
        book.setItemMeta(meta);
        finishedBook = book;
        return book;
    }

    public Material getBookMat() {
        return Material.WRITTEN_BOOK;
    }

    public List<String> getLines() {
        return lines;
    }

    public String getAuthor() {
        return author;
    }

    public String getName() {
        return name;
    }

    public List<String> getLore() {
        return lore;
    }

    private String[] getPages() {
        List<StringBuilder> pages = new ArrayList<>();
        pages.add(0, new StringBuilder());
        int charsPerLine = 19;
        int currentLine = 0;
        int currentpage = 0;
        boolean first = true;
        for (String line : lines) {
            int linesPlus = (int) Math.ceil((double) line.length() / charsPerLine);
            currentLine += linesPlus;
            if (currentLine >= 14 || line.equals("!")) {
                currentLine = linesPlus;
                currentpage++;
                if (currentpage > 50)
                    throw new IllegalStateException("Book " + name + " has more pages than 50");
                pages.add(currentpage, new StringBuilder());
                first = true;
                if (line.equals("!"))
                    continue;
            }
            if (!first) {
                pages.get(currentpage).append("\n");
            } else {
                first = false;
            }
            pages.get(currentpage).append(line);
        }

        String[] finalPages = new String[pages.size()];
        for (int i = 0; i < pages.size(); i++) {
            finalPages[i] = pages.get(i).toString();
        }
        return finalPages;
    }
}