package com.ruoyi.frequency.works.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.ruoyi.code.PublicCommon;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil;
import com.ruoyi.controller.req.DrawingDetailsPageReq;
import com.ruoyi.controller.req.WorksPageReq;
import com.ruoyi.controller.req.WorksReleaseReq;
import com.ruoyi.controller.resp.OrderWorksPricePage;
import com.ruoyi.controller.resp.WorksDetailResp;
import com.ruoyi.controller.resp.WorksPageResp;
import com.ruoyi.enums.user.UserEnums;
import com.ruoyi.frequency.customer.service.UserService;
import com.ruoyi.frequency.enterprise.entity.Enterprise;
import com.ruoyi.frequency.enterprise.service.EnterpriseService;
import com.ruoyi.frequency.order.entity.Order;
import com.ruoyi.frequency.order.service.OrderService;
import com.ruoyi.frequency.works.entity.Works;
import com.ruoyi.frequency.works.mapper.WorksMapper;
import com.ruoyi.frequency.works.model.result.WorksCount;
import com.ruoyi.frequency.works.service.WorksService;
import com.ruoyi.frequency.workspanorama.entity.WorksPanorama;
import com.ruoyi.frequency.workspanorama.service.WorksPanoramaService;
import com.ruoyi.frequency.worksshield.service.WorksShieldService;
import com.ruoyi.frequency.workstype.service.WorksTypeService;
import com.ruoyi.post.frequency.post.mapper.PostMapper;
import com.ruoyi.response.ResponseData;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.utils.SnowIdUtils;
import com.ruoyi.vo.BodyIdReq;
import com.ruoyi.vo.UserInfo;
import com.ruoyi.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 作品Service业务层处理
 *
 * @author zj
 * @date 2023-09-22
 */
@Service
public class WorksServiceImpl extends ServiceImpl<WorksMapper, Works> implements WorksService {
    @Autowired
    private WorksMapper worksMapper;

    /**
     * 查询作品
     *
     * @param id 作品主键
     * @return 作品
     */
    @Override
    public Works selectWorksById(Long id) {

        Works works = worksMapper.selectWorksById(id);

        if (works != null) {
            Set<UserVo> userVoSet = new HashSet<>();
            userVoSet.add(new UserVo(works.getUserType(), works.getStoreId()));

            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, null);

            //查询3D图
            List<WorksPanorama> worksPanoramaList = worksPanoramaService.list(new QueryWrapper<WorksPanorama>().lambda().eq(WorksPanorama::getWorksId, id).orderByDesc(WorksPanorama::getCreateTime));

            works.setStoreInfo(userMap.get(new UserVo(works.getUserType(), works.getStoreId())));
            works.setWorksPanoramaList(worksPanoramaList);
        }

        return works;
    }

    @Autowired
    private EnterpriseService enterpriseService;

    /**
     * 查询作品列表
     *
     * @param works 作品
     * @return 作品
     */
    @Override
    public List<Works> selectWorksList(Works works) {


        List<Works> worksList = worksList(works);

        if (!worksList.isEmpty()) {

            Set<UserVo> userVoSet = worksList.stream().map(s -> new UserVo(s.getUserType(), s.getStoreId())).collect(Collectors.toSet());
            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, null);

            //作品ids
            List<Long> worksIds = worksList.stream().map(Works::getId).collect(Collectors.toList());
            //查询3D图
            List<WorksPanorama> worksPanoramaList = worksPanoramaService.list(new QueryWrapper<WorksPanorama>().lambda().in(WorksPanorama::getWorksId, worksIds).orderByDesc(WorksPanorama::getCreateTime));

            Map<Long, List<WorksPanorama>> map = worksPanoramaList.stream().collect(Collectors.groupingBy(WorksPanorama::getWorksId));

            worksList.stream().forEach(s -> {
                s.setStoreInfo(userMap.get(new UserVo(s.getUserType(), s.getStoreId())));
                s.setWorksPanoramaList(map.get(s.getId()));
            });
        }

        return worksList;
    }

    private List<Works> worksList(Works works) {
        if (SecurityUtils.hasRoleKey("enterprise")) {
            Enterprise enterprise = enterpriseService.getOne(new QueryWrapper<Enterprise>().lambda()
                    .ne(Enterprise::getDelFlag, PublicCommon.删除)
                    .eq(Enterprise::getSysUserId, SecurityUtils.getUserId()));
            if (enterprise == null) {
                return null;
            }
            works.setEnterpriseId(enterprise.getId());
        }
        startPage();
        List<Works> worksList = worksMapper.selectWorksList(works);
        return worksList;
    }

    protected void startPage()
    {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
        {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            Boolean reasonable = pageDomain.getReasonable();
            PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
        }
    }

    @Override
    public WorksCount statistics(Works works) {
        List<Works> worksList = worksList(works);
        List<Long> workIdList = worksList.stream().map(x -> x.getId()).collect(Collectors.toList());
        workIdList.add(-1L);
        return worksMapper.statistics(workIdList);
    }

    /**
     * 新增作品
     *
     * @param works 作品
     * @return 结果
     */
    @Override
    public int insertWorks(Works works) {
        if (SecurityUtils.hasRoleKey("enterprise")) {
            Enterprise enterprise = enterpriseService.getOne(new QueryWrapper<Enterprise>().lambda()
                    .ne(Enterprise::getDelFlag, PublicCommon.删除)
                    .eq(Enterprise::getSysUserId, SecurityUtils.getUserId()));
            works.setStoreId(enterprise.getId());

            works.setUserType(UserEnums.enterprise.getCode());
        } else {
            return 1;
        }

        int insert = worksMapper.insert(works);
        //关联3D图
        if (insert > 0 && works.getWorksPanoramaList() != null && !works.getWorksPanoramaList().isEmpty()) {

            List<WorksPanorama> saveList = works.getWorksPanoramaList().stream().filter(s -> ObjectUtil.isAllNotEmpty(s.getPanorama(), s.getPanoramaImage())).collect(Collectors.toList());

            if (saveList.size() > 0) {
                saveList.stream().forEach(w -> w.setWorksId(works.getId()));
                worksPanoramaService.saveBatch(saveList);
            }
        }

        return insert;
    }

    /**
     * 修改作品
     *
     * @param works 作品
     * @return 结果
     */
    @Override
    public int updateWorks(Works works) {
        works.setUpdateTime(DateUtils.getNowDate());
        int i = worksMapper.updateWorks(works);

        //删除关联 3D图
        worksPanoramaService.remove(new QueryWrapper<WorksPanorama>().lambda().eq(WorksPanorama::getWorksId, works.getId()));
        //关联3D图
        if (i > 0 && works.getWorksPanoramaList() != null && !works.getWorksPanoramaList().isEmpty()) {

            List<WorksPanorama> saveList = works.getWorksPanoramaList().stream().filter(s -> ObjectUtil.isAllNotEmpty(s.getPanorama(), s.getPanoramaImage())).collect(Collectors.toList());

            if (saveList.size() > 0) {
                saveList.stream().forEach(w -> w.setWorksId(works.getId()));
                worksPanoramaService.saveBatch(saveList);
            }
        }
        return i;
    }


    /**
     * 批量删除作品
     *
     * @param ids 需要删除的作品主键
     * @return 结果
     */
    @Override
    public int deleteWorksByIds(Long[] ids) {
        this.lambdaUpdate().set(Works::getDelFlag, PublicCommon.删除).in(Works::getId, ids).update();
        return ids.length;
    }

    /**
     * 删除作品信息
     *
     * @param id 作品主键
     * @return 结果
     */
    @Override
    public int deleteWorksById(Long id) {
        return worksMapper.deleteWorksById(id);
    }


    @Autowired
    private WorksPanoramaService worksPanoramaService;

    @Override
    public ResponseData worksRelease(WorksReleaseReq req, UserVo userVo) {

        Works works = new Works(req, userVo);

        this.save(works);

        //关联3D图
        if (req.getWorksPanoramaList() != null && !req.getWorksPanoramaList().isEmpty()) {

            List<WorksPanorama> saveList = req.getWorksPanoramaList().stream().filter(s -> ObjectUtil.isAllNotEmpty(s.getPanorama(), s.getPanoramaImage())).collect(Collectors.toList());

            if (saveList.size() > 0) {
                saveList.stream().forEach(w -> w.setWorksId(works.getId()));
                worksPanoramaService.saveBatch(saveList);
            }
        }

        return ResponseData.success(works.getId());
    }



    @Autowired
    private UserService userService;

    @Autowired
    private WorksTypeService worksTypeService;

    @Autowired
    private WorksShieldService worksShieldService;

    @Override
    public ResponseData worksPage(WorksPageReq req, UserVo userVo) {

        if (ObjectUtil.isNotEmpty(req.getTypeId()) && ObjectUtil.notEqual(UserEnums.enterprise.getCode(), req.getUserType())) {

            //根据类型id获取所有作品关联id
            List<Long> typeIdList = new ArrayList<>();

            if (req.getTypeIds() != null && req.getTypeIds().size() > 0) {
                typeIdList = req.getTypeIds();
            } else {
                //根据类型id获取三级id
                typeIdList = worksTypeService.getIdsByTypeId(req.getTypeId());
            }

            if (typeIdList.isEmpty()) {
                return ResponseData.success(new PageResult<>(new Page<>(req.getPageNo(), req.getPageSize())));
            }
            req.setTypeIds(typeIdList);
        }

        //是否是查看自己的 1 是 2 否
        if (req.getIsSelf() == 2) {

            //筛去拉黑与被拉黑用户
            List<UserVo> blockUserList = userService.blockUserList(userVo);
            req.setBlockUserList(blockUserList);

            //筛去屏蔽用户
            List<UserVo> shieldUserList = userService.shieldUserList(userVo);
            req.setShieldUserList(shieldUserList);

            //筛去屏蔽的作品
            List<Long> shieldWorksIdList = worksShieldService.shieldWorksList(userVo);
            req.setShieldWorksIdList(shieldWorksIdList);

        }

        Page<WorksPageResp> page = this.baseMapper.worksPage(new Page<>(req.getPageNo(), req.getPageSize()), req, userVo);

        if (!page.getRecords().isEmpty()) {

            Set<UserVo> userVoSet = page.getRecords().stream().map(worksPageResp -> new UserVo(worksPageResp.getUserType(), worksPageResp.getStoreId())).collect(Collectors.toSet());
            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

            //作品ids
            List<Long> worksIds = page.getRecords().stream().map(WorksPageResp::getId).collect(Collectors.toList());
            //查询3D图
            List<WorksPanorama> worksPanoramaList = worksPanoramaService.list(new QueryWrapper<WorksPanorama>().lambda().in(WorksPanorama::getWorksId, worksIds).orderByDesc(WorksPanorama::getCreateTime));

            Map<Long, List<WorksPanorama>> map = worksPanoramaList.stream().collect(Collectors.groupingBy(WorksPanorama::getWorksId));

            page.getRecords().stream().forEach(worksPageResp -> {
                worksPageResp.setUserInfo(userMap.get(new UserVo(worksPageResp.getUserType(), worksPageResp.getStoreId())));
                worksPageResp.setWorksPanoramaList(map.get(worksPageResp.getId()));
            });
        }


        return ResponseData.success(new PageResult<>(page));
    }

    @Override
    public ResponseData worksDetail(Long id, Integer isAddBrowseNum, UserVo userVo) {

        WorksDetailResp worksDetailResp = this.baseMapper.worksDetail(id, userVo);

        if (worksDetailResp != null) {

            Set<UserVo> userVoSet = new HashSet<>();
            userVoSet.add(new UserVo(worksDetailResp.getUserType(), worksDetailResp.getStoreId()));

            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

            //查询3D图
            List<WorksPanorama> worksPanoramaList = worksPanoramaService.list(new QueryWrapper<WorksPanorama>().lambda().eq(WorksPanorama::getWorksId, id).orderByDesc(WorksPanorama::getCreateTime));

            worksDetailResp.setUserInfo(userMap.get(new UserVo(worksDetailResp.getUserType(), worksDetailResp.getStoreId())));
            worksDetailResp.setWorksPanoramaList(worksPanoramaList);

            //是否增加浏览数 1不增加 2 加
            if (ObjectUtil.equal(2, isAddBrowseNum)) {
                //增加浏览数
                this.baseMapper.updateWorks(new Works().setId(id).setBrowseNum(1));

                postMapper.updateBrowseRecord(SnowIdUtils.uniqueLong(), 1, new Date(), id, userVo);
            }

            //企业查询企业信息
            if (ObjectUtil.equal(UserEnums.enterprise.getCode(), worksDetailResp.getUserType())) {
                Enterprise byId = enterpriseService.getById(worksDetailResp.getStoreId());
                worksDetailResp.setEnterprise(byId);
            }

            //作品是否是我的订单里产生的(设计师可隐藏该作品)
            if (worksDetailResp.getOrderId() != null) {
                Order order = orderService.getById(worksDetailResp.getOrderId());
                if (order.getCustomerId().equals(userVo.getUserId()) && ObjectUtil.equal(UserEnums.customer.getCode(), userVo.getUserType())) {
                    worksDetailResp.setIsCustomerSelf(2);
                } else {
                    worksDetailResp.setIsCustomerSelf(1);
                }
            }
        }
        return ResponseData.success(worksDetailResp);
    }

    @Autowired
    private OrderService orderService;

    @Autowired
    private PostMapper postMapper;

    @Override
    public Map<Long, Works> selectWorksMap(Set<Long> worksIds) {
        List<Works> works = this.list(new QueryWrapper<Works>().lambda().in(Works::getId, worksIds));

        return works.stream().collect(Collectors.toMap(Works::getId, Function.identity()));
    }

    @Override
    public ResponseData<OrderWorksPricePage> drawingDetailsPage(DrawingDetailsPageReq req, UserVo userVo) {

        Page<OrderWorksPricePage> page = worksMapper.orderWorksPriceList(new Page<>(req.getPageNo(), req.getPageSize()), req.getOrderId());

        return ResponseData.success(new PageResult<>(page));
    }

    @Override
    public ResponseData hideWork(BodyIdReq req, UserVo userVo) {
        Works works = baseMapper.selectById(req.getId());
        if (works.getOrderId() == null) {
            return ResponseData.error("您无权隐藏该作品");
        }
        Order order = orderService.getById(works.getOrderId());
        if (!order.getCustomerId().equals(userVo.getUserId()) || !ObjectUtil.equal(UserEnums.customer.getCode(), userVo.getUserType())) {
            return ResponseData.error("您无权隐藏该作品");
        }
        works.setIsHide(2);
        updateById(works);
        return ResponseData.success();
    }

    @Autowired
    private ISysDictDataService iSysDictDataService;

    @Override
    public ResponseData<List<SysDictData>> getHaveWorkCategory(WorksPageReq req) {
        SysDictData sysDictData = new SysDictData();
        sysDictData.setDictType("ENTERPRISES_WORK_TYPE");
        sysDictData.setStatus("0");
        List<SysDictData> list = iSysDictDataService.selectDictDataList(sysDictData);

        if (CollectionUtil.isEmpty(list)) {
            return ResponseData.success(new ArrayList<>());
        }

        // 过滤只要有作品的分类信息
        List<Long> dictCodeList = list.stream().map(SysDictData::getDictCode).collect(Collectors.toList());

        List<Works> worksList = worksMapper.selectList(new LambdaQueryWrapper<Works>()
                .eq(Works::getDelFlag, PublicCommon.启用)
                .eq(Works::getStoreId, req.getUserId())
                .eq(Works::getUserType, req.getUserType())
                .in(Works::getWorksTypeId, dictCodeList));
        if (CollectionUtil.isEmpty(worksList)) {
            return ResponseData.success(new ArrayList<>());
        }

        List<Long> workTypeIdList = worksList.stream().map(Works::getWorksTypeId).collect(Collectors.toList());

        return ResponseData.success(list.stream().filter(s -> workTypeIdList.contains(s.getDictCode()))
                .collect(Collectors.toList()));
    }
}
