package com.fs.his.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.common.exception.ServiceException;
import com.fs.common.utils.bean.BeanUtils;
import com.fs.course.mapper.FsUserCourseVideoMapper;
import com.fs.his.domain.FsPromotionalActive;
import com.fs.his.domain.FsPromotionalActiveResource;
import com.fs.his.dto.FsPromotionalActiveDTO;
import com.fs.his.mapper.*;
import com.fs.his.service.IFsPromotionalActiveService;
import com.fs.his.vo.FsGoodsVO;
import com.fs.his.vo.FsPromotionalActiveDetailVO;
import com.fs.his.vo.FsPromotionalActiveVO;
import com.fs.his.vo.OptionsVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class FsPromotionalActiveServiceImpl extends ServiceImpl<FsPromotionalActiveMapper, FsPromotionalActive> implements IFsPromotionalActiveService {

    @Resource
    private FsPromotionalActiveResourceMapper fsPromotionalActiveResourceMapper;
    @Resource
    private FsUserCourseVideoMapper fsUserCourseVideoMapper;
    @Resource
    private FsDoctorMapper fsDoctorMapper;
    @Resource
    private FsIntegralGoodsMapper fsIntegralGoodsMapper;
    @Resource
    private FsPackageMapper fsPackageMapper;

    /**
     * 添加活动
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addPromotionalActive(FsPromotionalActiveDTO param) {
        FsPromotionalActive promotionalActive = new FsPromotionalActive();
        promotionalActive.setTitle(param.getTitle());
        promotionalActive.setTheme(param.getTheme());
        promotionalActive.setContent(param.getContent());
        promotionalActive.setCreateTime(LocalDateTime.now());
        baseMapper.insert(promotionalActive);

        List<FsPromotionalActiveResource> resources = buildResourceParam(param, promotionalActive.getId());
        if (!resources.isEmpty()) {
            fsPromotionalActiveResourceMapper.insertBatch(resources);
        }
    }

    /**
     * 组装参数
     */
    private List<FsPromotionalActiveResource> buildResourceParam(FsPromotionalActiveDTO param, Long activeId) {
        List<FsPromotionalActiveResource> resources = new ArrayList<>();
        if (Objects.nonNull(param.getVideoIds()) && !param.getVideoIds().isEmpty()) {
            param.getVideoIds().forEach(videoId -> {
               FsPromotionalActiveResource resource = new FsPromotionalActiveResource();
               resource.setActiveId(activeId);
               resource.setType(1);
               resource.setResourceId(videoId);
               resource.setCreateTime(LocalDateTime.now());
               resources.add(resource);
            });
        }

        if (Objects.nonNull(param.getDoctorIds()) && !param.getDoctorIds().isEmpty()) {
            param.getDoctorIds().forEach(doctorId -> {
                FsPromotionalActiveResource resource = new FsPromotionalActiveResource();
                resource.setActiveId(activeId);
                resource.setType(2);
                resource.setResourceId(doctorId);
                resource.setCreateTime(LocalDateTime.now());
                resources.add(resource);
            });
        }

        if (Objects.nonNull(param.getPackageIds()) && !param.getPackageIds().isEmpty()) {
            param.getPackageIds().forEach(packageId -> {
                FsPromotionalActiveResource resource = new FsPromotionalActiveResource();
                resource.setActiveId(activeId);
                resource.setType(3);
                resource.setProductType(1);
                resource.setResourceId(packageId);
                resource.setCreateTime(LocalDateTime.now());
                resources.add(resource);
            });
        }

        if (Objects.nonNull(param.getGoodsIds()) && !param.getGoodsIds().isEmpty()) {
            param.getGoodsIds().forEach(goodsId -> {
                FsPromotionalActiveResource resource = new FsPromotionalActiveResource();
                resource.setActiveId(activeId);
                resource.setType(3);
                resource.setProductType(2);
                resource.setResourceId(goodsId);
                resource.setCreateTime(LocalDateTime.now());
                resources.add(resource);
            });
        }

        return resources;
    }

    /**
     * 修改活动
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void editPromotionalActive(FsPromotionalActiveDTO param) {
        if (Objects.isNull(param.getId())) {
            throw new ServiceException("活动ID不能为空");
        }

        FsPromotionalActive promotionalActive = baseMapper.selectById(param.getId());
        promotionalActive.setTitle(param.getTitle());
        promotionalActive.setTheme(param.getTheme());
        promotionalActive.setContent(param.getContent());
        promotionalActive.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(promotionalActive);

        Wrapper<FsPromotionalActiveResource> deleteWrapper = Wrappers.<FsPromotionalActiveResource>lambdaQuery()
                .eq(FsPromotionalActiveResource::getActiveId, param.getId());
        fsPromotionalActiveResourceMapper.delete(deleteWrapper);

        List<FsPromotionalActiveResource> resources = buildResourceParam(param, promotionalActive.getId());
        if (!resources.isEmpty()) {
            fsPromotionalActiveResourceMapper.insertBatch(resources);
        }
    }

    /**
     * 查询活动列表
     */
    @Override
    public List<FsPromotionalActiveVO> selectPromotionalActiveVOList(FsPromotionalActive active) {
        return baseMapper.selectPromotionalActiveVOList(active);
    }

    /**
     * 根据ID查询活动详情
     */
    @Override
    public FsPromotionalActiveVO selectPromotionalActiveVOById(Long activeId) {
        FsPromotionalActiveVO vo = baseMapper.selectPromotionalActiveVOById(activeId);

        Wrapper<FsPromotionalActiveResource> queryWrapper = Wrappers.<FsPromotionalActiveResource>lambdaQuery()
                .eq(FsPromotionalActiveResource::getActiveId, activeId);
        List<FsPromotionalActiveResource> resources = fsPromotionalActiveResourceMapper.selectList(queryWrapper);

        List<Long> videoIds = resources.stream()
                .filter(resource -> resource.getType() == 1)
                .map(FsPromotionalActiveResource::getResourceId)
                .collect(Collectors.toList());
        if (!videoIds.isEmpty()) {
            Map<String, Object> params = new HashMap<>();
            params.put("videoIds", videoIds);
            vo.setVideoList(fsUserCourseVideoMapper.getChooseCourseVideoListByMap(params));
        }

        List<Long> doctorIds = resources.stream()
                .filter(resource -> resource.getType() == 2)
                .map(FsPromotionalActiveResource::getResourceId)
                .collect(Collectors.toList());
        if (!doctorIds.isEmpty()) {
            Map<String, Object> params = new HashMap<>();
            params.put("doctorIds", doctorIds);
            vo.setDoctorList(fsDoctorMapper.getChooseDoctorListByMap(params));
        }

        List<Long> packageIds = resources.stream()
                .filter(resource -> resource.getType() == 3 && resource.getProductType() == 1)
                .map(FsPromotionalActiveResource::getResourceId)
                .collect(Collectors.toList());
        if (!packageIds.isEmpty()) {
            Map<String, Object> params = new HashMap<>();
            params.put("packageIds", packageIds);
            vo.setPackageList(fsPackageMapper.getChoosePackageListByMap(params));
        }

        List<Long> goodsIds = resources.stream()
                .filter(resource -> resource.getType() == 3 && resource.getProductType() == 2)
                .map(FsPromotionalActiveResource::getResourceId)
                .collect(Collectors.toList());
        if (!goodsIds.isEmpty()) {
            Map<String, Object> params = new HashMap<>();
            params.put("goodsIds", goodsIds);
            vo.setGoodsList(fsIntegralGoodsMapper.getChooseIntegralGoodsListByMap(params));
        }
        return vo;
    }

    /**
     * 逻辑删除
     */
    @Override
    public void logicalRemove(Long[] activeIds) {
        if (activeIds.length == 0) {
            return;
        }

        baseMapper.update(
                null,
                Wrappers.<FsPromotionalActive>lambdaUpdate()
                .set(FsPromotionalActive::getIsDel, 1)
                .set(FsPromotionalActive::getUpdateTime, LocalDateTime.now())
                .in(FsPromotionalActive::getId, Arrays.asList(activeIds))
        );
    }

    /**
     * 根据活动ID查询活动详情
     */
    @Override
    public FsPromotionalActiveDetailVO getActiveDetail(Long activeId) {
        FsPromotionalActiveVO vo = baseMapper.selectPromotionalActiveVOById(activeId);

        Wrapper<FsPromotionalActiveResource> queryWrapper = Wrappers.<FsPromotionalActiveResource>lambdaQuery()
                .eq(FsPromotionalActiveResource::getActiveId, activeId);
        List<FsPromotionalActiveResource> resources = fsPromotionalActiveResourceMapper.selectList(queryWrapper);

        FsPromotionalActiveDetailVO detailVO = new FsPromotionalActiveDetailVO();
        BeanUtils.copyProperties(vo, detailVO);

        List<Long> videoIds = resources.stream()
                .filter(resource -> resource.getType() == 1)
                .map(FsPromotionalActiveResource::getResourceId)
                .collect(Collectors.toList());
        if (!videoIds.isEmpty()) {
            detailVO.setVideoList(fsUserCourseVideoMapper.getFsUserCourseVideoAppletVOListByIds(videoIds));
        }

        List<Long> doctorIds = resources.stream()
                .filter(resource -> resource.getType() == 2)
                .map(FsPromotionalActiveResource::getResourceId)
                .collect(Collectors.toList());
        if (!doctorIds.isEmpty()) {
            detailVO.setDoctorList(fsDoctorMapper.getFsDoctorListUVOListByIds(doctorIds));
        }

        List<Long> packageIds = resources.stream()
                .filter(resource -> resource.getType() == 3 && resource.getProductType() == 1)
                .map(FsPromotionalActiveResource::getResourceId)
                .collect(Collectors.toList());

        List<Long> goodsIds = resources.stream()
                .filter(resource -> resource.getType() == 3 && resource.getProductType() == 2)
                .map(FsPromotionalActiveResource::getResourceId)
                .collect(Collectors.toList());

        List<FsGoodsVO> goodsList = Stream.concat(
                packageIds.isEmpty() ? Stream.empty() : fsPackageMapper.getFsGoodsVOListByIds(packageIds).stream(),
                goodsIds.isEmpty() ? Stream.empty() : fsIntegralGoodsMapper.getFsGoodsVOListByIds(goodsIds).stream()
        ).collect(Collectors.toList());

        detailVO.setGoodsList(goodsList);
        return detailVO;
    }

    /**
     * 获取活动选项列表
     */
    @Override
    public List<OptionsVO> getPromotionalActiveOption() {
        return baseMapper.getPromotionalActiveOption();
    }
}
