package com.fjhx.purchase.service.subscribe.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.common.enums.CodingRuleEnum;
import com.fjhx.common.service.coding.CodingRuleService;
import com.fjhx.item.entity.product.po.ProductInfo;
import com.fjhx.item.entity.product.vo.ProductInfoVo;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.purchase.entity.purchase.po.Purchase;
import com.fjhx.purchase.entity.purchase.po.PurchaseDetail;
import com.fjhx.purchase.entity.subscribe.dto.DecisionAidDto;
import com.fjhx.purchase.entity.subscribe.dto.SubscribeDetailSelectDto;
import com.fjhx.purchase.entity.subscribe.dto.SubscribeDto;
import com.fjhx.purchase.entity.subscribe.dto.SubscribeSelectDto;
import com.fjhx.purchase.entity.subscribe.po.Subscribe;
import com.fjhx.purchase.entity.subscribe.po.SubscribeDetail;
import com.fjhx.purchase.entity.subscribe.vo.DecisionAidVo;
import com.fjhx.purchase.entity.subscribe.vo.SubscribeDetailVo;
import com.fjhx.purchase.entity.subscribe.vo.SubscribeVo;
import com.fjhx.purchase.mapper.subscribe.SubscribeMapper;
import com.fjhx.purchase.service.purchase.PurchaseDetailService;
import com.fjhx.purchase.service.purchase.PurchaseService;
import com.fjhx.purchase.service.subscribe.SubscribeDetailService;
import com.fjhx.purchase.service.subscribe.SubscribeService;
import com.ruoyi.common.core.domain.BaseIdPo;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.system.service.ISysDeptService;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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


/**
 * <p>
 * 申购单 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-03
 */
//@DS(SourceConstant.PURCHASE)
@Service
public class SubscribeServiceImpl extends ServiceImpl<SubscribeMapper, Subscribe> implements SubscribeService {

    @Autowired
    private SubscribeDetailService subscribeDetailService;

    @Autowired
    private ProductInfoService productInfoService;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private CodingRuleService codingRuleService;

    @Autowired
    private PurchaseService purchaseService;

    @Autowired
    private PurchaseDetailService purchaseDetailService;


    @Override
    public Page<SubscribeVo> getPage(SubscribeSelectDto dto) {
        IWrapper<Subscribe> wrapper = getWrapper();

        //权限过滤：申购-子公司看自己的,总公司看全部
        Long companyId = SecurityUtils.getCompanyId();
        if (!Objects.equals(companyId, 100L)) {
            wrapper.eq("s", Subscribe::getCompanyId, companyId);
        } else {
            wrapper.eq("s", Subscribe::getCompanyId, dto.getCompanyId());
        }

        wrapper.orderByDesc("s", Subscribe::getId);
        Page<SubscribeVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        return page;
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @Override
    public SubscribeVo detail(Long id) {
        if (ObjectUtils.isEmpty(id)) {
            throw new ServiceException("参数异常");
        }
        Subscribe subscribe = this.getById(id);
        if (ObjectUtils.isEmpty(subscribe)) {
            throw new ServiceException("数据不存在");
        }
        SubscribeVo subscribeVo = BeanUtil.copyProperties(subscribe, SubscribeVo.class);

        //处理申购产品
        List<SubscribeDetail> subscribeDetailList = subscribeDetailService.list(
                Wrappers.<SubscribeDetail>query().lambda()
                        .eq(SubscribeDetail::getSubscribeId, id));
        List<SubscribeDetailVo> subscribeDetailVos = BeanUtil.copyToList(subscribeDetailList, SubscribeDetailVo.class);
        if (CollectionUtils.isNotEmpty(subscribeDetailList)) {
            //根据申购businessId取出所有产品
            List<Long> productIds = subscribeDetailList.stream().map(SubscribeDetail::getProductId).collect(Collectors.toList());
            List<ProductInfoVo> productInfoVos = productInfoService.getListByProductIds(productIds);
            Map<Long, List<ProductInfoVo>> productMap = productInfoVos.stream().collect(Collectors.groupingBy(ProductInfoVo::getId));
            for (SubscribeDetailVo s : subscribeDetailVos) {
                if (MapUtils.isNotEmpty(productMap)) {
                    ProductInfoVo p = productMap.get(s.getProductId()).get(0);
                    s.setProductCategory(p.getClassifyName());
                    s.setProductCode(p.getCustomCode());
                    s.setProductUnit(p.getUnit());
                    s.setProductType(p.getType());
                    s.setProductName(p.getName());
                    s.setProductDefinition(p.getDefinition());

                    s.setProductLength(p.getLength());
                    s.setProductWidth(p.getWidth());
                    s.setProductHeight(p.getHeight());
                }
            }
        }
        subscribeVo.setSubscribeDetailList(subscribeDetailVos);
        return subscribeVo;
    }

//    @Override
//    public Subscribe detailByWdly(Long id) {
//        Subscribe subscribe = detail(id);
//        //赋值维多利亚扩展收货仓库名
//        String victoriatouristJson = subscribe.getVictoriatouristJson();
//        if (ObjectUtils.isNotEmpty(victoriatouristJson)) {
//            JSONObject json = JSONObject.parseObject(victoriatouristJson);
//            Long receiptWarehouseId = json.getLong("receiptWarehouseId");
//            Warehouse warehouse = warehouseService.getById(receiptWarehouseId);
//            if (ObjectUtils.isNotEmpty(victoriatouristJson)) {
//                json.put("receiptWarehouseName", warehouse.getName());
//                subscribe.setVictoriatouristJson(JSONObject.toJSONString(json,JSONWriter.Feature.WriteLongAsString));
//            }
//        }
//        return subscribe;
//    }

    @DSTransactional
    @Override
    public void add(SubscribeDto subscribe) {
        SubscribeService subscribeService = SpringUtil.getBean(SubscribeService.class);
        SubscribeDetailService subscribeDetailService = SpringUtil.getBean(SubscribeDetailService.class);
        subscribe.setCode(codingRuleService.createCode(CodingRuleEnum.SUBSCRIBE.getKey(), null));
        subscribeService.save(subscribe);
        List<SubscribeDetail> SubscribeDetails = subscribe.getSubscribeDetailList();
        if (CollectionUtils.isNotEmpty(SubscribeDetails)) {
            for (SubscribeDetail s : SubscribeDetails) {
                s.setSubscribeId(subscribe.getId());
            }
            subscribeDetailService.saveBatch(subscribe.getSubscribeDetailList());
        }
    }

    /**
     * 编辑
     *
     * @param subscribeDto
     */
    @DSTransactional
    @Override
    public void edit(SubscribeDto subscribeDto) {
        this.updateById(subscribeDto);
    }

    @Override
    public void delete(Long id) {
        this.removeById(id);
    }

    @Override
    public List<SysDept> getDepts(SubscribeDetailSelectDto subscribeDetailDto) {
        List<Long> deptIds = new ArrayList<>();
        List<SubscribeDetail> list;
        String status = subscribeDetailDto.getStatus();
        if(ObjectUtils.isEmpty(status)){
            list = subscribeDetailService.list();
        } else {
            String[] split = status.split(",");
            list = subscribeDetailService.list(q -> q.in(SubscribeDetail::getStatus, split));
        }
        if (ObjectUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<Long> ids = list.stream().map(SubscribeDetail::getProductId).collect(Collectors.toList());
        List<ProductInfo> list1 = productInfoService.listByIds(ids);
//        for (ProductInfo productInfo : list1) {
//            String victoriatouristJson = productInfo.getVictoriatouristJson();
//            JSONObject json = ObjectUtils.isNotEmpty(victoriatouristJson) ? JSONObject.parseObject(victoriatouristJson) : new JSONObject();
//            Long deptId = json.getLong("deptId");
//            deptIds.add(deptId);
//        }
        if (ObjectUtils.isEmpty(deptIds)) {
            return new ArrayList<>();
        }
        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
        List<SysDept> sysDepts = deptService.listByIds(deptIds);
        DynamicDataSourceContextHolder.poll();
        return sysDepts;
    }

    @Override
    public DecisionAidVo decisionAid(DecisionAidDto dto) {
        DecisionAidVo decisionAidVo = new DecisionAidVo();

        Long supplyId = dto.getSupplyId();
        if (supplyId != null) {
            List<Purchase> purchaseList = purchaseService.list(q -> q.eq(Purchase::getSupplyId, supplyId)
                    .orderByDesc(BaseIdPo::getId).last("limit 3"));
            decisionAidVo.setPurchaseList(purchaseList);
        }

        // 产品价格
        List<Long> productIdList = dto.getProductIdList();
        if (ObjectUtil.isNotEmpty(productIdList)) {

            Map<Long, List<PurchaseDetail>> map = purchaseDetailService.mapKGroup(PurchaseDetail::getBussinessId, q -> q
                    .select(PurchaseDetail::getBussinessId, PurchaseDetail::getPrice)
                    .in(PurchaseDetail::getBussinessId, productIdList)
                    .orderByDesc(BaseIdPo::getId)
            );

            List<DecisionAidVo.ProductPrice> productPriceList = new ArrayList<>();

            for (Long productId : productIdList) {
                List<PurchaseDetail> contractProductList = map.get(productId);
                DecisionAidVo.ProductPrice productPrice = new DecisionAidVo.ProductPrice();
                productPrice.setId(productId);
                if (ObjectUtil.isNotEmpty(contractProductList)) {
                    productPrice.setLastPrice(contractProductList.get(0).getPrice());
                    productPrice.setMaxPrice(contractProductList.stream().map(PurchaseDetail::getPrice).max(BigDecimal::compareTo).get());
                    productPrice.setMinPrice(contractProductList.stream().map(PurchaseDetail::getPrice).min(BigDecimal::compareTo).get());
                } else {
                    productPrice.setLastPrice(BigDecimal.ZERO);
                    productPrice.setMaxPrice(BigDecimal.ZERO);
                    productPrice.setMinPrice(BigDecimal.ZERO);
                }
                productPriceList.add(productPrice);

            }

            productInfoService.attributeAssign(productPriceList, DecisionAidVo.ProductPrice::getId, (item, product) -> {
                item.setName(product.getName());
            });

            decisionAidVo.setProductPriceList(productPriceList);
        } else {
            decisionAidVo.setProductPriceList(Collections.emptyList());
        }

        return decisionAidVo;
    }

}
