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

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.apply.EduProductNotice;
import com.yida.data.common.core.entity.apply.EduProductNoticeStudent;
import com.yida.data.common.core.entity.constant.AppConstant;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.notice.qywx.TextSchoolNotice;
import com.yida.data.common.core.entity.notice.qywx.inside.Text;
import com.yida.data.common.core.entity.system.EduApp;
import com.yida.data.common.core.entity.user.EduStudent;
import com.yida.data.common.core.utils.EasyExcelUtil;
import com.yida.data.common.core.utils.WxUtil;
import com.yida.data.common.service.CommonService;
import com.yida.data.school.dto.transaction.ListBuyStudentDTO;
import com.yida.data.school.transaction.mapper.EduProductMapper;
import com.yida.data.school.transaction.mapper.EduProductNoticeStudentMapper;
import com.yida.data.school.transaction.service.EduProductNoticeService;
import com.yida.data.school.transaction.service.EduProductNoticeStudentService;
import com.yida.data.school.transaction.service.EduProductService;
import com.yida.data.school.vo.transcation.DownStudentBuyDataVO;
import com.yida.data.school.vo.transcation.EduProductNoticeVO;
import com.yida.data.school.vo.transcation.StudentNotBuyExportVO;
import com.yida.data.user.feign.RemoteStudentService;
import com.yida.data.user.vo.ListParentByStudentIdsVO;
import java.io.File;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * 催缴通知对应接收学生表 Service实现
 *
 * @author ccl
 * @date 2021-09-03 15:33:47
 */
@RefreshScope
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class EduProductNoticeStudentServiceImpl extends ServiceImpl
    <EduProductNoticeStudentMapper, EduProductNoticeStudent> implements EduProductNoticeStudentService {

    private final EduProductNoticeStudentMapper eduProductNoticeStudentMapper;
    @Resource
    private WxUtil wxUtil;
    @Resource
    private RemoteStudentService remoteStudentService;
    @Resource
    private CommonService commonService;
    @Resource
    private EduProductNoticeService eduProductNoticeService;
    @Resource
    private EduProductService eduProductService;
    @Resource
    private EduProductMapper eduProductMapper;

    private final RedisService redisService;

    @Value("${febs.pageUrl}")
    private String pageUrl;

    @Value("${febs.uploadUrl}")
    private String uploadUrl;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchPutNotice(List<EduProductNoticeStudent> noticeStudents) {
        EduProductNotice notice = new EduProductNotice();
        notice.setContent(noticeStudents.get(0).getContent());
        notice.setProductId(noticeStudents.get(0).getProductId());
        eduProductNoticeService.save(notice);

        List<Long> studentIds = new ArrayList<>();
        for (EduProductNoticeStudent noticeStudent : noticeStudents) {
            studentIds.add(noticeStudent.getStudentId());
            noticeStudent.setNoticeId(notice.getId());
        }

        Long productId = noticeStudents.get(0).getProductId();
        Long schoolId = eduProductService.getById(productId).getSchoolId();

        EduApp app = commonService.getAppByCodeAndSchool(AppConstant.INDEX_PARENT, null,
            schoolId);
        String accessToken = wxUtil.getAccessToken(app.getWxCorpId(), app.getWxSecret());

        //家长wxId
        List<String> parentWxId = remoteStudentService.findParentWxId(studentIds).getData();
        Text text = new Text();
        //http://zbztest.yd-data.com/view/campusService/index.html?corpId=ww930b8b35eab68020#/detail?productId=218
        String url = pageUrl + "/campusService/index.html?" + "corpId=" + app.getWxCorpId() + "&detail=" + productId;
        String content = noticeStudents.get(0).getContent() + "\n" + "<a href='" + url + "'>" + "#点击此处前往缴费#" + "</a>";
        text.setContent(content);
        TextSchoolNotice textSchoolNotice = new TextSchoolNotice();
        textSchoolNotice.setText(text);
        textSchoolNotice.setAgentid(app.getWxAgentId());
        textSchoolNotice.setTo_parent_userid(parentWxId);
        //发送微信通知
        wxUtil.pushSchoolNotice(accessToken, textSchoolNotice);

        saveBatch(noticeStudents);
    }

    @Override
    public IPage<EduProductNoticeStudent> findRecordList(Page page, Long productId) {
        List<EduProductNotice> list = eduProductNoticeService.list(Wrappers.lambdaQuery(new EduProductNotice())
            .eq(EduProductNotice::getProductId, productId));

        if (CollectionUtil.isEmpty(list)) {
            return new Page<>();
        }
        ArrayList<Long> noticeIds = new ArrayList<>();

        for (EduProductNotice notice : list) {
            noticeIds.add(notice.getId());
        }

        return baseMapper.findRecordList(page, noticeIds);
    }

    @Override
    public IPage<ListParentByStudentIdsVO> findRecordParent(Page page, Long id) {
        ArrayList<Long> ids = new ArrayList<>();
        ids.add(id);
        IPage<EduProductNoticeStudent> recordList = baseMapper.findRecordList(page, ids);
        List<EduProductNoticeStudent> records = recordList.getRecords();
        ArrayList<Long> noticeId = new ArrayList<>();
        for (EduProductNoticeStudent record : records) {
            if (ObjectUtil.isNotEmpty(record)) {
                noticeId.add(record.getNoticeId());
            }
        }
        List<EduProductNoticeStudent> list = list(Wrappers.lambdaQuery(new EduProductNoticeStudent())
            .in(EduProductNoticeStudent::getNoticeId, noticeId));
        ArrayList<Long> studentIds = new ArrayList<>();
        for (EduProductNoticeStudent eduProductNoticeStudent : list) {
            studentIds.add(eduProductNoticeStudent.getStudentId());
        }

        page.setRecords(remoteStudentService.listParentByStudentIds(studentIds).getData());
        return page;
    }

    @Override
    public void studentNotBuyExport(ListBuyStudentDTO listBuyStudentDTO, HttpServletResponse response) {
        List<EduProductNoticeVO> list1 = eduProductMapper.listBuyStudent(listBuyStudentDTO);
        ArrayList<Long> studentIds = new ArrayList<>();
        for (EduProductNoticeVO eduProductNoticeVO : list1) {
            studentIds.add(eduProductNoticeVO.getStudentId());
        }
        //已购买学生
        listBuyStudentDTO.setStudentId(studentIds);
        List<EduStudent> data = remoteStudentService.listAllNotBuyStudent(listBuyStudentDTO).getData();
        ArrayList<StudentNotBuyExportVO> list = new ArrayList<>();

        for (int i = 0; i < data.size(); i++) {
            StudentNotBuyExportVO welcomeStudentExportDTO = new StudentNotBuyExportVO();
            welcomeStudentExportDTO.setCampusName(data.get(i).getCampusName());
            welcomeStudentExportDTO.setSectionName(data.get(i).getSectionName());
            welcomeStudentExportDTO.setGradeName(data.get(i).getGradeName());
            welcomeStudentExportDTO.setClassName(data.get(i).getClassName());
            welcomeStudentExportDTO.setStudentName(data.get(i).getStuName());
            welcomeStudentExportDTO.setIndexNo((long) i);
            welcomeStudentExportDTO.setStudentNumber(data.get(i).getStuNumber());
            list.add(welcomeStudentExportDTO);
        }
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 根据查询条件导出未购买学生数据

        // 导出Excel
        EasyExcelUtil.exportExcelData(list, StudentNotBuyExportVO.class, "导出未购买导出数据",
            ExcelTypeEnum.XLS, response);
        stopWatch.stop();
        log.info("导出未购买学生数据总共耗时: {}", stopWatch.getTotalTimeSeconds() + "秒");
    }


    @Override
    public void studentBuyExport(ListBuyStudentDTO listBuyStudentDTO, HttpServletResponse response, String uuid) {
        File file = null;
        String fileName = com.yida.data.common.core.utils.FileUtil.getLocalUploadAddress() + uuid + ".xlsx";
        file = new File(fileName);

        try {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();

            List<EduProductNoticeVO> list1 = eduProductMapper.listBuyStudent(listBuyStudentDTO);
            List<Long> studentId = new ArrayList<>();
            for (EduProductNoticeVO eduProductNoticeVO : list1) {
                studentId.add(eduProductNoticeVO.getStudentId());
            }
            ArrayList<StudentNotBuyExportVO> list = new ArrayList<>();

            for (int i = 0; i < studentId.size(); i++) {

                log.info("学生ID:{}", studentId.get(i));

                redisService.hset(CachePrefixConstant.PRODUCT_BUY_DATA_DOWNLOAD, uuid, DownStudentBuyDataVO.builder()
                    .key(uuid)
                    .finish(0)
                    .totalNum(studentId.size())
                    .currentNum(i + 1).build());

                EduStudent data = remoteStudentService.getStudentNoPermission(studentId.get(i)).getData();

                StudentNotBuyExportVO studentNotBuyExportVO = new StudentNotBuyExportVO();
                studentNotBuyExportVO.setCampusName(ObjectUtil.isNull(data) ? "" : data.getCampusName());
                studentNotBuyExportVO.setSectionName(ObjectUtil.isNull(data) ? "" : data.getSectionName());
                studentNotBuyExportVO.setGradeName(ObjectUtil.isNull(data) ? "" : data.getGradeName());
                studentNotBuyExportVO.setClassName(ObjectUtil.isNull(data) ? "" : data.getClassName());
                studentNotBuyExportVO.setStudentName(ObjectUtil.isNull(data) ? "" : data.getStuName());
                studentNotBuyExportVO.setIndexNo((long) i + 1);
                studentNotBuyExportVO.setStudentNumber(ObjectUtil.isNull(data) ? "" : data.getStuNumber());
                list.add(studentNotBuyExportVO);
            }

            // 根据查询条件导出未购买学生数据
            // 导出数据
            EasyExcel.write(file)
                .excelType(ExcelTypeEnum.XLSX)
                // 这里放入动态头
                .head(StudentNotBuyExportVO.class).sheet("职工通行记录")
                // 当然这里数据也可以用 List<List<String>> 去传入
                .doWrite(list);
            // 上传文件到媒资
            String fileUrl = com.yida.data.common.core.utils.FileUtil.uploadFileToMediaServer(uploadUrl, file);

            redisService
                .hset(CachePrefixConstant.PRODUCT_BUY_DATA_DOWNLOAD, uuid, DownStudentBuyDataVO.builder()
                    .key(uuid)
                    .finish(1)
                    .filePath(fileUrl)
                    .totalNum(list.size())
                    .currentNum(list.size()).build());

//        // 导出Excel
//        EasyExcelUtil.exportExcelData(list, StudentNotBuyExportVO.class, "导出需要已购买学生",
//            ExcelTypeEnum.XLS, response);
            stopWatch.stop();
            log.info("导出已购买学生数据总共耗时: {}", stopWatch.getTotalTimeSeconds() + "秒");
        } catch (IllegalStateException e) {
            log.error("导出已购买学生数据出错:{}", e);
        } finally {
            if (Objects.nonNull(file)) {
                cn.hutool.core.io.FileUtil.del(file);
            }
        }
    }

    @Override
    public void allPutNotice(EduProductNoticeStudent eduProductNoticeStudent) {
        EduProductNotice notice = new EduProductNotice();
        notice.setContent(eduProductNoticeStudent.getContent());
        notice.setProductId(eduProductNoticeStudent.getProductId());
        eduProductNoticeService.save(notice);

        Long productId = eduProductNoticeStudent.getProductId();
        Long schoolId = eduProductService.getById(productId).getSchoolId();
        //查询所有购买学生
        ListBuyStudentDTO listBuyStudentDTO = new ListBuyStudentDTO();
        listBuyStudentDTO.setSchoolId(schoolId);
        listBuyStudentDTO.setProductId(productId);
        List<EduProductNoticeVO> list = eduProductMapper.listBuyStudent(listBuyStudentDTO);

        List<Long> studentIds = new ArrayList<>();
        for (EduProductNoticeVO o : list) {
            //快到期学生
            studentIds.add(o.getStudentId());
        }
        listBuyStudentDTO.setStudentId(studentIds);
        List<EduStudent> students = remoteStudentService.listAllNotBuyStudent(listBuyStudentDTO).getData();

        ArrayList<Long> notBuyStudentIds = new ArrayList<>();
        ArrayList<EduProductNoticeStudent> noticeStudents = new ArrayList<>();
        for (EduStudent student : students) {
            EduProductNoticeStudent noticeStudent = new EduProductNoticeStudent();
            noticeStudent.setProductId(productId);
            noticeStudent.setNoticeId(notice.getId());
            noticeStudent.setStudentId(student.getId());
            noticeStudent.setContent(notice.getContent());
            noticeStudent.setReceiveType(0);
            noticeStudents.add(noticeStudent);
            notBuyStudentIds.add(student.getId());
        }

        EduApp app = commonService.getAppByCodeAndSchool(AppConstant.INDEX_PARENT, null,
            schoolId);
        String accessToken = wxUtil.getAccessToken(app.getWxCorpId(), app.getWxSecret());

        //家长wxId
        List<String> parentWxId = remoteStudentService.findParentWxId(notBuyStudentIds).getData();
        Text text = new Text();
        //http://zbztest.yd-data.com/view/campusService/index.html?corpId=ww930b8b35eab68020#/detail?productId=218
        String url = pageUrl + "/campusService/index.html?" + "corpId=" + app.getWxCorpId() + "&detail=" + productId;
        String content = eduProductNoticeStudent.getContent() + "\n" + "<a href='" + url + "'>" + "#点击此处前往缴费#" + "</a>";
        text.setContent(content);
        TextSchoolNotice textSchoolNotice = new TextSchoolNotice();
        textSchoolNotice.setText(text);
        textSchoolNotice.setAgentid(app.getWxAgentId());
        textSchoolNotice.setTo_parent_userid(parentWxId);
        //发送微信通知
        wxUtil.pushSchoolNotice(accessToken, textSchoolNotice);

        saveBatch(noticeStudents);
    }
}
