package com.kamco.cd.kamcoback.postgres.core;

import com.kamco.cd.kamcoback.model.dto.ModelMngDto;
import com.kamco.cd.kamcoback.model.dto.ModelVerDto;
import com.kamco.cd.kamcoback.postgres.entity.ModelMngEntity;
import com.kamco.cd.kamcoback.postgres.entity.ModelVerEntity;
import com.kamco.cd.kamcoback.postgres.repository.model.ModelMngRepository;
import com.kamco.cd.kamcoback.postgres.repository.model.ModelVerRepository;
import jakarta.persistence.EntityNotFoundException;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class ModelMngCoreService {

  private final ModelMngRepository modelMngRepository;
  private final ModelVerRepository modelVerRepository;

  public List<ModelMngDto.Basic> findModelMngAll() {
    return modelMngRepository.findModelMngAll().stream().map(ModelMngEntity::toDto).toList();
  }

  public Optional<ModelMngDto.FinalModelDto> getFinalModelInfo() {
    return modelMngRepository.getFinalModelInfo();
  }

  public ModelVerDto.Basic save(ModelMngDto.AddReq addReq) {
    ModelMngEntity modelMngEntity =
        new ModelMngEntity(
            addReq.getModelNm(),
            addReq.getModelCate(),
            addReq.getModelPath(),
            1L,
            1L,
            addReq.getModelCntnt()); // TODO: 로그인 기능 붙이면 Uid 넣어야 함

    ModelMngEntity saved = modelMngRepository.save(modelMngEntity);
    ModelVerEntity modelVerEntity =
        new ModelVerEntity(
            saved.getId(),
            addReq.getModelCate(),
            addReq.getModelVer(),
            "NONE",
            "NONE",
            0.0,
            "NONE",
            addReq.getModelPath(),
            1L,
            1L);
    return modelVerRepository.save(modelVerEntity).toDto();
  }

  public Long update(Long id, ModelMngDto.AddReq addReq) {
    // 조회
    ModelVerEntity existData =
        modelVerRepository
            .findModelVerById(id)
            .orElseThrow(EntityNotFoundException::new); // 데이터 없는 경우 exception
    existData.update(addReq);
    // TODO: 추후 수정 단계에서 도커파일 업로드하면 버전 업데이트 하는 로직 필요
    return existData.getId();
  }

  public Long delete(Long id) {
    // 조회
    ModelVerEntity verEntity =
        modelVerRepository
            .findModelVerById(id)
            .orElseThrow(() -> new EntityNotFoundException("버전 id 에 대한 정보를 찾을 수 없습니다. id : " + id));

    // usedState가 USED 이거나 이미 삭제된 상태이면 삭제 불가
    if (verEntity.getUsedState().equals("USED") || verEntity.isDeleted().equals(true)) {
      throw new IllegalStateException("해당 모델이 사용중이라 삭제 불가"); // TODO: 추후 규칙 정의되면 수정 필요
    }

    // id 코드 deleted = true 업데이트
    verEntity.deleted();
    return verEntity.getId();
  }

  public Page<ModelMngDto.ModelRegHistory> getRegHistoryList(
      ModelMngDto.searchReq searchReq, LocalDate startDate, LocalDate endDate, String searchVal) {
    return modelMngRepository.getRegHistoryList(searchReq, startDate, endDate, searchVal);
  }
}
