package com.alttd.altitudeweb.setup;

import com.alttd.altitudeweb.database.Databases;
import com.alttd.altitudeweb.database.litebans.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;

import java.sql.SQLException;
import java.sql.Statement;

@Slf4j
public class InitializeLiteBans {

    protected static void init() {
        log.info("Initializing LiteBans");
        Connection.getConnection(Databases.LITE_BANS, (configuration) -> {
                    configuration.addMapper(RecentNamesMapper.class);
                    configuration.addMapper(NameHistoryMapper.class);
                    configuration.addMapper(UUIDHistoryMapper.class);
                    configuration.addMapper(HistoryCountMapper.class);
                    configuration.addMapper(IdHistoryMapper.class);
                    configuration.addMapper(EditHistoryMapper.class);
                }).join()
                .runQuery(sqlSession -> {
                    createAllPunishmentsView(sqlSession);
                    createUserLookupView(sqlSession);
                });
        log.debug("Initialized LiteBans");
    }

    private static void createAllPunishmentsView(SqlSession sqlSession) {
        String query = """
                CREATE VIEW IF NOT EXISTS all_punishments AS
                SELECT id, uuid, reason, banned_by_uuid, banned_by_name, removed_by_name, time, until, removed_by_reason,
                    'ban' as type
                FROM litebans_bans
                UNION ALL
                SELECT id, uuid, reason, banned_by_uuid, banned_by_name, removed_by_name, time, until, removed_by_reason,
                       'mute' as type
                FROM litebans_mutes
                UNION ALL
                SELECT id, uuid, reason, banned_by_uuid, banned_by_name, removed_by_name, time, until, removed_by_reason,
                       'warn' as type
                FROM litebans_warnings
                ORDER BY time DESC;
                """;
        try (Statement statement = sqlSession.getConnection().createStatement()) {
            statement.execute(query);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    private static void createUserLookupView(SqlSession sqlSession) {
        String query = """
                CREATE VIEW IF NOT EXISTS user_lookup AS
                SELECT history_1.uuid, history_1.name
                FROM litebans.litebans_history history_1
                         INNER JOIN (
                    SELECT uuid, MAX(id) as max_id
                    FROM litebans.litebans_history
                    GROUP BY uuid
                ) history_2 ON history_1.uuid = history_2.uuid AND history_1.id = history_2.max_id
                """;
        try (Statement statement = sqlSession.getConnection().createStatement()) {
            statement.execute(query);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

}
