package de.szut.casino.lootboxes;

import de.szut.casino.exceptionHandling.exceptions.InsufficientFundsException;
import de.szut.casino.exceptionHandling.exceptions.UserNotFoundException;
import de.szut.casino.user.UserEntity;
import de.szut.casino.user.UserService;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@RestController
public class LootBoxController {
    private final LootBoxRepository lootBoxRepository;
    private final UserService userService;
    private final LootBoxService lootBoxService;

    public LootBoxController(LootBoxRepository lootBoxRepository, UserService userService, LootBoxService lootBoxService) {
        this.lootBoxRepository = lootBoxRepository;
        this.userService = userService;
        this.lootBoxService = lootBoxService;
    }

    @GetMapping("/lootboxes")
    public List<LootBoxEntity> getAllLootBoxes() {
        return lootBoxRepository.findAll();
    }

    @PostMapping("/lootboxes/{id}")
    public ResponseEntity<Object> purchaseLootBox(@PathVariable Long id) {
        Optional<LootBoxEntity> optionalLootBox = lootBoxRepository.findById(id);
        if (optionalLootBox.isEmpty()) {
            return ResponseEntity.notFound().build();
        }

        LootBoxEntity lootBox = optionalLootBox.get();
        UserEntity user = userService.getCurrentUser();

        if (lootBoxService.hasSufficientBalance(user, lootBox.getPrice())) {
            throw new InsufficientFundsException();
        }

        RewardEntity reward = lootBoxService.determineReward(lootBox);
        lootBoxService.handleBalance(user, lootBox, reward);

        return ResponseEntity.ok(reward);
    }

    @PostMapping("/lootboxes")
    public ResponseEntity<Object> createLootbox(@RequestBody @Valid CreateLootBoxDto createLootBoxDto) {
        List<RewardEntity> rewardEntities = new ArrayList<>();

        for (CreateRewardDto createRewardDto : createLootBoxDto.getRewards()) {
            rewardEntities.add(new RewardEntity(createRewardDto.getValue(), createRewardDto.getProbability()));
        }

        LootBoxEntity lootBoxEntity = new LootBoxEntity(
                createLootBoxDto.getName(),
                createLootBoxDto.getPrice(),
                rewardEntities
        );

        this.lootBoxRepository.save(lootBoxEntity);

        return ResponseEntity.ok(lootBoxEntity);
    }

    @DeleteMapping("/lootboxes/{id}")
    public ResponseEntity<Object> deleteLootbox(@PathVariable Long id) {
        Optional<LootBoxEntity> optionalLootBox = lootBoxRepository.findById(id);
        if (optionalLootBox.isEmpty()) {
            return ResponseEntity.notFound().build();
        }

        LootBoxEntity lootBox = optionalLootBox.get();
        lootBoxRepository.delete(lootBox);

        return ResponseEntity.ok(Collections.singletonMap("message", "successfully deleted lootbox"));
    }

}
