/*
 *   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.features.script.lua.libs;

import de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin;
import de.steamwar.linkage.Linked;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.VarArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;

@Linked
public class PlayerLib implements LuaLib {

    public String name() {
        return "player";
    }

    public LuaTable get(Player player) {
        LuaTable table = new LuaTable();
        table.set("name", getter(player::getName));
        table.set("chat", new Print(player));
        table.set("actionbar", new SendActionbar(player));

        table.set("pos", getter(() -> {
            return SteamWarLuaPlugin.pos(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ());
        }));
        table.set("blockPos", getter(() -> {
            return SteamWarLuaPlugin.pos(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ());
        }));
        table.set("x", getterAndSetter("x", () -> player.getLocation().getX(), x -> {
            Location location = player.getLocation();
            location.setX(x);
            player.teleport(location);
        }));
        table.set("y", getterAndSetter("y", () -> player.getLocation().getY(), y -> {
            Location location = player.getLocation();
            location.setY(y);
            player.teleport(location);
        }));
        table.set("z", getterAndSetter("z", () -> player.getLocation().getZ(), z -> {
            Location location = player.getLocation();
            location.setZ(z);
            player.teleport(location);
        }));
        table.set("yaw", getterAndSetter("yaw", () -> player.getLocation().getYaw(), yaw -> {
            Location location = player.getLocation();
            location.setYaw(yaw);
            player.teleport(location);
        }));
        table.set("pitch", getterAndSetter("pitch", () -> player.getLocation().getPitch(), pitch -> {
            Location location = player.getLocation();
            location.setPitch(pitch);
            player.teleport(location);
        }));

        table.set("sneaking", getter(player::isSneaking));
        table.set("sprinting", getter(player::isSprinting));
        table.set("slot", getterAndSetter("slot", () -> player.getInventory().getHeldItemSlot(), player.getInventory()::setHeldItemSlot));
        table.set("item", getter(() -> player.getInventory().getItemInMainHand().getType().name()));
        table.set("offHandItem", getter(() -> player.getInventory().getItemInOffHand().getType().name()));
        table.set("closeInventory", new ZeroArgFunction() {
            @Override
            public LuaValue call() {
                player.closeInventory();
                return LuaValue.NIL;
            }
        });
        return table;
    }

    private class Print extends VarArgFunction {
        private final Player player;

        public Print(Player player) {
            this.player = player;
        }

        @Override
        public Varargs invoke(Varargs args) {
            player.sendMessage(ChatColor.translateAlternateColorCodes('&', varArgsToString(args)));
            return LuaValue.NIL;
        }
    }

    private class SendActionbar extends VarArgFunction {
        private final Player player;

        public SendActionbar(Player player) {
            this.player = player;
        }

        @Override
        public Varargs invoke(Varargs args) {
            player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(ChatColor.translateAlternateColorCodes('&', varArgsToString(args))));
            return LuaValue.NIL;
        }
    }
}
