package com.bio.bio_backend.domain.base.resource.repository;

import com.bio.bio_backend.domain.base.resource.entity.Resource;
import com.bio.bio_backend.domain.base.authgroup.entity.QAuthGroup;
import com.bio.bio_backend.domain.base.authgroupresource.entity.QAuthGroupResource;
import com.bio.bio_backend.domain.base.memberauthgroup.entity.QMemberAuthGroup;
import com.bio.bio_backend.domain.base.resource.entity.QResource;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * QueryDSL을 활용하여 ResourceRepositoryCustom 인터페이스를 구현하는 클래스
 * 복잡한 쿼리나 동적 쿼리를 QueryDSL로 작성하여 성능과 가독성을 향상시킵니다.
 */
@Repository
@RequiredArgsConstructor
public class ResourceRepositoryImpl implements ResourceRepositoryCustom {

    private final JPAQueryFactory queryFactory;

    /**
     * QResource 인스턴스를 생성하여 쿼리에서 사용합니다.
     * QueryDSL의 Q클래스를 통해 타입 안전한 쿼리 작성이 가능합니다.
     */
    // private final QMember member = QMember.member;
    private final QMemberAuthGroup memberAuthGroup = QMemberAuthGroup.memberAuthGroup;
    private final QAuthGroup authGroup = QAuthGroup.authGroup;
    private final QAuthGroupResource authGroupResource = QAuthGroupResource.authGroupResource;
    private final QResource resource = QResource.resource;

    @Override
    public List<Resource> findResourcesByMemberId(Long memberOId) {
        return queryFactory
                .select(resource).distinct()
                .from(resource)
                // join(연결할 Q-Type).on(연결 조건) 형태로 명시적 조인
                .join(authGroupResource).on(authGroupResource.resourceOid.eq(resource))
                .join(authGroup).on(authGroupResource.authGroupOid.eq(authGroup))
                .join(memberAuthGroup).on(memberAuthGroup.authGroupOid.eq(authGroup))
                // 최종적으로 Member ID로 필터링
                .where(memberAuthGroup.memberOid.oid.eq(memberOId))
                .fetch();
    }
}
