package com.trunksbomb.minetriad.blockentity;

import com.trunksbomb.minetriad.game.DuelSession;
import com.trunksbomb.minetriad.game.DuelSessionManager;
import com.trunksbomb.minetriad.game.MoveResult;
import com.trunksbomb.minetriad.item.CardItem;
import com.trunksbomb.minetriad.registry.TriadItems;

import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.Level;

public final class DuelTableAnimationResolver {
    private DuelTableAnimationResolver() {
    }

    static void handleAfterPlayerAnimation(Level level, BlockPos pos, DuelTableBlockEntity table, DuelSession session) {
        ServerPlayer player = getPlayer(level, session);
        if (player == null) {
            return;
        }

        if (session.isComplete()) {
            enterOverview(table, session, player);
            return;
        }

        if (session.isAiVsAi()) {
            startAiTurn(table, session, player);
            return;
        }

        MoveResult opponentMove = session.playOpponentTurn();
        if (!opponentMove.valid()) {
            player.displayClientMessage(Component.literal(opponentMove.errorMessage()).withStyle(ChatFormatting.RED), false);
            table.clearBoard();
            DuelSessionManager.end(player, true);
            return;
        }

        if (!table.setCard(opponentMove.playedCell().index(), CardItem.createCardStack(opponentMove.playedCardId(), TriadItems.TRIAD_CARD.get()), DuelTableBlockEntity.OWNER_SECOND)) {
            player.displayClientMessage(Component.literal("The Duel Table could not stage the opponent move.").withStyle(ChatFormatting.RED), false);
            table.clearBoard();
            DuelSessionManager.end(player, true);
            return;
        }

        session.beginOpponentAnimation();
        table.startMoveAnimation(opponentMove, DuelTableBlockEntity.OWNER_SECOND);
        player.displayClientMessage(Component.literal("Training Duelist answers with " + opponentMove.playedCardName() + ".").withStyle(ChatFormatting.GRAY), false);
        sendBattleLog(player, opponentMove, ChatFormatting.GRAY);
    }

    static void handleAfterOpponentAnimation(Level level, BlockPos pos, DuelTableBlockEntity table, DuelSession session) {
        ServerPlayer player = getPlayer(level, session);
        if (player == null) {
            return;
        }

        if (session.isComplete()) {
            enterOverview(table, session, player);
            return;
        }

        if (session.isAiVsAi()) {
            startAiTurn(table, session, player);
            return;
        }

        session.returnToPlaying();
        player.displayClientMessage(session.boardSummary(), false);
        player.displayClientMessage(Component.literal("Your turn. Hold one of your remaining duel cards and click an open space.").withStyle(ChatFormatting.YELLOW), false);
        player.displayClientMessage(session.handSummary(), false);
    }

    public static void startAiTurn(DuelTableBlockEntity table, DuelSession session, ServerPlayer player) {
        MoveResult aiMove = session.playAiTurn();
        if (!aiMove.valid()) {
            player.displayClientMessage(Component.literal(aiMove.errorMessage()).withStyle(ChatFormatting.RED), false);
            table.clearBoard();
            DuelSessionManager.end(player, true);
            return;
        }

        int owner = session.isPlayerTurn() ? DuelTableBlockEntity.OWNER_SECOND : DuelTableBlockEntity.OWNER_FIRST;
        if (!table.setCard(aiMove.playedCell().index(), CardItem.createCardStack(aiMove.playedCardId(), TriadItems.TRIAD_CARD.get()), owner)) {
            player.displayClientMessage(Component.literal("The Duel Table could not stage the AI move.").withStyle(ChatFormatting.RED), false);
            table.clearBoard();
            DuelSessionManager.end(player, true);
            return;
        }

        if (owner == DuelTableBlockEntity.OWNER_FIRST) {
            session.beginPlayerAnimation();
        } else {
            session.beginOpponentAnimation();
        }
        table.startMoveAnimation(aiMove, owner);
        player.displayClientMessage(Component.literal((owner == DuelTableBlockEntity.OWNER_FIRST ? "Blue AI" : "Red AI") + " plays " + aiMove.playedCardName() + ".")
                .withStyle(ChatFormatting.GRAY), false);
        sendBattleLog(player, aiMove, ChatFormatting.GRAY);
    }

    private static void enterOverview(DuelTableBlockEntity table, DuelSession session, ServerPlayer player) {
        session.enterOverview();
        table.startOverviewSweepAnimation();
        player.displayClientMessage(session.resultSummary().copy().withStyle(ChatFormatting.AQUA), false);
        player.displayClientMessage(session.overviewMessage().copy().withStyle(ChatFormatting.YELLOW), false);
    }

    private static void sendBattleLog(ServerPlayer player, MoveResult moveResult, ChatFormatting color) {
        for (String line : moveResult.battleLog()) {
            player.displayClientMessage(Component.literal(line).withStyle(color), false);
        }
    }

    private static ServerPlayer getPlayer(Level level, DuelSession session) {
        return level.getServer() == null ? null : level.getServer().getPlayerList().getPlayer(session.playerParticipantId());
    }
}
