package com.unicorn.hgzero.meeting.infra.gateway;

import com.unicorn.hgzero.meeting.biz.usecase.out.ParticipantReader;
import com.unicorn.hgzero.meeting.biz.usecase.out.ParticipantWriter;
import com.unicorn.hgzero.meeting.infra.gateway.entity.MeetingParticipantEntity;
import com.unicorn.hgzero.meeting.infra.gateway.repository.MeetingParticipantJpaRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 참석자 Gateway 구현체
 * ParticipantReader, ParticipantWriter 인터페이스 구현
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ParticipantGateway implements ParticipantReader, ParticipantWriter {

    private final MeetingParticipantJpaRepository participantRepository;

    @Override
    @Transactional(readOnly = true)
    public List<String> findParticipantsByMeetingId(String meetingId) {
        return participantRepository.findByMeetingId(meetingId).stream()
                .map(MeetingParticipantEntity::getUserId)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public List<String> findMeetingsByParticipant(String userId) {
        return participantRepository.findByUserId(userId).stream()
                .map(MeetingParticipantEntity::getMeetingId)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public boolean existsParticipant(String meetingId, String userId) {
        return participantRepository.existsByMeetingIdAndUserId(meetingId, userId);
    }

    @Override
    @Transactional(readOnly = true)
    public int countParticipantsByMeetingId(String meetingId) {
        return participantRepository.countByMeetingId(meetingId);
    }

    @Override
    @Transactional
    public void saveParticipant(String meetingId, String userId) {
        if (!participantRepository.existsByMeetingIdAndUserId(meetingId, userId)) {
            MeetingParticipantEntity participant = MeetingParticipantEntity.builder()
                    .meetingId(meetingId)
                    .userId(userId)
                    .invitationStatus("PENDING")
                    .attended(false)
                    .build();
            participantRepository.save(participant);
            log.debug("Participant saved: meetingId={}, userId={}", meetingId, userId);
        } else {
            log.debug("Participant already exists: meetingId={}, userId={}", meetingId, userId);
        }
    }

    @Override
    @Transactional
    public void saveParticipants(String meetingId, List<String> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return;
        }

        List<MeetingParticipantEntity> participants = userIds.stream()
                .filter(userId -> !participantRepository.existsByMeetingIdAndUserId(meetingId, userId))
                .map(userId -> MeetingParticipantEntity.builder()
                        .meetingId(meetingId)
                        .userId(userId)
                        .invitationStatus("PENDING")
                        .attended(false)
                        .build())
                .collect(Collectors.toList());

        if (!participants.isEmpty()) {
            participantRepository.saveAll(participants);
            log.debug("Participants saved: meetingId={}, count={}", meetingId, participants.size());
        }
    }

    @Override
    @Transactional
    public void deleteParticipant(String meetingId, String userId) {
        participantRepository.deleteById(new com.unicorn.hgzero.meeting.infra.gateway.entity.MeetingParticipantId(meetingId, userId));
        log.debug("Participant deleted: meetingId={}, userId={}", meetingId, userId);
    }

    @Override
    @Transactional
    public void deleteAllParticipants(String meetingId) {
        participantRepository.deleteByMeetingId(meetingId);
        log.debug("All participants deleted: meetingId={}", meetingId);
    }
}
