package de.oaa.xxx.games.chastity.common;

import de.oaa.xxx.games.chastity.cardlock.CardlockTemplateEntity;
import de.oaa.xxx.games.chastity.timelock.TimeLockTemplateEntity;
import de.oaa.xxx.user.UserService;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.*;

@RestController
@RequestMapping("/templates")
public class BaseLockTemplateController {

    private final BaseLockTemplateRepository templateRepository;
    private final UserService userService;

    public BaseLockTemplateController(BaseLockTemplateRepository templateRepository,
                                      UserService userService) {
        this.templateRepository = templateRepository;
        this.userService = userService;
    }

    @GetMapping
    public ResponseEntity<Map<String, Object>> list(
            @RequestParam(name = "page", defaultValue = "0") int page,
            @RequestParam(name = "size", defaultValue = "20") int size,
            Principal principal) {
        UUID myId = userService.requireUser(principal).getUserId();

        var pageable = PageRequest.of(page, Math.min(size, 50), Sort.by("name"));
        var pageResult = templateRepository.findByOwner(myId, pageable);

        var content = pageResult.getContent().stream().map(t -> {
            Map<String, Object> dto = new LinkedHashMap<>();
            dto.put("templateId", t.getTemplateId());
            dto.put("name", t.getName());
            dto.put("lockType", t instanceof CardlockTemplateEntity ? "CARDLOCK" : "TIMELOCK");
            dto.put("hygineOpeningEveryMinites", t.getHygineOpeningEveryMinites());
            dto.put("hygineOpeningDurationMinutes", t.getHygineOpeningDurationMinutes());
            dto.put("taskCount", t.getTasks() != null ? t.getTasks().size() : 0);
            dto.put("requiresVerification", t.isRequiresVerification());
            dto.put("published", t.isPublished());
            dto.put("showAuthor", t.isShowAuthor());
            return dto;
        }).toList();

        Map<String, Object> response = new LinkedHashMap<>();
        response.put("content", content);
        response.put("page", pageResult.getNumber());
        response.put("totalPages", pageResult.getTotalPages());
        response.put("last", pageResult.isLast());
        return ResponseEntity.ok(response);
    }

    @GetMapping("/{id}")
    public ResponseEntity<Map<String, Object>> getById(@PathVariable("id") UUID id, Principal principal) {
        UUID myId = userService.requireUser(principal).getUserId();

        var opt = templateRepository.findById(id);
        if (opt.isEmpty()) return ResponseEntity.notFound().build();
        var t = opt.get();
        if (!t.getOwner().equals(myId)) return ResponseEntity.status(403).build();

        if (t instanceof CardlockTemplateEntity c) {
            return ResponseEntity.ok(toCardlockDto(c));
        } else if (t instanceof TimeLockTemplateEntity tl) {
            return ResponseEntity.ok(toTimelockDto(tl));
        }
        return ResponseEntity.notFound().build();
    }

    private Map<String, Object> toCardlockDto(CardlockTemplateEntity t) {
        Map<String, Object> dto = new LinkedHashMap<>();
        dto.put("_type", "CARDLOCK");
        dto.put("templateId", t.getTemplateId());
        dto.put("name", t.getName());
        dto.put("cardCountsMin", t.getCardCountsMin() != null ? t.getCardCountsMin() : Map.of());
        dto.put("cardCountsMax", t.getCardCountsMax() != null ? t.getCardCountsMax() : Map.of());
        dto.put("pickEveryMinute", t.getPickEveryMinute());
        dto.put("accumulatePicks", t.isAccumulatePicks());
        dto.put("showRemainingCards", t.isShowRemainingCards());
        dto.put("hygineOpeningEveryMinites", t.getHygineOpeningEveryMinites());
        dto.put("hygineOpeningDurationMinutes", t.getHygineOpeningDurationMinutes());
        dto.put("tasks", t.getTasks() != null ? t.getTasks() : List.of());
        dto.put("requiresVerification", t.isRequiresVerification());
        dto.put("taskCardMode", t.getTaskCardMode());
        return dto;
    }

    private Map<String, Object> toTimelockDto(TimeLockTemplateEntity t) {
        Map<String, Object> dto = new LinkedHashMap<>();
        dto.put("_type", "TIMELOCK");
        dto.put("templateId", t.getTemplateId());
        dto.put("name", t.getName());
        dto.put("minTimeInMinutes", t.getMinTimeInMinutes());
        dto.put("maxTimeInMinutes", t.getMaxTimeInMinutes());
        dto.put("endTimeVisible", t.isEndTimeVisible());
        dto.put("hygineOpeningEveryMinites", t.getHygineOpeningEveryMinites());
        dto.put("hygineOpeningDurationMinutes", t.getHygineOpeningDurationMinutes());
        dto.put("tasks", t.getTasks() != null ? t.getTasks() : List.of());
        dto.put("taskEveryMinutes", t.getTaskEveryMinutes());
        dto.put("minTasksPerDay", t.getMinTasksPerDay());
        dto.put("spinningWheelEntries", t.getSpinningWheelEntries() != null ? t.getSpinningWheelEntries() : List.of());
        dto.put("spinsEveryMinutes", t.getSpinsEveryMinutes());
        dto.put("minSpinsPerDay", t.getMinSpinsPerDay());
        dto.put("requiresVerification", t.isRequiresVerification());
        dto.put("taskMode", t.getTaskCardMode());
        dto.put("penaltyType", t.getPenaltyType());
        dto.put("penaltyValue", t.getPenaltyValue());
        return dto;
    }
}
