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

import de.steamwar.sql.internal.Field;
import de.steamwar.sql.internal.SqlTypeMapper;
import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NonNull;

import java.sql.Timestamp;
import java.time.Instant;

@AllArgsConstructor
public class AuditLog {

    static {
        SqlTypeMapper.nameEnumMapper(AuditLog.Type.class);
    }

    public static final String SERVER_NAME_VELOCITY = "Velocity";

    private static final Table<AuditLog> table = new Table<>(AuditLog.class);

    private static final Statement create = table.insertFields(true, "time", "serverName", "serverOwner", "actor", "actionType", "actionText");

    @Getter
    @Field
    private final Timestamp time;

    @Getter
    @Field
    private final String serverName;

    @Field(nullable = true)
    private final int serverOwner;

    @Field
    private final int actor;

    @Getter
    @Field
    private final Type actionType;

    @Getter
    @Field
    private final String actionText;

    public enum Type {
        JOIN,
        LEAVE,
        COMMAND,
        SENSITIVE_COMMAND,

        CHAT,
        GUI_OPEN,
        GUI_CLOSE,
        GUI_CLICK,
    }

    private static void create(String serverName, SteamwarUser serverOwner, SteamwarUser actor, Type actionType, String text) {
        create.insertGetKey(Timestamp.from(Instant.now()), serverName, serverOwner, actor, actionType, text);
    }

    public static void createJoin(@NonNull String jointServerName, SteamwarUser serverOwner, @NonNull SteamwarUser joinedPlayer) {
        create(jointServerName, serverOwner, joinedPlayer, Type.JOIN, "");
    }

    public static void createLeave(@NonNull String leftServerName, SteamwarUser serverOwner, @NonNull SteamwarUser joinedPlayer) {
        create(leftServerName, serverOwner, joinedPlayer, Type.LEAVE, "");
    }

    public static void createCommand(@NonNull String serverName, SteamwarUser serverOwner, SteamwarUser player, @NonNull String command) {
        if (player == null) return;
        create(serverName, serverOwner, player, Type.COMMAND, command);
    }

    public static void createSensitiveCommand(@NonNull String serverName, SteamwarUser serverOwner, SteamwarUser player, @NonNull String command) {
        if (player == null) return;
        create(serverName, serverOwner, player, Type.SENSITIVE_COMMAND, command);
    }

    public static void createChat(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser chatter, @NonNull String chat) {
        create(serverName, serverOwner, chatter, Type.CHAT, chat);
    }

    public static void createGuiOpen(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser player, @NonNull String guiName) {
        create(serverName, serverOwner, player, Type.GUI_OPEN, guiName);
    }

    public static void createGuiClick(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser player, @NonNull String guiName, @NonNull String clickType, int slot, @NonNull String itemName) {
        create(serverName, serverOwner, player, Type.GUI_CLICK, "Gui: " + guiName + "\nSlot: " + slot + "\nClickType: " + clickType + "\nItemName: " + itemName);
    }

    public static void createGuiClose(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser player, @NonNull String guiName) {
        create(serverName, serverOwner, player, Type.GUI_CLOSE, guiName);
    }

    public SteamwarUser getServerOwner() {
        return SteamwarUser.get(serverOwner);
    }

    public SteamwarUser getActor() {
        return SteamwarUser.get(actor);
    }
}
