package com.ecep.contract.ds.other.service;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.other.repository.InventoryHistoryPriceRepository;
import com.ecep.contract.model.Inventory;
import com.ecep.contract.model.InventoryHistoryPrice;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.InventoryHistoryPriceVo;
import com.fasterxml.jackson.databind.JsonNode;

import jakarta.persistence.criteria.Path;

@Lazy
@Service
@CacheConfig(cacheNames = "inventory-history-price")
public class InventoryHistoryPriceService
        implements IEntityService<InventoryHistoryPrice>, QueryService<InventoryHistoryPriceVo>,
        VoableService<InventoryHistoryPrice, InventoryHistoryPriceVo> {
    @Lazy
    @Autowired
    InventoryHistoryPriceRepository repository;

    @Lazy
    @Autowired
    InventoryService inventoryService;

    @Override
    public InventoryHistoryPriceVo findById(Integer id) {
        return repository.findById(id).map(InventoryHistoryPrice::toVo).orElse(null);
    }
    
    public InventoryHistoryPrice getById(Integer id) {
        return repository.findById(id).orElse(null);
    }

    @Override
    public Specification<InventoryHistoryPrice> getSpecification(String searchText) {
        if (!StringUtils.hasText(searchText)) {
            return null;
        }
        return (root, query, builder) -> {
            Path<Inventory> inventory = root.get("inventory");
            return builder.or(
                    builder.like(inventory.get("name"), "%" + searchText + "%"),
                    builder.like(inventory.get("specification"), "%" + searchText + "%"));
        };
    }

    @Override
    public Page<InventoryHistoryPrice> findAll(Specification<InventoryHistoryPrice> spec, Pageable pageable) {
        return repository.findAll(spec, pageable);
    }

    @Override
    public Page<InventoryHistoryPriceVo> findAll(JsonNode paramsNode, Pageable pageable) {
        Specification<InventoryHistoryPrice> spec = null;
        if (paramsNode.has("searchText")) {
            spec = getSpecification(paramsNode.get("searchText").asText());
        }
        // 可以根据需要添加更多参数处理
        return findAll(spec, pageable).map(InventoryHistoryPrice::toVo);
    }

    public List<InventoryHistoryPrice> findAllByInventory(Inventory inventory) {
        return repository.findAllByInventory(inventory);
    }

    @Override
    public void delete(InventoryHistoryPrice entity) {
        repository.delete(entity);
    }

    @Override
    public InventoryHistoryPrice save(InventoryHistoryPrice entity) {
        return repository.save(entity);
    }

    @Override
    public void updateByVo(InventoryHistoryPrice entity, InventoryHistoryPriceVo vo) {
        if (entity == null || vo == null) {
            return;
        }

        // 映射基本属性
        if (vo.getInventoryId() == null) {
            entity.setInventory(null);
        } else {
            if (entity.getInventory() == null || !entity.getInventory().getId().equals(vo.getInventoryId())) {
                Inventory inventory = inventoryService.getById(vo.getInventoryId());
                if (inventory != null) {
                    entity.setInventory(inventory);
                }
            }
        }

        entity.setYear(vo.getYear());

        // 映射各种价格属性
        if (vo.getLatestPurchasePrice() != null) {
            entity.getLatestPurchasePrice().setTaxRate(vo.getLatestPurchasePrice().getTaxRate());
            entity.getLatestPurchasePrice().setPreTaxPrice(vo.getLatestPurchasePrice().getPreTaxPrice());
            entity.getLatestPurchasePrice().setPostTaxPrice(vo.getLatestPurchasePrice().getPostTaxPrice());
            entity.getLatestPurchasePrice().setMonthDay(vo.getLatestPurchasePrice().getMonthDay());
        }

        if (vo.getLatestSalePrice() != null) {
            entity.getLatestSalePrice().setTaxRate(vo.getLatestSalePrice().getTaxRate());
            entity.getLatestSalePrice().setPreTaxPrice(vo.getLatestSalePrice().getPreTaxPrice());
            entity.getLatestSalePrice().setPostTaxPrice(vo.getLatestSalePrice().getPostTaxPrice());
            entity.getLatestSalePrice().setMonthDay(vo.getLatestSalePrice().getMonthDay());
        }

        if (vo.getMiniPurchasePrice() != null) {
            entity.getMiniPurchasePrice().setTaxRate(vo.getMiniPurchasePrice().getTaxRate());
            entity.getMiniPurchasePrice().setPreTaxPrice(vo.getMiniPurchasePrice().getPreTaxPrice());
            entity.getMiniPurchasePrice().setPostTaxPrice(vo.getMiniPurchasePrice().getPostTaxPrice());
        }

        if (vo.getMiniSalePrice() != null) {
            entity.getMiniSalePrice().setTaxRate(vo.getMiniSalePrice().getTaxRate());
            entity.getMiniSalePrice().setPreTaxPrice(vo.getMiniSalePrice().getPreTaxPrice());
            entity.getMiniSalePrice().setPostTaxPrice(vo.getMiniSalePrice().getPostTaxPrice());
            entity.getMiniSalePrice().setMonthDay(vo.getMiniSalePrice().getMonthDay());
        }

        if (vo.getMaxPurchasePrice() != null) {
            entity.getMaxPurchasePrice().setTaxRate(vo.getMaxPurchasePrice().getTaxRate());
            entity.getMaxPurchasePrice().setPreTaxPrice(vo.getMaxPurchasePrice().getPreTaxPrice());
            entity.getMaxPurchasePrice().setPostTaxPrice(vo.getMaxPurchasePrice().getPostTaxPrice());
            entity.getMaxPurchasePrice().setMonthDay(vo.getMaxPurchasePrice().getMonthDay());
        }

        if (vo.getMaxSalePrice() != null) {
            entity.getMaxSalePrice().setTaxRate(vo.getMaxSalePrice().getTaxRate());
            entity.getMaxSalePrice().setPreTaxPrice(vo.getMaxSalePrice().getPreTaxPrice());
            entity.getMaxSalePrice().setPostTaxPrice(vo.getMaxSalePrice().getPostTaxPrice());
            entity.getMaxSalePrice().setMonthDay(vo.getMaxSalePrice().getMonthDay());
        }
    }

}
