package com.yida.data.school.secondClass.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yida.data.common.core.entity.school.secondClass.EduSecondClassCourse;
import com.yida.data.common.core.entity.school.secondClass.EduSecondClassSubject;
import com.yida.data.common.core.entity.school.secondClass.EduSecondClassSubject.TopicType;
import com.yida.data.common.core.entity.school.secondClass.EduSecondClassVenue;
import com.yida.data.common.core.entity.school.secondClass.EduSecondClassVenueExhibit;
import com.yida.data.common.core.entity.school.secondClass.EduSecondClassVenueExhibitGroup;
import com.yida.data.common.core.entity.system.EduArea;
import com.yida.data.common.core.vo.NameValueVO;
import com.yida.data.common.service.CommonService;
import com.yida.data.school.secondClass.mapper.EduSecondClassSubjectMapper;
import com.yida.data.school.secondClass.mapper.EduSecondClassVenueMapper;
import com.yida.data.school.secondClass.service.EduSecondClassVenueExhibitService;
import com.yida.data.school.secondClass.service.EduSecondClassVenueService;
import com.yida.data.school.secondClass.service.EduSecondClassVenueExhibitGroupService;
import com.yida.data.school.vo.secondClass.CourseH5ContentVO;
import com.yida.data.school.vo.secondClass.CourseVO;
import com.yida.data.school.vo.secondClass.SubjectVO;
import com.yida.data.school.vo.secondClass.VenueExhibitGroupVO;
import com.yida.data.school.vo.secondClass.VenueH5ContentVO;
import com.yida.data.school.vo.secondClass.VenueVO;
import java.util.ArrayList;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.List;

/**
 * Service实现
 *
 * @author zhanghaijun
 * @date 2022-04-18 09:39:53
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class EduSecondClassVenueServiceImpl extends ServiceImpl
    <EduSecondClassVenueMapper, EduSecondClassVenue> implements EduSecondClassVenueService {

    private final EduSecondClassVenueExhibitGroupService eduSecondClassVenueExhibitGroupService;
    private final EduSecondClassVenueExhibitService eduSecondClassVenueExhibitService;
    private final EduSecondClassSubjectMapper eduSecondClassSubjectMapper;

    private final CommonService commonService;

    private static ExecutorService VENUE_VISIT = new ThreadPoolExecutor(1, 1,
        0L, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>(), ThreadUtil.newNamedThreadFactory("second-class-venue-visit", false));

    @Override
    @Transactional(readOnly = true)
    public IPage<VenueVO> listVenuePage(Long deptId, String name, Integer pageNum, Integer pageSize) {
        Page page = Page.of(pageNum, pageSize);
        List<VenueVO> venueList = baseMapper.listVenue(page, deptId, name, null, null, null, null, null);
        // 填充地址
        for (VenueVO venue : venueList) {
            StringBuilder address = new StringBuilder();
            EduArea village = commonService.getArea(venue.getVillageId());
            EduArea city = commonService.getArea(venue.getCityId());
            address.append(city.getParentName()).append(city.getName()).append(village.getParentName()).append(village.getName())
                .append(venue.getAddress());
            venue.setAddress(address.toString());
        }
        page.setRecords(venueList);
        return page;
    }

    @Override
    @Transactional(readOnly = true)
    public VenueVO getInfo(Long id,Boolean operateVisit) {
        EduSecondClassVenue originData = getById(id);
        VenueVO targetData = new VenueVO();
        BeanUtils.copyProperties(originData, targetData);
        // 地址
        StringBuilder address = new StringBuilder();
        EduArea village = commonService.getArea(originData.getVillageId());
        EduArea city = commonService.getArea(originData.getCityId());
        address.append(city.getParentName()).append(city.getName()).append(village.getParentName()).append(village.getName())
            .append(originData.getAddress());
        targetData.setAddress(address.toString());
        if (operateVisit){
            VENUE_VISIT.execute(() -> baseMapper.incrVisitNum(id));
        }
        return targetData;
    }

    @Override
    public void saveVenue(EduSecondClassVenue venue) {
        saveOrUpdate(venue);
    }

    @Override
    public void delVenue(Long id) {
        eduSecondClassVenueExhibitService
            .remove(Wrappers.<EduSecondClassVenueExhibit>lambdaQuery().eq(EduSecondClassVenueExhibit::getVenueId, id));
        eduSecondClassVenueExhibitGroupService
            .remove(Wrappers.<EduSecondClassVenueExhibitGroup>lambdaQuery().eq(EduSecondClassVenueExhibitGroup::getVenueId, id));
        removeById(id);
    }

    @Override
    public VenueH5ContentVO getHomeInfo(Long deptId) {
        VenueH5ContentVO vo = new VenueH5ContentVO();
        List<SubjectVO> sujectList = eduSecondClassSubjectMapper.listSubject(TopicType.VENUE.getValue(),null, deptId);
        vo.setSubjectList(sujectList);
        if (CollUtil.isNotEmpty(sujectList)) {
            List<List<VenueVO>> subjectContentList = new ArrayList<>();
            // 查询所有推荐数据 进行填充
            List<VenueVO> venueList = baseMapper
                .listVenue(null, deptId, null, 0, 1, 1, null, null);
            Map<Long, List<VenueVO>> vuenueGroup = venueList.stream().collect(Collectors.groupingBy(VenueVO::getSubjectId));
            for (SubjectVO subject : sujectList) {
                List<VenueVO> subjectVenueList = null;
                if (subject.getType() == 0) {
                    // 普通信息流数据
                    if (CollUtil.isNotEmpty(venueList)) {
                        for (Entry<Long, List<VenueVO>> entry : vuenueGroup.entrySet()) {
                            if (entry.getKey().equals(subject.getId())) {
                                subjectVenueList = entry.getValue();
                            }
                        }
                    }
                } else {
                    // 排行榜数据
                    subjectVenueList = baseMapper
                        .listVenue(null, deptId, null, 1, 1, null, subject.getRowNum(),
                            null);
                }
                subjectContentList.add(subjectVenueList);
            }
            vo.setSubjectContentList(subjectContentList);
        }
        return vo;
    }

    @Override
    public IPage<VenueVO> listVenuePageBySubject(Integer pageNum, Integer pageSize, Long subjectId) {
        EduSecondClassSubject subject = eduSecondClassSubjectMapper.selectById(subjectId);
        Integer targetPageSize = pageSize;
        if (subject.getType()==1) {
            if (pageNum * pageSize > subject.getRowNum()) {
                if ((pageNum - 1) * pageSize < subject.getRowNum()) {
                    targetPageSize = subject.getRowNum() - (pageNum - 1) * pageSize;
                } else {
                    targetPageSize = 0;
                }
            }
        }
        Page page = Page.of(pageNum, targetPageSize);
        List<VenueVO> list = baseMapper
            .listVenue(page, subject.getDeptId(), null, subject.getType(), 1, null, null, subject.getType() == 0 ? subjectId : null);
        page.setRecords(list);
        return page;
    }

    @Override
    public void changeStatus(Long id, Integer status, Long subjectId) {
        EduSecondClassVenue venue = new EduSecondClassVenue();
        venue.setId(id);
        venue.setStatus(status);
        venue.setSubjectId(subjectId);
        updateById(venue);
    }
}
