package com.kt.event.participation.test.integration;

import com.kt.event.participation.domain.participant.Participant;
import com.kt.event.participation.domain.participant.ParticipantRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;

/**
 * Spring Data JPA 메서드의 실제 쿼리 확인용 테스트
 *
 * @author Digital Garage Team
 * @since 2025-01-24
 */
@DataJpaTest
@TestPropertySource(properties = {
    "spring.jpa.show-sql=true",
    "spring.jpa.properties.hibernate.format_sql=true",
    "logging.level.org.hibernate.SQL=DEBUG",
    "logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE"
})
@DisplayName("JPA 쿼리 검증 테스트")
class QueryVerificationTest {

    @Autowired
    private ParticipantRepository participantRepository;

    @Test
    @DisplayName("countByEventIdAndIsWinnerTrue 메서드의 실제 쿼리 확인")
    void verifyCountByEventIdAndIsWinnerTrueQuery() {
        // Given
        String eventId = "evt_test_001";

        // 테스트 데이터 생성
        for (int i = 1; i <= 5; i++) {
            Participant participant = Participant.builder()
                    .participantId("prt_test_" + i)
                    .eventId(eventId)
                    .name("참여자" + i)
                    .phoneNumber("010-1234-" + String.format("%04d", i))
                    .email("test" + i + "@test.com")
                    .storeVisited(true)
                    .bonusEntries(2)
                    .agreeMarketing(true)
                    .agreePrivacy(true)
                    .isWinner(i <= 2)
                    .build();
            participantRepository.save(participant);
        }

        // When - 이 쿼리가 실행되면서 콘솔에 SQL이 출력됨
        System.out.println("\n========== countByEventIdAndIsWinnerTrue 실행 ==========");
        long count = participantRepository.countByEventIdAndIsWinnerTrue(eventId);
        System.out.println("========== 결과: " + count + " ==========\n");
    }

    @Test
    @DisplayName("findByEventIdAndPhoneNumber 메서드의 실제 쿼리 확인")
    void verifyExistsByEventIdAndPhoneNumberQuery() {
        // Given
        String eventId = "evt_test_002";
        String phoneNumber = "010-1234-5678";

        Participant participant = Participant.builder()
                .participantId("prt_test_001")
                .eventId(eventId)
                .name("홍길동")
                .phoneNumber(phoneNumber)
                .email("hong@test.com")
                .storeVisited(true)
                .bonusEntries(2)
                .agreeMarketing(true)
                .agreePrivacy(true)
                .isWinner(false)
                .build();
        participantRepository.save(participant);

        // When
        System.out.println("\n========== existsByEventIdAndPhoneNumber 실행 ==========");
        boolean exists = participantRepository.existsByEventIdAndPhoneNumber(eventId, phoneNumber);
        System.out.println("========== 결과: " + exists + " ==========\n");
    }

    @Test
    @DisplayName("findByEventIdOrderByCreatedAtDesc 메서드의 실제 쿼리 확인")
    void verifyFindByEventIdOrderByCreatedAtDescQuery() {
        // Given
        String eventId = "evt_test_003";

        for (int i = 1; i <= 3; i++) {
            Participant participant = Participant.builder()
                    .participantId("prt_test_" + i)
                    .eventId(eventId)
                    .name("참여자" + i)
                    .phoneNumber("010-1234-" + String.format("%04d", i))
                    .email("test" + i + "@test.com")
                    .storeVisited(true)
                    .bonusEntries(2)
                    .agreeMarketing(true)
                    .agreePrivacy(true)
                    .isWinner(false)
                    .build();
            participantRepository.save(participant);
        }

        // When
        System.out.println("\n========== findByEventIdOrderByCreatedAtDesc 실행 ==========");
        participantRepository.findByEventIdOrderByCreatedAtDesc(eventId,
            org.springframework.data.domain.PageRequest.of(0, 10));
        System.out.println("========== 쿼리 실행 완료 ==========\n");
    }
}
