package org.example.game;

import com.nhn.gameanvil.exceptions.GameAnvilException;
import com.nhn.gameanvil.exceptions.NodeNotFoundException;
import com.nhn.gameanvil.game.GameAnvilRoom;
import com.nhn.gameanvil.node.game.IRoom;
import com.nhn.gameanvil.node.game.context.IRoomContext;
import com.nhn.gameanvil.node.game.data.MatchCancelReason;
import com.nhn.gameanvil.packet.IPayload;
import com.nhn.gameanvil.packet.Packet;
import com.nhn.gameanvil.serializer.ITimerHandlerTransferPack;
import com.nhn.gameanvil.serializer.ITransferPack;
import org.example.StringValues;
import org.example.match.BasicRoomMatchInfo;
import protocol.Puzzle;
import org.slf4j.Logger;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;

import static org.slf4j.LoggerFactory.getLogger;

@GameAnvilRoom(
    gameServiceName = StringValues.serviceName,
    gameType = StringValues.roomType,
    useChannelInfo = true
)
public class BasicRoom implements IRoom<BasicUser> {

    private static final Logger logger = getLogger(BasicRoom.class);

    private IRoomContext roomContext;

    private BasicRoomMatchInfo gameRoomMatchInfo;
    public Map<Integer, Puzzle.PuzzlePosition> puzzlePositions = new HashMap<>();

    public void broadcast(Packet packet) {
        final var allUsers = roomContext.getAllUsers();

        for (final var user : allUsers) {
            final var userContext = ((BasicUser)user).getUserContext();
            userContext.send(packet);
        }
    }

    @Override
    public void onCreate(IRoomContext<BasicUser> roomContext) {
        this.roomContext = roomContext;
    }

    @Override
    public void onInit() {
        gameRoomMatchInfo = new BasicRoomMatchInfo(roomContext.getId());
    }

    @Override
    public void onDestroy() {

    }

    @Override
    public boolean onCreateRoom(BasicUser user, IPayload payload, IPayload outPayload) {
        boolean isSuccess = true;
        try {
            roomContext.registerRoomMatch(gameRoomMatchInfo, user.getUserContext().getUserId());
        } catch (NodeNotFoundException | TimeoutException | GameAnvilException e) {
            logger.error("BasicRoom::onCreateRoom()", e);
        }
        return isSuccess;
    }

    @Override
    public boolean onJoinRoom(BasicUser user, IPayload payload, IPayload outPayload) {
        boolean isSuccess = true;
        try {
            roomContext.updateRoomMatch(gameRoomMatchInfo);
        } catch (NodeNotFoundException | TimeoutException | GameAnvilException e) {
            logger.error("BasicRoom::onJoinRoom()", e);
        }
        return isSuccess;
    }

    @Override
    public boolean canLeaveRoom(BasicUser user, IPayload payload, IPayload outPayload) {
        return true;
    }

    @Override
    public void onLeaveRoom(BasicUser user) {

    }

    @Override
    public void onAfterLeaveRoom() {

    }

    @Override
    public void onRejoinRoom(BasicUser user, IPayload payload) {

    }

    @Override
    public void onTransferOut(ITransferPack transferPack) {

    }

    @Override
    public void onTransferIn(List<BasicUser> list, ITransferPack transferPack, ITimerHandlerTransferPack timerHandlerTransferPack) {

    }

    @Override
    public void onAfterTransferIn() {

    }

    @Override
    public void onPause() {

    }

    @Override
    public void onResume() {

    }

    @Override
    public boolean onMatchParty(String roomType, String matchingGroup, BasicUser user, IPayload payload, IPayload outPayload) {
        boolean isSuccess = true;
        return isSuccess;
    }

    @Override
    public void onMatchPartyCancel(MatchCancelReason matchCancelReason) {

    }

    @Override
    public void onForceMatchRoomUnregistered(MatchCancelReason matchCancelReason) {

    }

    @Override
    public boolean canTransfer() {
        return true;
    }
}
