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

import com.unicorn.hgzero.meeting.biz.domain.AgendaSection;
import com.unicorn.hgzero.meeting.biz.usecase.out.AgendaSectionReader;
import com.unicorn.hgzero.meeting.biz.usecase.out.AgendaSectionWriter;
import com.unicorn.hgzero.meeting.infra.gateway.entity.AgendaSectionEntity;
import com.unicorn.hgzero.meeting.infra.gateway.repository.AgendaSectionJpaRepository;
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.Optional;
import java.util.stream.Collectors;

/**
 * 안건별 회의록 섹션 Gateway 구현체
 */
@Component
@RequiredArgsConstructor
@Slf4j
@Transactional(readOnly = true)
public class AgendaSectionGateway implements AgendaSectionReader, AgendaSectionWriter {

    private final AgendaSectionJpaRepository repository;

    @Override
    public List<AgendaSection> findByMeetingId(String meetingId) {
        log.debug("회의 ID로 안건별 섹션 조회: {}", meetingId);
        return repository.findByMeetingIdOrderByAgendaNumberAsc(meetingId).stream()
                .map(AgendaSectionEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public List<AgendaSection> findByMinutesId(String minutesId) {
        log.debug("회의록 ID로 안건별 섹션 조회: {}", minutesId);
        return repository.findByMinutesIdOrderByAgendaNumberAsc(minutesId).stream()
                .map(AgendaSectionEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    public Optional<AgendaSection> findById(String id) {
        log.debug("ID로 안건별 섹션 조회: {}", id);
        return repository.findById(id)
                .map(AgendaSectionEntity::toDomain);
    }

    @Override
    public Optional<AgendaSection> findByMeetingIdAndAgendaNumber(String meetingId, Integer agendaNumber) {
        log.debug("회의 ID와 안건 번호로 섹션 조회: meetingId={}, agendaNumber={}", meetingId, agendaNumber);
        return Optional.ofNullable(repository.findByMeetingIdAndAgendaNumber(meetingId, agendaNumber))
                .map(AgendaSectionEntity::toDomain);
    }

    @Override
    @Transactional
    public AgendaSection save(AgendaSection section) {
        log.debug("안건별 섹션 저장: {}", section.getId());
        AgendaSectionEntity entity = AgendaSectionEntity.fromDomain(section);
        AgendaSectionEntity saved = repository.save(entity);
        return saved.toDomain();
    }

    @Override
    @Transactional
    public List<AgendaSection> saveAll(List<AgendaSection> sections) {
        log.debug("안건별 섹션 일괄 저장: {} 개", sections.size());
        List<AgendaSectionEntity> entities = sections.stream()
                .map(AgendaSectionEntity::fromDomain)
                .collect(Collectors.toList());

        List<AgendaSectionEntity> saved = repository.saveAll(entities);
        return saved.stream()
                .map(AgendaSectionEntity::toDomain)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void delete(String id) {
        log.debug("안건별 섹션 삭제: {}", id);
        repository.deleteById(id);
    }

    @Override
    @Transactional
    public void deleteByMeetingId(String meetingId) {
        log.debug("회의 ID로 안건별 섹션 전체 삭제: {}", meetingId);
        repository.deleteByMeetingId(meetingId);
    }
}
