package co.yixiang.yshop.module.product.service.shippingtemplates;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.module.product.dal.dataobject.shippingtemplatesfree.ShippingTemplatesFreeDO;
import co.yixiang.yshop.module.product.dal.dataobject.shippingtemplatesregion.ShippingTemplatesRegionDO;
import co.yixiang.yshop.module.product.dal.dataobject.storeproduct.StoreProductDO;
import co.yixiang.yshop.module.product.dal.mysql.storeproduct.StoreProductMapper;
import co.yixiang.yshop.module.product.service.shippingtemplates.dto.*;
import co.yixiang.yshop.module.product.service.shippingtemplatesfree.ShippingTemplatesFreeService;
import co.yixiang.yshop.module.product.service.shippingtemplatesregion.ShippingTemplatesRegionService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.util.*;
import co.yixiang.yshop.module.product.controller.admin.shippingtemplates.vo.*;
import co.yixiang.yshop.module.product.dal.dataobject.shippingtemplates.ShippingTemplatesDO;
import co.yixiang.yshop.framework.common.pojo.PageResult;

import co.yixiang.yshop.module.product.convert.shippingtemplates.ShippingTemplatesConvert;
import co.yixiang.yshop.module.product.dal.mysql.shippingtemplates.ShippingTemplatesMapper;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.product.enums.ErrorCodeConstants.*;

/**
 * 运费模板 Service 实现类
 *
 * @author yshop
 */
@Service
@Validated
public class ShippingTemplatesServiceImpl extends ServiceImpl<ShippingTemplatesMapper, ShippingTemplatesDO> implements ShippingTemplatesService {

    @Resource
    private ShippingTemplatesMapper shippingTemplatesMapper;
    @Resource
    private ShippingTemplatesRegionService shippingTemplatesRegionService;
    @Resource
    private ShippingTemplatesFreeService shippingTemplatesFreeService;

    @Override
    public Integer createShippingTemplates(ShippingTemplatesCreateReqVO createReqVO) {
        // 插入
        ShippingTemplatesDO shippingTemplates = ShippingTemplatesConvert.INSTANCE.convert(createReqVO);
        shippingTemplatesMapper.insert(shippingTemplates);
        // 返回
        return shippingTemplates.getId();
    }

    @Override
    public void updateShippingTemplates(ShippingTemplatesUpdateReqVO updateReqVO) {
        // 校验存在
        validateShippingTemplatesExists(updateReqVO.getId());
        // 更新
        ShippingTemplatesDO updateObj = ShippingTemplatesConvert.INSTANCE.convert(updateReqVO);
        shippingTemplatesMapper.updateById(updateObj);
    }

    @Override
    public void deleteShippingTemplates(Integer id) {
        // 校验存在
        validateShippingTemplatesExists(id);
        // 删除
        shippingTemplatesMapper.deleteById(id);
    }

    private void validateShippingTemplatesExists(Integer id) {
        if (shippingTemplatesMapper.selectById(id) == null) {
            throw exception(SHIPPING_TEMPLATES_NOT_EXISTS);
        }
    }

    @Override
    public ShippingTemplatesDO getShippingTemplates(Integer id) {
        return shippingTemplatesMapper.selectById(id);
    }

    @Override
    public List<ShippingTemplatesDO> getShippingTemplatesList(Collection<Integer> ids) {
        return shippingTemplatesMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ShippingTemplatesDO> getShippingTemplatesPage(ShippingTemplatesPageReqVO pageReqVO) {
        return shippingTemplatesMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ShippingTemplatesDO> getShippingTemplatesList(ShippingTemplatesExportReqVO exportReqVO) {
        return shippingTemplatesMapper.selectList(exportReqVO);
    }

    /**
     * 新增与更新模板
     * @param id 模板id
     * @param shippingTemplatesDto ShippingTemplatesDto
     */
    @Override
    public void addAndUpdate(Integer id, ShippingTemplatesDto shippingTemplatesDto) {
        if(ShopCommonEnum.ENABLE_1.getValue().equals(shippingTemplatesDto.getAppoint())
                && shippingTemplatesDto.getAppointInfo().isEmpty()){
            throw exception(SHIPPING_TEMPLATES_FREE_NEED);
        }
        ShippingTemplatesDO shippingTemplates = new ShippingTemplatesDO();
        BeanUtil.copyProperties(shippingTemplatesDto,shippingTemplates);
        shippingTemplates.setRegionInfo(JSON.toJSONString(shippingTemplatesDto.getRegionInfo()));
        shippingTemplates.setAppointInfo(JSON.toJSONString(shippingTemplatesDto.getAppointInfo()));
        if(id != null && id > 0){
            shippingTemplates.setId(id);
            this.updateById(shippingTemplates);
        }else{
            this.save(shippingTemplates);
        }

        this.saveRegion(shippingTemplatesDto,shippingTemplates.getId());
        this.saveFreeReigion(shippingTemplatesDto,shippingTemplates.getId());
    }

    /**
     * 保存模板设置的区域价格
     * @param yxShippingTemplates ShippingTemplatesDTO
     * @param tempId 运费模板id
     */
    private void saveRegion(ShippingTemplatesDto yxShippingTemplates,Integer tempId){
        Long count = shippingTemplatesRegionService.count(Wrappers
                .<ShippingTemplatesRegionDO>lambdaQuery()
                .eq(ShippingTemplatesRegionDO::getTempId,tempId));
        if(count > 0) {
            shippingTemplatesRegionService.remove(Wrappers
                    .<ShippingTemplatesRegionDO>lambdaQuery()
                    .eq(ShippingTemplatesRegionDO::getTempId,tempId));
        }

        List<ShippingTemplatesRegionDO> shippingTemplatesRegions = new ArrayList<>();


        List<RegionInfoDto> regionInfo = yxShippingTemplates.getRegionInfo();


        for (RegionInfoDto regionInfoDto : regionInfo){
            String uni = IdUtil.simpleUUID();
            if(regionInfoDto.getRegion() != null && !regionInfoDto.getRegion().isEmpty()){
                for (RegionDto regionDto : regionInfoDto.getRegion()){
                    if(regionDto.getChildren() != null && !regionDto.getChildren().isEmpty()){
                        for (RegionChildrenDto childrenDtp : regionDto.getChildren()){
                            ShippingTemplatesRegionDO shippingTemplatesRegion = ShippingTemplatesRegionDO.builder()
                                    .tempId(tempId)
                                    .first(new BigDecimal(regionInfoDto.getFirst()))
                                    .firstPrice(new BigDecimal(regionInfoDto.getPrice()))
                                    .continues(new BigDecimal(regionInfoDto.get_continue()))
                                    .continuePrice(new BigDecimal(regionInfoDto.getContinue_price()))
                                    .type(yxShippingTemplates.getType())
                                    .uniqid(uni)
                                    .provinceId(Integer.valueOf(regionDto.getCity_id()))
                                    .cityId(Integer.valueOf(childrenDtp.getCity_id()))
                                    .build();
                            shippingTemplatesRegions.add(shippingTemplatesRegion);
                        }
                    }else{
                        ShippingTemplatesRegionDO shippingTemplatesRegion = ShippingTemplatesRegionDO.builder()
                                .tempId(tempId)
                                .first(new BigDecimal(regionInfoDto.getFirst()))
                                .firstPrice(new BigDecimal(regionInfoDto.getPrice()))
                                .continues(new BigDecimal(regionInfoDto.get_continue()))
                                .continuePrice(new BigDecimal(regionInfoDto.getContinue_price()))
                                .type(yxShippingTemplates.getType())
                                .uniqid(uni)
                                .provinceId(Integer.valueOf(regionDto.getCity_id()))
                                .build();
                        shippingTemplatesRegions.add(shippingTemplatesRegion);
                    }
                }
            }
        }

        if(shippingTemplatesRegions.isEmpty()) {
            throw exception(SHIPPING_TEMPLATES_REGION_NOT_EXISTS);
        }

        shippingTemplatesRegionService.saveBatch(shippingTemplatesRegions);

    }

    /**
     * 保存包邮区域
     * @param yxShippingTemplates ShippingTemplatesDto
     * @param tempId 模板id
     */
    private void saveFreeReigion(ShippingTemplatesDto yxShippingTemplates,Integer tempId){

        if(yxShippingTemplates.getAppointInfo() == null
                || yxShippingTemplates.getAppointInfo().isEmpty()){
            return;
        }

        Long count = shippingTemplatesFreeService.count(Wrappers
                .<ShippingTemplatesFreeDO>lambdaQuery()
                .eq(ShippingTemplatesFreeDO::getTempId,tempId));
        if(count > 0) {
            shippingTemplatesFreeService.remove(Wrappers
                    .<ShippingTemplatesFreeDO>lambdaQuery()
                    .eq(ShippingTemplatesFreeDO::getTempId,tempId));
        }

        List<ShippingTemplatesFreeDO> shippingTemplatesFrees = new ArrayList<>();


        List<AppointInfoDto> appointInfo = yxShippingTemplates.getAppointInfo();
        for (AppointInfoDto appointInfoDto : appointInfo){
            String uni = IdUtil.simpleUUID();

            if(appointInfoDto.getPlace() != null && !appointInfoDto.getPlace().isEmpty()){
                for (RegionDto regionDto : appointInfoDto.getPlace()){
                    if(regionDto.getChildren() != null && !regionDto.getChildren().isEmpty()){
                        for (RegionChildrenDto childrenDto : regionDto.getChildren()){
                            ShippingTemplatesFreeDO shippingTemplatesFree = ShippingTemplatesFreeDO.builder()
                                    .tempId(tempId)
                                    .number(new BigDecimal(appointInfoDto.getA_num()))
                                    .price(new BigDecimal(appointInfoDto.getA_price()))
                                    .type(yxShippingTemplates.getType())
                                    .uniqid(uni)
                                    .provinceId(Integer.valueOf(regionDto.getCity_id()))
                                    .cityId(Integer.valueOf(childrenDto.getCity_id()))
                                    .build();
                            shippingTemplatesFrees.add(shippingTemplatesFree);
                        }
                    }
                }
            }
        }


        if(shippingTemplatesFrees.isEmpty()) {
            throw exception(SHIPPING_TEMPLATES_FREE_NOT_EXISTS);
        }

        shippingTemplatesFreeService.saveBatch(shippingTemplatesFrees);


    }


}
