package com.kamco.cd.kamcoback.postgres.repository.mapsheet;

import static com.kamco.cd.kamcoback.postgres.entity.QImageryEntity.imageryEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngHstEntity.mapSheetMngHstEntity;

import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.validation.Valid;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;

public class MapSheetMngFileCheckerRepositoryImpl extends QuerydslRepositorySupport
    implements MapSheetMngFileCheckerRepositoryCustom {

  private final JPAQueryFactory queryFactory;
  private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)");

  public MapSheetMngFileCheckerRepositoryImpl(JPAQueryFactory queryFactory) {
    super(MapSheetMngHstEntity.class);
    this.queryFactory = queryFactory;
  }

  @Override
  public Page<ImageryDto.SyncDto> findImagerySyncList(ImageryDto.@Valid searchReq searchReq) {

    Pageable pageable = searchReq.toPageable();
    BooleanBuilder whereBuilder = new BooleanBuilder();

    if (searchReq.getMngYyyy() != null) {
      whereBuilder.and(imageryEntity.year.eq(searchReq.getMngYyyy()));
    }

    List<ImageryDto.SyncDto> foundContent =
        queryFactory
            .select(
                Projections.constructor(
                    ImageryDto.SyncDto.class,
                    imageryEntity.id,
                    imageryEntity.year,
                    imageryEntity.scene50k,
                    imageryEntity.scene5k,
                    imageryEntity.middlePath,
                    imageryEntity.cogMiddlePath,
                    imageryEntity.filename,
                    imageryEntity.cogFilename,
                    mapSheetMngHstEntity.hstUid))
            .from(imageryEntity)
            .leftJoin(mapSheetMngHstEntity)
            .on(
                imageryEntity
                    .year
                    .eq(mapSheetMngHstEntity.mngYyyy)
                    .and(imageryEntity.scene5k.eq(mapSheetMngHstEntity.mapSheetNum.stringValue())))
            .where(whereBuilder)
            .offset(pageable.getOffset())
            .limit(pageable.getPageSize())
            // .orderBy(mapSheetMngEntity.createdDttm.desc())
            .fetch();

    Long countQuery =
        queryFactory
            .select(imageryEntity.id.count())
            .from(imageryEntity)
            .where(whereBuilder)
            .fetchOne();

    return new PageImpl<>(foundContent, pageable, countQuery);
  }

  private NumberExpression<Integer> rowNum() {
    return Expressions.numberTemplate(
        Integer.class, "row_number() over(order by {0} desc)", mapSheetMngHstEntity.createdDate);
  }
}
