package com.toyshop.service;

import com.toyshop.entity.*;
import com.toyshop.repository.*;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

@Service
public class ProductService {
  private final ProductRepository productRepository;
  private final ProductImageRepository productImageRepository;
  private final CategoryRepository categoryRepository;

  public ProductService(ProductRepository productRepository, ProductImageRepository productImageRepository,
                        CategoryRepository categoryRepository) {
    this.productRepository = productRepository;
    this.productImageRepository = productImageRepository;
    this.categoryRepository = categoryRepository;
  }

  public List<Product> search(String keyword, Long categoryId, String sort) {
    Specification<Product> spec = (root, query, cb) -> {
      List<Predicate> predicates = new ArrayList<>();
      if (keyword != null && !keyword.isBlank()) {
        predicates.add(cb.like(root.get("name"), "%" + keyword + "%"));
      }
      if (categoryId != null) {
        predicates.add(cb.equal(root.get("category").get("id"), categoryId));
      }
      predicates.add(cb.isTrue(root.get("onSale")));
      return cb.and(predicates.toArray(new Predicate[0]));
    };
    Sort sortObj = Sort.by(Sort.Direction.DESC, "createdAt");
    if ("price".equalsIgnoreCase(sort)) {
      sortObj = Sort.by(Sort.Direction.ASC, "price");
    } else if ("sales".equalsIgnoreCase(sort)) {
      sortObj = Sort.by(Sort.Direction.DESC, "sales");
    }
    return productRepository.findAll(spec, sortObj);
  }

  public List<ProductImage> getImages(Product product) {
    return productImageRepository.findByProduct(product);
  }

  public Product saveProduct(Product product) {
    return productRepository.save(product);
  }

  public Category getCategory(Long id) {
    return categoryRepository.findById(id).orElse(null);
  }

  public List<Category> allCategories() {
    return categoryRepository.findAll();
  }

  public ProductImage getFirstImage(Product product) {
    return productImageRepository.findTopByProductOrderBySortOrderAsc(product).orElse(null);
  }

  @Transactional
  public void replaceProductImage(Product product, String url) {
    productImageRepository.deleteByProduct(product);
    ProductImage image = new ProductImage();
    image.setProduct(product);
    image.setUrl(url);
    image.setSortOrder(0);
    productImageRepository.save(image);
  }
}
