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

import com.kamco.cd.kamcoback.common.service.BaseCoreService;
import com.kamco.cd.kamcoback.postgres.entity.AnimalEntity;
import com.kamco.cd.kamcoback.postgres.entity.ZooEntity;
import com.kamco.cd.kamcoback.postgres.repository.AnimalRepository;
import com.kamco.cd.kamcoback.postgres.repository.ZooRepository;
import com.kamco.cd.kamcoback.zoo.dto.AnimalDto;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class AnimalCoreService
    implements BaseCoreService<AnimalDto.Basic, Long, AnimalDto.SearchReq> {

  private final AnimalRepository animalRepository;
  private final ZooRepository zooRepository;

  @Transactional(readOnly = true)
  public AnimalDto.Basic getDataByUuid(String uuid) {
    AnimalEntity getZoo =
        animalRepository
            .getAnimalByUuid(uuid)
            .orElseThrow(() -> new EntityNotFoundException("Zoo not found with uuid: " + uuid));
    return getZoo.toDto();
  }

  // AddReq를 받는 추가 메서드
  @Transactional
  public AnimalDto.Basic create(AnimalDto.AddReq req) {
    ZooEntity zoo = null;
    if (req.getZooUuid() != null) {
      zoo =
          zooRepository
              .getZooByUuid(req.getZooUuid())
              .orElseThrow(
                  () ->
                      new EntityNotFoundException("Zoo not found with uuid: " + req.getZooUuid()));
    }
    AnimalEntity entity = new AnimalEntity(req.getCategory(), req.getSpecies(), req.getName(), zoo);
    AnimalEntity saved = animalRepository.save(entity);
    return saved.toDto();
  }

  @Override
  @Transactional
  public void remove(Long id) {
    AnimalEntity getAnimal =
        animalRepository
            .getAnimalByUid(id)
            .orElseThrow(() -> new EntityNotFoundException("getAnimal not found with id: " + id));
    getAnimal.deleted();
  }

  @Override
  public AnimalDto.Basic getOneById(Long id) {
    AnimalEntity getAnimal =
        animalRepository
            .getAnimalByUid(id)
            .orElseThrow(() -> new EntityNotFoundException("Zoo not found with id: " + id));
    return getAnimal.toDto();
  }

  @Override
  public Page<AnimalDto.Basic> search(AnimalDto.SearchReq searchReq) {

    Page<AnimalEntity> animalEntities = animalRepository.listAnimal(searchReq);
    return animalEntities.map(AnimalEntity::toDto);
  }
}
