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

import java.util.Optional;
import java.util.UUID;

import de.oaa.xxx.games.history.GameHistoryRepository;
import de.oaa.xxx.games.chastity.common.BaseLockService;
import de.oaa.xxx.games.chastity.community.CommunityTaskVoteRepository;
import de.oaa.xxx.games.chastity.community.CommunityVerificationRepository;
import de.oaa.xxx.games.chastity.community.CommunityVerificationVoteRepository;
import de.oaa.xxx.games.chastity.timelock.TimeLockRepository;
import de.oaa.xxx.games.chastity.keyholder.KeyholderNotificationRepository;
import de.oaa.xxx.games.chastity.keyholder.KeyholderTaskChoiceRepository;
import de.oaa.xxx.games.chastity.keyholder.KeyholderVerificationRepository;
import de.oaa.xxx.games.chastity.lockcontroll.LockControlFactory;
import de.oaa.xxx.games.chastity.unlock.UnlockCodeHistoryService;
import de.oaa.xxx.social.SystemMessageService;
import de.oaa.xxx.user.UserRepository;
import org.springframework.stereotype.Service;

/**
 * Factory für CardLockService-Instanzen.
 *
 * CardLockService hält pro Instanz den Zustand eines konkreten CardLockEntity
 * und kann daher kein Singleton-Bean sein. Diese Factory zentralisiert die
 * Erzeugung und verwaltet alle Abhängigkeiten als injizierte Singletons.
 */
@Service
public class CardLockServiceFactory {

    private final CardLockRepository cardLockRepository;
    private final CommunityVerificationRepository communityVerificationRepository;
    private final CommunityVerificationVoteRepository communityVerificationVoteRepository;
    private final GameHistoryRepository gameHistoryRepository;
    private final UserRepository userRepository;
    private final UnlockCodeHistoryService unlockCodeHistoryService;
    private final KeyholderNotificationRepository keyholderNotificationRepository;
    private final KeyholderVerificationRepository keyholderVerificationRepository;
    private final SystemMessageService systemMessageService;
    private final KeyholderTaskChoiceRepository keyholderTaskChoiceRepository;
    private final CommunityTaskVoteRepository communityTaskVoteRepository;
    private final LockControlFactory lockControlFactory;
    private final CardlockRepository cardlockRepository;
    private final TimeLockRepository timeLockRepository;

    public CardLockServiceFactory(
            CommunityVerificationRepository communityVerificationRepository,
            CommunityVerificationVoteRepository communityVerificationVoteRepository,
            CardLockRepository cardLockRepository,
            CardlockRepository cardlockRepository,
            GameHistoryRepository gameHistoryRepository,
            UserRepository userRepository,
            KeyholderNotificationRepository keyholderNotificationRepository,
            KeyholderVerificationRepository keyholderVerificationRepository,
            UnlockCodeHistoryService unlockCodeHistoryService,
            SystemMessageService systemMessageService,
            KeyholderTaskChoiceRepository keyholderTaskChoiceRepository,
            CommunityTaskVoteRepository communityTaskVoteRepository,
            LockControlFactory lockControlFactory,
            TimeLockRepository timeLockRepository) {
        this.cardLockRepository = cardLockRepository;
        this.cardlockRepository = cardlockRepository;
        this.communityVerificationRepository = communityVerificationRepository;
        this.communityVerificationVoteRepository = communityVerificationVoteRepository;
        this.gameHistoryRepository = gameHistoryRepository;
        this.userRepository = userRepository;
        this.keyholderNotificationRepository = keyholderNotificationRepository;
        this.unlockCodeHistoryService = unlockCodeHistoryService;
        this.keyholderVerificationRepository = keyholderVerificationRepository;
        this.systemMessageService = systemMessageService;
        this.keyholderTaskChoiceRepository = keyholderTaskChoiceRepository;
        this.communityTaskVoteRepository = communityTaskVoteRepository;
        this.lockControlFactory = lockControlFactory;
        this.timeLockRepository = timeLockRepository;
    }

    public boolean hasActiveLock(UUID lockeeId) {
        return BaseLockService.hasActiveLock(lockeeId, cardlockRepository, timeLockRepository);
    }

    public Optional<UUID> findActiveLockId(UUID lockeeId) {
        var cardLock = cardlockRepository.findByLockee(lockeeId).stream()
                .filter(l -> l.getUnlockTime() == null).findFirst();
        if (cardLock.isPresent()) return Optional.of(cardLock.get().getLockId());
        return timeLockRepository.findFirstByLockeeAndStartTimeIsNotNullAndUnlockTimeIsNull(lockeeId)
                .map(l -> l.getLockId());
    }

    /**
     * Erstellt eine neue CardLockService-Instanz für das gegebene Lock.
     * Setzt den lockControl anhand des gespeicherten controllType.
     */
    public CardLockService create(CardLockEntity lock) {
        CardLockService service = new CardLockService(lock, communityVerificationVoteRepository,
                communityVerificationRepository, keyholderVerificationRepository, gameHistoryRepository,
                userRepository, keyholderNotificationRepository, systemMessageService, unlockCodeHistoryService,
                keyholderTaskChoiceRepository, communityTaskVoteRepository, cardLockRepository, lockControlFactory);
        
        return service;
    }
}
