package cn.iocoder.yudao.module.crm.service.crmbusiness;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.crm.controller.admin.crmbusiness.vo.CrmBusinessPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.crmbusiness.vo.CrmBusinessRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.crmbusiness.vo.CrmBusinessSaveReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.crmbusiness.vo.CrmBusinessTransferVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.crmbusiness.CrmBusinessDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.crmbusiness.CrmBusinessProductDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.crmrecord.CrmRecordDO;
import cn.iocoder.yudao.module.crm.dal.mysql.crmbusiness.CrmBusinessMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmbusiness.CrmBusinessProductMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmrecord.CrmRecordMapper;
import cn.iocoder.yudao.module.crm.service.crmoperatelog.CrmOperatelogService;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
import cn.iocoder.yudao.module.hrm.enums.TypesEnum;
import cn.iocoder.yudao.module.product.api.storeproductattrvalue.StoreProductAttrValueApi;
import cn.iocoder.yudao.module.product.api.storeproductattrvalue.dto.StoreProductAttrValueApiDTO;
import cn.iocoder.yudao.module.product.api.storeproductattrvalue.vo.StoreProductAttrValueApiVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS;


/**
 * 商机 Service 实现类
 *
 * @author yshop
 */
@Service
@Validated
public class CrmBusinessServiceImpl implements CrmBusinessService {

    @Resource
    private CrmBusinessMapper businessMapper;
    @Resource
    private CrmBusinessProductMapper businessProductMapper;
    @Resource
    private StoreProductAttrValueApi storeProductAttrValueApi;
    @Resource
    private CrmCustomerMapper customerMapper;
    @Resource
    private CrmRecordMapper crmRecordMapper;
    @Resource
    private UserLiveTreeService userLiveTreeService;
    @Resource
    private CrmOperatelogService crmOperatelogService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createBusiness(CrmBusinessSaveReqVO createReqVO) {
        // 插入
        CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class);
        business.setOwnerUserId(SecurityFrameworkUtils.getLoginUserId());
        businessMapper.insert(business);

        // 插入子表
        createBusinessProductList(business.getId(), createReqVO.getBusinessProducts());
        // 返回
        return business.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBusiness(CrmBusinessSaveReqVO updateReqVO) {
        // 校验存在
        validateBusinessExists(updateReqVO.getId());
        // 更新
        CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class);
        businessMapper.updateById(updateObj);

        // 更新子表
        updateBusinessProductList(updateReqVO.getId(), updateReqVO.getBusinessProducts());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBusiness(Long id) {
        // 校验存在
        validateBusinessExists(id);
        // 删除
        businessMapper.deleteById(id);

        //删除记录
        crmRecordMapper.delete(new LambdaQueryWrapper<CrmRecordDO>()
                .eq(CrmRecordDO::getTypes, TypesEnum.BUSINESS.getValue())
                .eq(CrmRecordDO::getTypesId, id));

        // 删除子表
        deleteBusinessProductByBusinessId(id);
    }

    private void validateBusinessExists(Long id) {
        if (businessMapper.selectById(id) == null) {
            throw exception(BUSINESS_NOT_EXISTS);
        }
    }

    @Override
    public CrmBusinessRespVO getBusiness(Long id) {
        CrmBusinessDO businessDO = businessMapper.selectById(id);
        CrmBusinessRespVO businessRespVO = BeanUtils.toBean(businessDO, CrmBusinessRespVO.class);
        CrmCustomerDO customerDO = customerMapper.selectById(businessDO.getCustomerId());
        businessRespVO.setCustomerName(customerDO.getName());
        return businessRespVO;
    }

    @Override
    public PageResult<CrmBusinessRespVO> getBusinessPage(CrmBusinessPageReqVO pageReqVO) {
        List<Long> ids = new ArrayList<>();
        Long adminId = SecurityFrameworkUtils.getLoginUserId();
        if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
            ids.add(adminId);
        } else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
            ids = userLiveTreeService.getItemIdsByUserId(adminId);
        }
        if (CollUtil.isEmpty(ids)) {
            return PageResult.empty();
        }
        IPage mpPage = MyBatisUtils.buildPage(pageReqVO);
        IPage<CrmBusinessRespVO> page = businessMapper.selectPageList(mpPage, pageReqVO, ids);
        return new PageResult<>(page.getRecords(), page.getTotal());
    }

    // ==================== 子表（商机产品关联） ====================

    @Override
    public List<CrmBusinessProductDO> getBusinessProductListByBusinessId(Long businessId) {
        List<CrmBusinessProductDO> businessProductDOS = businessProductMapper.selectListByBusinessId(businessId);
        List<StoreProductAttrValueApiVO> storeProductAttrValueList = new ArrayList<>();
        if (CollUtil.isNotEmpty(businessProductDOS)) {
            List<Long> productIds = businessProductDOS.stream().map(CrmBusinessProductDO::getProductId).collect(Collectors.toList());
            List<String> productAttrUnique = businessProductDOS.stream().map(CrmBusinessProductDO::getProductAttrUnique).collect(Collectors.toList());
            storeProductAttrValueList = storeProductAttrValueApi.getStoreProductAttrValueList(new StoreProductAttrValueApiDTO()
                    .setProductIds(productIds)
                    .setUniques(productAttrUnique)).getCheckedData();
        }
        Map<String, List<StoreProductAttrValueApiVO>> map = storeProductAttrValueList.stream().collect(Collectors.groupingBy(a -> a.getProductId() + "_" + a.getUnique()));

        for (CrmBusinessProductDO businessProductDO : businessProductDOS) {
            List<StoreProductAttrValueApiVO> storeProductAttrValueApiVOS = map.get(businessProductDO.getProductId() + "_" + businessProductDO.getProductAttrUnique());
            if (CollUtil.isNotEmpty(storeProductAttrValueApiVOS)) {
                businessProductDO.setSku(storeProductAttrValueApiVOS.get(0).getSku());
            }
        }
        return businessProductDOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transfer(CrmBusinessTransferVO transferVO) {
        //客户
        List<CrmBusinessDO> crmBusinessDOS = businessMapper.selectBatchIds(transferVO.getBusinessIds());
        if (crmBusinessDOS == null || crmBusinessDOS.isEmpty()) {
            throw exception(new ErrorCode(202409091, "商机信息不存在"));
        }

        int adminCount = transferVO.getOwnerAdminIds().size();
        int i = 0;
        List<CrmBusinessDO> businessUpdateList = new ArrayList<>();
        for (CrmBusinessDO businessDO : crmBusinessDOS) {
            Long adminId;
            if (ShopCommonEnum.AVG_1.getValue().equals(transferVO.getAverageType())) {
                //平均分配
                adminId = transferVO.getOwnerAdminIds().get(i);
                if (i == (adminCount - 1)) {
                    i = 0;
                } else {
                    i++;
                }
            } else {
                //随机分配
                Random random = new Random();
                int num = random.nextInt(adminCount);
                adminId = transferVO.getOwnerAdminIds().get(num);
            }
            businessDO.setOwnerUserId(adminId);
            businessUpdateList.add(businessDO);
            //处理日志
            crmOperatelogService.createLog("转移商机", businessDO.getCustomerId(), 0L, 0L);
        }
        if (CollUtil.isNotEmpty(businessUpdateList)) {
            businessMapper.updateBatch(businessUpdateList);
        }
    }

    @Override
    public void updateIsEnd(Long id, Integer isEnd) {
        CrmBusinessDO businessDO = new CrmBusinessDO();
        businessDO.setId(id);
        businessDO.setIsEnd(isEnd);
        businessMapper.updateById(businessDO);
    }

    private void createBusinessProductList(Long businessId, List<CrmBusinessProductDO> list) {
        list.forEach(o -> o.setBusinessId(businessId));
        businessProductMapper.insertBatch(list);
    }

    private void updateBusinessProductList(Long businessId, List<CrmBusinessProductDO> list) {
        deleteBusinessProductByBusinessId(businessId);
        list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createBusinessProductList(businessId, list);
    }

    private void deleteBusinessProductByBusinessId(Long businessId) {
        businessProductMapper.deleteByBusinessId(businessId);
    }

}
