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

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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;

@Component
public class CommunityTaskVoteScheduler {

    private static final Logger LOG = LoggerFactory.getLogger(CommunityTaskVoteScheduler.class);

    private final CommunityTaskVoteRepository communityTaskVoteRepository;
    private final CommunityTaskVoteEntryRepository communityTaskVoteEntryRepository;
    private final CardlockRepository cardlockRepository;
    private final AssignedTaskRepository assignedTaskRepository;
	private SystemMessageService systemMessageService;

    public CommunityTaskVoteScheduler(CommunityTaskVoteRepository communityTaskVoteRepository,
                             CommunityTaskVoteEntryRepository communityTaskVoteEntryRepository,
                             CardlockRepository cardlockRepository,
                             AssignedTaskRepository assignedTaskRepository,
                             SystemMessageService systemMessageService) {
        this.communityTaskVoteRepository      = communityTaskVoteRepository;
        this.communityTaskVoteEntryRepository = communityTaskVoteEntryRepository;
        this.cardlockRepository               = cardlockRepository;
        this.assignedTaskRepository           = assignedTaskRepository;
        this.systemMessageService             = systemMessageService;
    }

    @Scheduled(fixedDelay = 60_000)
    @Transactional
    public void processExpiredVotes() {
        var expired = communityTaskVoteRepository
                .findByActiveTrueAndExpiresAtBefore(LocalDateTime.now());

        for (var vote : expired) {
            LOG.debug("Processing expired community task vote {}", vote.getDisplayId());

            var lockOpt = cardlockRepository.findById(vote.getLockId());
            if (lockOpt.isEmpty()) {
                vote.setActive(false);
                communityTaskVoteRepository.save(vote);
                continue;
            }
            var lock = lockOpt.get();
            List<Task> tasks = lock.getTasks();
            if (tasks == null || tasks.isEmpty()) {
                vote.setActive(false);
                communityTaskVoteRepository.save(vote);
                continue;
            }

            var entries = communityTaskVoteEntryRepository.findByDisplayId(vote.getDisplayId());
            int winnerIndex;
            if (entries.isEmpty()) {
                winnerIndex = new Random().nextInt(tasks.size());
                LOG.debug("No votes → random task index {}", winnerIndex);
            } else {
                int[] counts = new int[tasks.size()];
                for (var e : entries) {
                    if (e.getTaskIndex() >= 0 && e.getTaskIndex() < tasks.size()) {
                        counts[e.getTaskIndex()]++;
                    }
                }
                int max = Arrays.stream(counts).max().getAsInt();
                List<Integer> winners = new ArrayList<>();
                for (int i = 0; i < counts.length; i++) {
                    if (counts[i] == max) winners.add(i);
                }
                winnerIndex = winners.get(new Random().nextInt(winners.size()));
                LOG.debug("Vote winner: task index {} with {} votes", winnerIndex, max);
            }

            Task task = tasks.get(winnerIndex);
            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");
            assignedTaskRepository.save(assigned);

            vote.setActive(false); 
            vote.setWinningTaskIndex(winnerIndex);
            communityTaskVoteRepository.save(vote);

            sendMessage(lock.getLockee(),
                    "Die Community hat für deine Aufgabe abgestimmt: \"" + task.getTitle() + "\"",
                    "/games/chastity/activelock.html?lockId=" + lock.getLockId());
        }
    }

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