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

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import de.oaa.xxx.games.chastity.cardlock.CardlockRepository;
import de.oaa.xxx.games.chastity.tasks.AssignedTaskEntity;
import de.oaa.xxx.games.chastity.tasks.AssignedTaskRepository;
import de.oaa.xxx.games.chastity.tasks.Task;
import de.oaa.xxx.social.SystemMessageService;
import de.oaa.xxx.user.UserRepository;
import de.oaa.xxx.user.UserService;

@RestController
@RequestMapping("/games/chastity/keyholder/choices")
public class KeyholderTaskChoiceController {

    private final CardlockRepository cardlockRepository;
    private final UserRepository userRepository;
    private final KeyholderTaskChoiceRepository keyholderTaskChoiceRepository;
    private final AssignedTaskRepository assignedTaskRepository;
    private final SystemMessageService systemMessageService;
    private final UserService userService;

    public KeyholderTaskChoiceController(CardlockRepository cardlockRepository,
                              UserRepository userRepository,
                              KeyholderTaskChoiceRepository keyholderTaskChoiceRepository,
                              AssignedTaskRepository assignedTaskRepository,
                              SystemMessageService systemMessageService,
                              UserService userService) {
        this.cardlockRepository              = cardlockRepository;
        this.userRepository                  = userRepository;
        this.keyholderTaskChoiceRepository   = keyholderTaskChoiceRepository;
        this.assignedTaskRepository          = assignedTaskRepository;
        this.systemMessageService            = systemMessageService;
        this.userService                     = userService;
    }
    
    // ── Keyholder: ausstehende Aufgaben-Karten-Entscheidungen ─────────────────
    @GetMapping
    @Transactional(readOnly = true)
    public ResponseEntity<List<Map<String, Object>>> getPendingChoices(Principal principal) {
        UUID myId = userService.requireUser(principal).getUserId();

        // Alle Locks bei denen ich Keyholder bin
        var locks = cardlockRepository.findByKeyholderAndUnlockTimeIsNull(myId);
        List<Map<String, Object>> result = new ArrayList<>();

        for (var lock : locks) {
            var pending = keyholderTaskChoiceRepository.findByLockIdAndActiveTrue(lock.getLockId());
            if (pending.isEmpty()) continue;

            var lockee = userRepository.findById(lock.getLockee()).orElse(null);
            List<Map<String, Object>> taskList = buildTaskList(lock.getTasks());

            for (var choice : pending) {
                Map<String, Object> m = new LinkedHashMap<>();
                m.put("choiceId",    choice.getChoiceId().toString());
                m.put("lockId",      lock.getLockId().toString());
                m.put("lockName",    lock.getName() != null ? lock.getName() : "");
                m.put("lockeeName",  lockee != null ? lockee.getName() : "");
                m.put("createdAt",   choice.getCreatedAt().toString());
                m.put("tasks",       taskList);
                result.add(m);
            }
        }
        return ResponseEntity.ok(result);
    }

    record PenaltyRequest(Integer penaltyFreezeMinutes, Integer penaltyRedCards) {}

    @PostMapping("/{choiceId}/choose/{taskIndex}")
    @Transactional
    public ResponseEntity<Void> chooseTask(@PathVariable("choiceId") UUID choiceId,
                                           @PathVariable("taskIndex") int taskIndex,
                                           @org.springframework.web.bind.annotation.RequestBody(required = false) PenaltyRequest penalty,
                                           Principal principal) {
        UUID myId = userService.requireUser(principal).getUserId();

        var choiceOpt = keyholderTaskChoiceRepository.findById(choiceId);
        if (choiceOpt.isEmpty()) return ResponseEntity.notFound().build();
        var choice = choiceOpt.get();

        var lockOpt = cardlockRepository.findById(choice.getLockId());
        if (lockOpt.isEmpty()) return ResponseEntity.notFound().build();
        var lock = lockOpt.get();

        if (!myId.equals(lock.getKeyholder())) return ResponseEntity.status(403).build();
        if (!choice.isActive()) return ResponseEntity.status(409).build();

        List<Task> tasks = lock.getTasks();
        if (tasks == null || taskIndex < 0 || taskIndex >= tasks.size())
            return ResponseEntity.badRequest().build();

        Task task = tasks.get(taskIndex);
        AssignedTaskEntity assigned = new AssignedTaskEntity();
        assigned.setLockId(lock.getLockId());
        assigned.setTaskTitle(task.getTitle());
        assigned.setTaskDescription(task.getDescription());
        assigned.setTaskText(task.getTitle());
        assigned.setTaskMinutes(task.getMinutes());
        assigned.setAssignedAt(LocalDateTime.now());
        assigned.setAcceptDeadline(LocalDateTime.now().plusHours(1));
        assigned.setStatus("PENDING");
        if (penalty != null) {
            assigned.setPenaltyFreezeMinutes(penalty.penaltyFreezeMinutes());
            assigned.setPenaltyRedCards(penalty.penaltyRedCards());
        }
        assignedTaskRepository.save(assigned);

        choice.setActive(false);
        keyholderTaskChoiceRepository.save(choice);

        sendMessage(myId, lock.getLockee(),
                "Dein Keyholder hat eine Aufgabe für dich ausgewählt.",
                "/games/chastity/activelock.html?lockId=" + lock.getLockId());

        return ResponseEntity.noContent().build();
    }


    // ── Helpers ───────────────────────────────────────────────────────────────

    private List<Map<String, Object>> buildTaskList(List<Task> tasks) {
        if (tasks == null) return List.of();
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < tasks.size(); i++) {
            Task t = tasks.get(i);
            Map<String, Object> m = new LinkedHashMap<>();
            m.put("index",       i);
            m.put("title",       t.getTitle());
            m.put("description", t.getDescription() != null ? t.getDescription() : "");
            m.put("minutes",     t.getMinutes() != null ? t.getMinutes() : 0);
            list.add(m);
        }
        return list;
    }

    private void sendMessage(UUID fromId, UUID toId, String text, String targetUrl) {
        systemMessageService.send(fromId, toId, text, targetUrl, de.oaa.xxx.social.entity.MessageCause.GAME_STATE);
    }
}
