package de.szut.casino.slots;

import de.szut.casino.exceptionHandling.exceptions.InsufficientFundsException;
import de.szut.casino.exceptionHandling.exceptions.UserNotFoundException;
import de.szut.casino.shared.dto.BetDto;
import de.szut.casino.shared.service.BalanceService;
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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@RestController
public class SlotController {
    private final UserService userService;
    private final BalanceService balanceService;
    private final SlotService slotService;

    public SlotController(UserService userService, BalanceService balanceService, SlotService slotService) {
        this.userService = userService;
        this.balanceService = balanceService;
        this.slotService = slotService;
    }

    @PostMapping("/slots/spin")
    public ResponseEntity<Object> spinSlots(@RequestBody @Valid BetDto betDto) {
        Optional<UserEntity> optionalUser = userService.getCurrentUser();

        if (optionalUser.isEmpty()) {
            throw new UserNotFoundException();
        }

        UserEntity user = optionalUser.get();

        if (!this.balanceService.hasFunds(user, betDto)) {
            throw new InsufficientFundsException();
        }

        SpinResult spinResult = this.slotService.spin(
                betDto.getBetAmount(),
                user
        );

        return ResponseEntity.ok(spinResult);
    }

    @GetMapping("/slots/info")
    public ResponseEntity<Object> spinSlots() {
        Map<String, BigDecimal> info = new HashMap<>();

        for (Symbol symbol : Symbol.values()) {
            info.put(symbol.getDisplayName(), symbol.getPayoutMultiplier());
        }

        return ResponseEntity.ok(info);
    }
}
