package com.mortals.xhx.module.product.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.module.category.model.CategoryEntity;
import com.mortals.xhx.module.category.service.CategoryService;
import com.mortals.xhx.module.company.model.CompanyEntity;
import com.mortals.xhx.module.company.model.CompanyProductEntity;
import com.mortals.xhx.module.company.model.CompanyProductQuery;
import com.mortals.xhx.module.company.service.CompanyProductService;
import com.mortals.xhx.module.company.service.CompanyService;
import com.mortals.xhx.module.favorites.model.FavoritesProductEntity;
import com.mortals.xhx.module.favorites.model.FavoritesProductQuery;
import com.mortals.xhx.module.favorites.service.FavoritesProductService;
import com.mortals.xhx.module.product.model.*;
import com.mortals.xhx.module.product.service.ProductCategoryService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.product.dao.ProductDao;
import com.mortals.xhx.module.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import com.mortals.xhx.module.product.service.ProductQuestionService;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;

/**
 * ProductService
 * 产品 service实现
 *
 * @author zxfei
 * @date 2023-09-18
 */
@Service("productService")
@Slf4j
public class ProductServiceImpl extends AbstractCRUDCacheServiceImpl<ProductDao, ProductEntity, Long> implements ProductService {
    @Autowired
    private ProductQuestionService productQuestionService;

    @Autowired
    private ProductCategoryService productCategoryService;
    @Autowired
    private CompanyProductService companyProductService;

    @Autowired
    private CategoryService categoryService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private FavoritesProductService favoritesProductService;

    @Value("${domain.name:https://oa.xinhx.co}")
    private String domain;

    @Override
    public Result<ProductEntity> find(ProductEntity entity, PageInfo pageInfo, Context context) throws AppException {
        Result<ProductEntity> productEntityResult = new Result<>();
        if (ObjectUtils.isEmpty(entity.getCategoryId()) && ObjectUtils.isEmpty(entity.getCompanyId())) {
            return super.find(entity, pageInfo, context);
        } else {
            Integer hot = entity.getHot();
            //针对不同查询返回不同结果集
            if (!ObjectUtils.isEmpty(entity.getCategoryId()) && ObjectUtils.isEmpty(entity.getCompanyId())) {
                Result<ProductCategoryEntity> productCategoryResult = productCategoryService.find(new ProductCategoryQuery().categoryId(Long.parseLong(entity.getCategoryId())), pageInfo, context);
                List<ProductEntity> productList = getProductEntitiesByCategory(entity, productCategoryResult);
                if (!ObjectUtils.isEmpty(hot)) {
                    //过滤热门与非热门
                    productList = productList.stream().filter(f -> f.getHot() == hot).collect(Collectors.toList());
                }

                productEntityResult.setList(productList);
                productEntityResult.setPageInfo(productCategoryResult.getPageInfo());
                productEntityResult.setDict(productCategoryResult.getDict());

            } else if (ObjectUtils.isEmpty(entity.getCategoryId()) && !ObjectUtils.isEmpty(entity.getCompanyId())) {

                Result<CompanyProductEntity> companyProductEntityResult = companyProductService.find(new CompanyProductQuery().companyId(Long.parseLong(entity.getCompanyId())), pageInfo, context);
                List<CompanyProductEntity> companyProducList = companyProductEntityResult.getList();
                List<ProductEntity> productList = getProductEntitiesByCompanyId(entity, companyProducList);
                if (!ObjectUtils.isEmpty(hot)) {
                    //过滤热门与非热门
                    productList = productList.stream().filter(f -> f.getHot() == hot).collect(Collectors.toList());
                }
                productEntityResult.setList(productList);
                productEntityResult.setPageInfo(companyProductEntityResult.getPageInfo());
                productEntityResult.setDict(companyProductEntityResult.getDict());
            } else {
                //同时查询公司与种类
                Result<ProductCategoryEntity> productCategoryResult = productCategoryService.find(new ProductCategoryQuery().categoryId(Long.parseLong(entity.getCategoryId())), pageInfo, context);
                List<ProductEntity> productCategoryList = getProductEntitiesByCategory(entity, productCategoryResult);

                Result<CompanyProductEntity> companyProductEntityResult = companyProductService.find(new CompanyProductQuery().companyId(Long.parseLong(entity.getCompanyId())), pageInfo, context);
                List<CompanyProductEntity> companyProducList = companyProductEntityResult.getList();
                List<ProductEntity> productCompanyList = getProductEntitiesByCompanyId(entity, companyProducList);

                //求2个list的交集
                List<ProductEntity> collect = CollUtil.intersection(productCategoryList, productCompanyList).stream().collect(Collectors.toList());
                if (!ObjectUtils.isEmpty(hot)) {
                    //过滤热门与非热门
                    collect = collect.stream().filter(f -> f.getHot() == hot).collect(Collectors.toList());
                }
                productEntityResult.setList(collect);
                pageInfo.setTotalResult(collect.size());
                productEntityResult.setPageInfo(pageInfo);
                productEntityResult.setDict(companyProductEntityResult.getDict());
            }
        }
        if(CollectionUtils.isNotEmpty(productEntityResult.getList())){
            String regex = "src=\"file";
            String replacement;
            if(domain.endsWith("/")){
                replacement = "src=\"" + domain + "file";
            }else {
                replacement = "src=\"" + domain + "/file";
            }
            productEntityResult.getList().forEach(item -> {
                if(StringUtils.isNotEmpty(item.getProductDetail())) {
                    item.setProductDetail(item.getProductDetail().replaceAll(regex, replacement));
                }
                String categoryIds = productCategoryService.find(new ProductCategoryQuery().productId(item.getId())).stream().map(i -> i.getCategoryId().toString()).distinct().collect(Collectors.joining(","));
                String companyIds = companyProductService.find(new CompanyProductQuery().productId(item.getId())).stream().map(i -> i.getCompanyId().toString()).distinct().collect(Collectors.joining(","));
                item.setCompanyId(companyIds);
                item.setCategoryId(categoryIds);
            });
        }
        return productEntityResult;
    }

    @Override
    public List<ProductEntity> getProductEntitiesByCompanyId(ProductEntity entity, List<CompanyProductEntity> companyProducList) {
        List<ProductEntity> productList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(companyProducList)){
            companyProducList.forEach(item->{
                ProductEntity productEntity = this.getCache(item.getProductId().toString());
                if (!ObjectUtils.isEmpty(productEntity)) {
                    productEntity.setCompanyId(entity.getCompanyId());
                    String categoryIds = productCategoryService.find(new ProductCategoryQuery().productId(item.getId())).stream().map(i -> i.getCategoryId().toString()).collect(Collectors.joining(","));
                    productEntity.setCategoryId(categoryIds);
                    productList.add(productEntity);
                }
            });
        }
        return productList;
    }

    private List<ProductEntity> getProductEntitiesByCategory(ProductEntity entity, Result<ProductCategoryEntity> productCategoryResult) {
        List<ProductEntity> productList = productCategoryResult.getList().stream().map(item -> {
            ProductEntity productEntity = this.getCache(item.getProductId().toString());
            if (!ObjectUtils.isEmpty(productEntity)) {
                String companyIds = companyProductService.find(new CompanyProductQuery().productId(productEntity.getId())).stream().map(i -> i.getCompanyId().toString()).collect(Collectors.joining(","));
                productEntity.setCompanyId(companyIds);
                productEntity.setCategoryId(entity.getCategoryId());
            }
            return productEntity;
        }).collect(Collectors.toList());
        return productList;
    }

    @Override
    protected void findAfter(ProductEntity params, PageInfo pageInfo, Context context, List<ProductEntity> list) throws AppException {
        String regex = "src=\"file";
        String replacement;
        if(domain.endsWith("/")){
            replacement = "src=\"" + domain + "file";
        }else {
            replacement = "src=\"" + domain + "/file";
        }
        list.forEach(item -> {
            if(StringUtils.isNotEmpty(item.getProductDetail())) {
                item.setProductDetail(item.getProductDetail().replaceAll(regex, replacement));
            }
            String categoryIds = productCategoryService.find(new ProductCategoryQuery().productId(item.getId())).stream().map(i -> i.getCategoryId().toString()).distinct().collect(Collectors.joining(","));
            String companyIds = companyProductService.find(new CompanyProductQuery().productId(item.getId())).stream().map(i -> i.getCompanyId().toString()).distinct().collect(Collectors.joining(","));
            item.setCompanyId(companyIds);
            item.setCategoryId(categoryIds);
        });

    }

    @Override
    protected void saveAfter(ProductEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getProductQuestionList())) {
            entity.getProductQuestionList().stream().peek(item -> {
                item.setProductId(entity.getId());
                item.setProductName(entity.getProductName());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
            }).count();
            productQuestionService.save(entity.getProductQuestionList());
        }

        if (!ObjectUtils.isEmpty(entity.getCompanyId())) {
            List<CompanyProductEntity> companyProductList = Arrays.asList(entity.getCompanyId().split(",")).stream().map(item -> {
                CompanyEntity companyEntity = companyService.get(Long.parseLong(item), context);
                CompanyProductEntity companyProductEntity = new CompanyProductEntity();
                companyProductEntity.initAttrValue();
                companyProductEntity.setProductId(entity.getId());
                companyProductEntity.setProductName(entity.getProductName());
                companyProductEntity.setCompanyId(companyEntity.getId());
                companyProductEntity.setCompanyName(companyEntity.getCompanyName());
                companyProductEntity.setCreateUserId(this.getContextUserId(context));
                companyProductEntity.setCreateTime(new Date());
                return companyProductEntity;
            }).collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(companyProductList)) {
                companyProductService.save(companyProductList);
            }
        }

        if (!ObjectUtils.isEmpty(entity.getCategoryId())) {
            List<ProductCategoryEntity> productCategoryList = Arrays.asList(entity.getCategoryId().split(",")).stream().map(item -> {
                CategoryEntity categoryEntity = categoryService.get(Long.parseLong(item), context);
                ProductCategoryEntity productCategoryEntity = new ProductCategoryEntity();
                productCategoryEntity.initAttrValue();
                productCategoryEntity.setProductId(entity.getId());
                productCategoryEntity.setProductName(entity.getProductName());
                productCategoryEntity.setCategoryId(categoryEntity.getId());
                productCategoryEntity.setCategoryName(categoryEntity.getName());
                productCategoryEntity.setCreateUserId(this.getContextUserId(context));
                productCategoryEntity.setCreateTime(new Date());
                return productCategoryEntity;
            }).collect(Collectors.toList());

            if (!ObjectUtils.isEmpty(productCategoryList)) {
                productCategoryService.save(productCategoryList);
            }
        }


        super.saveAfter(entity, context);
    }

    @Override
    protected void updateAfter(ProductEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getProductQuestionList())) {
            Long[] productQuestionIds = productQuestionService.find(new ProductQuestionQuery().productId(entity.getId())).stream().map(ProductQuestionEntity::getId).toArray(Long[]::new);
            productQuestionService.remove(productQuestionIds, context);
            entity.getProductQuestionList().stream().peek(item -> {
                item.setProductId(entity.getId());
                item.setProductName(entity.getProductName());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
                item.setUpdateUserId(this.getContextUserId(context));
                item.setUpdateTime(new Date());
            }).count();
            productQuestionService.save(entity.getProductQuestionList());
        }

        if (!ObjectUtils.isEmpty(entity.getCompanyId())) {

            List<Long> companyList = Arrays.asList(entity.getCompanyId().split(",")).stream().map(Long::parseLong).collect(Collectors.toList());

            CompanyProductQuery companyProductQuery = new CompanyProductQuery();
            companyProductQuery.setProductId(entity.getId());
           // companyProductQuery.setCompanyIdList(companyList);

            Long[] companyProductRemoveIds = companyProductService.find(companyProductQuery).stream().map(i -> i.getId()).toArray(Long[]::new);
            if (!ObjectUtils.isEmpty(companyProductRemoveIds)) {
                companyProductService.remove(companyProductRemoveIds, context);
            }
            List<CompanyProductEntity> companyProductList = companyList.stream().map(item -> {
                CompanyEntity companyEntity = companyService.get(item, context);
                CompanyProductEntity companyProductEntity = new CompanyProductEntity();
                companyProductEntity.initAttrValue();
                companyProductEntity.setProductId(entity.getId());
                companyProductEntity.setProductName(entity.getProductName());
                companyProductEntity.setCompanyId(companyEntity.getId());
                companyProductEntity.setCompanyName(companyEntity.getCompanyName());
                companyProductEntity.setCreateUserId(this.getContextUserId(context));
                companyProductEntity.setCreateTime(new Date());
                return companyProductEntity;
            }).collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(companyProductList)) {
                companyProductService.save(companyProductList);
            }
        }

        if (!ObjectUtils.isEmpty(entity.getCategoryId())) {
            List<Long> categoryList = Arrays.asList(entity.getCategoryId().split(",")).stream().map(i->Long.parseLong(i)).collect(Collectors.toList());
            ProductCategoryQuery productCategoryQuery = new ProductCategoryQuery();
            productCategoryQuery.setProductId(entity.getId());
            //productCategoryQuery.setCategoryIdList(categoryList);

            Long[] productCategoryRemoveIds = productCategoryService.find(productCategoryQuery).stream().map(i -> i.getId()).toArray(Long[]::new);
            if (!ObjectUtils.isEmpty(productCategoryRemoveIds)) {
                productCategoryService.remove(productCategoryRemoveIds, context);
            }

            List<ProductCategoryEntity> productCategoryList = categoryList.stream().map(item -> {
                CategoryEntity categoryEntity = categoryService.get(item, context);
                ProductCategoryEntity productCategoryEntity = new ProductCategoryEntity();
                productCategoryEntity.initAttrValue();
                productCategoryEntity.setProductId(entity.getId());
                productCategoryEntity.setProductName(entity.getProductName());
                productCategoryEntity.setCategoryId(categoryEntity.getId());
                productCategoryEntity.setCategoryName(categoryEntity.getName());
                productCategoryEntity.setCreateUserId(this.getContextUserId(context));
                productCategoryEntity.setCreateTime(new Date());
                return productCategoryEntity;
            }).collect(Collectors.toList());

            if (!ObjectUtils.isEmpty(productCategoryList)) {
                productCategoryService.save(productCategoryList);
            }
        }


        super.updateAfter(entity, context);
    }

    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        List<ProductQuestionEntity> productQuestionlist = productQuestionService.find(new ProductQuestionQuery().productIdList(Arrays.asList(ids)));
        productQuestionService.removeList(productQuestionlist, context);
        List<ProductCategoryEntity> productCategoryList = productCategoryService.find(new ProductCategoryQuery().productIdList(Arrays.asList(ids)));
        productCategoryService.removeList(productCategoryList,context);
        List<CompanyProductEntity> companyProductList = companyProductService.find(new CompanyProductQuery().productIdList(Arrays.asList(ids)));
        companyProductService.removeList(companyProductList,context);
        super.removeAfter(ids, context, result);
    }

    @Override
    public ProductEntity get(Long key, Context context) throws AppException {
        ProductEntity entity = this.dao.get(key);
        if(entity!=null) {
            String regex = "src=\"file";
            String replacement;
            if (domain.endsWith("/")) {
                replacement = "src=\"" + domain + "file";
            } else {
                replacement = "src=\"" + domain + "/file";
            }
            if(StringUtils.isNotEmpty(entity.getProductDetail())) {
                entity.setProductDetail(entity.getProductDetail().replaceAll(regex, replacement));
            }
            if(context!=null && context.getUser()!=null) {
                FavoritesProductEntity favoritesProductEntity = favoritesProductService.selectOne(new FavoritesProductQuery().productId(key).userId(context.getUser().getId()));
                if(favoritesProductEntity!=null){
                    entity.setFavoriteStatus(1);
                }else {
                    entity.setFavoriteStatus(0);
                }
            }else {
                entity.setFavoriteStatus(0);
            }
            String categoryIds = productCategoryService.find(new ProductCategoryQuery().productId(entity.getId())).stream().map(i -> i.getCategoryId().toString()).distinct().collect(Collectors.joining(","));
            String companyIds = companyProductService.find(new CompanyProductQuery().productId(entity.getId())).stream().map(i -> i.getCompanyId().toString()).distinct().collect(Collectors.joining(","));
            entity.setCompanyId(companyIds);
            entity.setCategoryId(categoryIds);
        }
        return entity;
    }
}