/*
 *   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;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.TwoArgFunction;

import java.util.function.BiConsumer;
import java.util.function.Consumer;

@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class SteamWarGlobalLuaPlugin extends TwoArgFunction {
    private final BiConsumer<EventType, LuaFunction> eventConsumer;
    private final BiConsumer<String, LuaFunction> hotkeyConsumer;
    private final Consumer<CommandRegister> commandRegisterConsumer;

    @Override
    public LuaValue call(LuaValue modname, LuaValue env) {
        LuaValue types = tableOf();
        for (EventType value : EventType.values()) {
            types.set(value.name(), value.ordinal());
        }
        env.set("events", types);


        env.set("event", new On());
        env.set("command", new TwoArgFunction() {
            @Override
            public LuaValue call(LuaValue arg1, LuaValue arg2) {
                LuaString command = arg1.checkstring();
                LuaFunction function = arg2.checkfunction();

                commandRegisterConsumer.accept(new CommandRegister(command.tojstring().toLowerCase(), function));

                return NIL;
            }
        });
        env.set("hotkey", new TwoArgFunction() {
            @Override
            public LuaValue call(LuaValue arg1, LuaValue arg2) {
                LuaString key = arg1.checkstring();
                LuaFunction function = arg2.checkfunction();

                hotkeyConsumer.accept(key.tojstring().toLowerCase(), function);

                return null;
            }
        });
        return NIL;
    }

    class On extends TwoArgFunction {
        @Override
        public LuaValue call(LuaValue eventName, LuaValue function) {
            int ord = eventName.checkint();
            LuaFunction luaFunction = function.checkfunction();

            int nArgs = luaFunction.narg();
            if (nArgs != 1) {
                return LuaValue.valueOf("Expected 1 argument, got " + nArgs);
            }

            eventConsumer.accept(EventType.values()[ord], luaFunction);

            return LuaValue.NIL;
        }
    }

    public enum EventType {
        DoubleSwap,
        PlaceBlock,
        BreakBlock,
        RightClick,
        LeftClick,
        TNTSpawn,
        TNTExplode,
        TNTExplodeInBuild,
        SelfJoin,
        SelfLeave,
        DropItem,
        EntityDeath
    }
}
