package com.alterdekim.hearthhack.service;

import com.alterdekim.hearthhack.dto.RoomDTO;
import com.alterdekim.hearthhack.dto.RoomPlayerDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

import static com.alterdekim.hearthhack.component.GamePool.PLAYERS_COUNT;

@Slf4j
@Service
public class RoomService implements IService {

    private ConcurrentMap<Long, RoomDTO> map;
    private Long _id = 0L;

    public RoomService() {
        this.map = new ConcurrentHashMap<>();
    }

    public List<RoomDTO> getAll() {
        return new ArrayList<>(map.values());
    }

    public Optional<RoomDTO> findById(Long id) {
        return Optional.ofNullable(map.get(id));
    }

    public Long createRoom(RoomDTO room) {
        this._id++;
        room.setId(_id);
        this.map.put(_id, room);
        return this._id;
    }

    public void clearEmptyRooms() {
        this.map.keySet().stream()
                .filter(k -> map.get(k).getPlayers().isEmpty())
                .forEach(k -> map.remove(k));
    }

    public void removeRoom(Long roomId) {
        this.map.remove(roomId);
    }

    public void clear() {
        map = new ConcurrentHashMap<>();
    }

    public void joinRoom(Long roomId, Long userId, Long deckId) {
        RoomDTO r = map.get(roomId);
        log.info("userId: " + userId + "; deckId: " + deckId);
        r.getPlayers().add(new RoomPlayerDTO(userId, deckId));
        map.put(roomId, r);
    }

    public Optional<Long> findRoomWithPlayer() {
        return this.map.values()
                .stream()
                .filter(r -> !r.getPlayers().isEmpty() && r.getPlayers().size() < PLAYERS_COUNT)
                .map(RoomDTO::getId)
                .findFirst();
    }
}
