package com.alterdekim.game.service;

import com.alterdekim.game.component.ReferenceLoader;
import com.alterdekim.game.component.game.AvatarInventoryType;
import com.alterdekim.game.component.game.home.HomeInventoryGroup;
import com.alterdekim.game.component.game.home.HomeInventoryObject;
import com.alterdekim.game.entity.AvatarInventory;
import com.alterdekim.game.entity.Good;
import com.alterdekim.game.entity.HouseInventory;
import com.alterdekim.game.message.amf.AMFObject;
import com.alterdekim.game.repository.AvatarInventoryRepository;
import com.alterdekim.game.repository.GoodRepository;
import com.alterdekim.game.repository.HouseInventoryRepository;
import lombok.extern.slf4j.Slf4j;
import org.javatuples.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Slf4j
@Service
public class HomeInventoryService {

    @Autowired
    private HouseInventoryRepository houseInventoryRepository;

    @Autowired
    private AvatarInventoryRepository avatarInventoryRepository;

    @Autowired
    private GoodRepository goodRepository;

    public void removeFurnitureFromHome(int userId, Set<String> ids) {
        for( String id : ids ) {
            houseInventoryRepository.resetHomeId(Long.parseLong(id));
        }
    }

    public void addFurnitureToCurrentHome(int userId, Map<String, AMFObject> additions) {
        Set<String> ids = additions.keySet();
        long houseId = getCurrentHouseId(userId);
        for( String id : ids ) {
            Map<String, AMFObject> obj = (Map<String, AMFObject>) additions.get(id).getRaw();
            Integer frame = obj.containsKey("Frame") ? obj.get("Frame").getInt() : 0;
            houseInventoryRepository.updateInfoById(Long.parseLong(id), houseId, obj.get("x").getDouble(), obj.get("y").getDouble(), frame);
        }
    }

    private long getCurrentHouseId(int userId) {
        return avatarInventoryRepository.findUsedItemsByUserIdAndType(userId, AvatarInventoryType.House).stream()
                .findFirst()
                .map(AvatarInventory::getId)
                .orElse(-1L);
    }

    public List<HomeInventoryGroup> getHomeInventoryOfUser(int userId) {

        List<HomeInventoryGroup> groups = this.houseInventoryRepository.findByUserId(userId)
                .stream()
                .map(HouseInventory::getGoodId)
                .distinct()
                .map(i -> goodRepository.findById(i))
                .filter(Optional::isPresent)
                .map(Optional::get)
                .map(i -> new HomeInventoryGroup("1$"+i.getId(),
                        1,
                        i.getId(),
                        i.getGoodTypeId(),
                        i.getMRId(),
                        i.getTRId(),
                        new ArrayList<>()))
                .collect(Collectors.toList());

        this.houseInventoryRepository.findByUserId(userId)
                .forEach(i -> {
                    for( HomeInventoryGroup group : groups ) {
                        if( group.getObjectId() == i.getGoodId().longValue() ) {
                            group.getObject().add(new HomeInventoryObject(i.getId().intValue(), i.getHomeId() != -1));
                            break;
                        }
                    }
                });
        return groups;
    }
}
