package com.cirle.scientific.service.impl;

import com.cirle.scientific.constants.CourseWareConsts;
import com.cirle.scientific.dao.*;
import com.cirle.scientific.dto.QkjCourseWareDto;
import com.cirle.scientific.dto.SelectVO;
import com.cirle.scientific.po.*;
import com.cirle.scientific.pojo.BizCodeEnum;
import com.cirle.scientific.pojo.Result;
import com.cirle.scientific.service.OrderService;
import com.cirle.scientific.service.QkjCourseWareService;
import com.cirle.scientific.utils.LocalDateTimeUtil;
import com.cirle.scientific.utils.StringUtil;
import com.cirle.scientific.utils.page.Page;
import com.cirle.scientific.utils.page.ResultPage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.ListUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
@Slf4j
@Transactional
public class QkjCourseWareServiceImpl implements QkjCourseWareService {

    @Autowired
    QkjCourseWareDao qkjCourseWareDao;

    @Autowired
    QkjCatalogsDao qkjCatalogsDao;


    @Autowired
    QkjCatalogsDetailDao qkjCatalogsDetailDao;


    @Autowired
    OrderService orderService;

    @Autowired
    private OrderDao salesOrdersMainDao;

    @Autowired
    QkjTagsDao qkjTagsDao;

    @Autowired
    QkjTagsDetailDao qkjTagsDetailDao;

    @Autowired
    QkjRecommendDao qkjRecommendDao;

    @Override
    public Result getListData(String memCard, Integer cataId, Integer page, Integer size) {
        List<Map<String, Object>> productList = getCourseWareList(memCard, cataId, page, size);

        return Result.success(productList);
    }

    private List<Map<String, Object>> getCourseWareList(String memCard, Integer cataId, Integer page, Integer size) {
        List<QkjCourseWare> courseWareList = null;
        if(cataId == -1){
            courseWareList = qkjCourseWareDao.findList((page-1)*size, size);
        }else{
            //查询首页分类下数据列表
            List<Long> list = getCateList(cataId);
            String join = StringUtils.join(list, ",");
            courseWareList = qkjCourseWareDao.findList(join,(page-1)*size, size);
        }

        return courseWareList.stream().map(item ->{
            Map<String, Object> map = new HashMap<>();
            map.put("title", item.getTitle());
            map.put("fileType", item.getFileType());
            map.put("downloadMembers", StringUtil.getTenThousandOfANumber(item.getDownloadMembers()) + "次下载");
            map.put("price", item.getPrice());
            map.put("point", item.getPoint());
            map.put("id", item.getId());
            map.put("pointFlag", item.getPointFlag());
            map.put("isPurchased", 0);
            map.put("isSubscribe",isSubscribe(item.getId().intValue(), memCard));
            map.put("coverImg",item.getCoverImg());
            if(judgePurchased(item.getId().intValue(), memCard)){
                map.put("isPurchased", 1);
            }
            //保存课件标签
            List<QkjTags> tags = qkjTagsDao.findTagsByObjIdAndObjType(item.getId(), 5);
            if (tags != null && !tags.isEmpty()) {
                map.put("tags", tags);
            }
            return map;
        }).collect(Collectors.toList());
    }

    private List getCateList(Integer cataId ) {
        List<Long> list = new ArrayList<>();
        if (cataId != null) {
            List<QkjCatalogs> byFuId = qkjCatalogsDao.findByFuId(cataId);
            if (byFuId != null && !byFuId.isEmpty()) {
                for (QkjCatalogs qkjCatalogs : byFuId) {
                    List<QkjCatalogs> logs = qkjCatalogsDao.findByFuId(qkjCatalogs.getId().intValue());
                    if (logs != null && !logs.isEmpty()) {
                        for (QkjCatalogs q : logs) {
                            list.add(q.getId());
                        }
                    } else {
                        list.add(qkjCatalogs.getId());
                    }
                }
            }else{
                list.add(cataId.longValue());
            }
        }
        return list;
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public Result downFile(HttpServletResponse response,  String memCard, Long id) {
        if(!judgePurchased(id.intValue(), memCard)){
            return Result.failed("未购买");
        }
        QkjCourseWare courseWare = qkjCourseWareDao.findById(id).get();
        try {
            URL url = new URL(courseWare.getDownloadPath());
            URLConnection conn = url.openConnection();
            InputStream inputStream = conn.getInputStream();
            response.setContentType(conn.getContentType());
            response.setCharacterEncoding("UTF-8");
            String downloadPath = courseWare.getDownloadPath();
            String[] split = downloadPath.split("\\.");
            for (int i = 0; i <split.length ; i++) {
                System.out.println(split[i]);
            }
            if(split.length==1){
                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(courseWare.getFileName(), "UTF-8"));
            }else {
                // 在线打开方式 文件名应该编码成UTF-8
                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(courseWare.getFileName()+"."+split[split.length-1], "UTF-8"));
            }
            byte[] buffer = new byte[2048];
            int len;
            OutputStream outputStream = response.getOutputStream();
            while ((len = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, len);
            }
            inputStream.close();
            outputStream.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public ResultPage getPageData(String memCard, Integer cataId, Integer page, Integer size) {
        Integer totalCount = 0;
        if(cataId == -1){
            totalCount = qkjCourseWareDao.findListCount();
        }else {
            List<Long> list = getCateList(cataId);
            String join = StringUtils.join(list, ",");
            totalCount = qkjCourseWareDao.findListCount(join);
        }
        List<Map<String, Object>> data = getCourseWareList(memCard, cataId, page, size);

        //传入当前页、一页显示条数及总条数，获取分页所需要的起始结束值
        Page<Object> pageBean = new Page<Object>(page, size, totalCount);


        return new ResultPage(data, true,"200", pageBean.getTotalCount(), pageBean.getTotalPage(), pageBean.getPageSize(), pageBean.getCurrentPage());
    }

    @Override
    public ResultPage getListDataForMe(String memCard, Integer belongBrandId, Integer page, Integer size) {
        List<QkjCourseWare> courseWareList  = qkjCourseWareDao.findListByMember(memCard,(page-1)*size, size);


        List<Map<String, Object>> collect = courseWareList.stream().map(item -> {
            Map<String, Object> map = new HashMap<>();
            map.put("title", item.getTitle());
            map.put("fileType", item.getFileType());
            map.put("downloadMembers", StringUtil.getTenThousandOfANumber(item.getDownloadMembers()) + "次下载");
            map.put("price", item.getPrice());
            map.put("point", item.getPoint());
            map.put("id", item.getId());
            map.put("pointFlag", item.getPointFlag());
            map.put("isPurchased", 0);
            map.put("isSubscribe", isSubscribe(item.getId().intValue(), memCard));
            map.put("coverImg", item.getCoverImg());
            if (judgePurchased(item.getId().intValue(), memCard)) {
                map.put("isPurchased", 1);
            }
            //保存课件标签
            List<QkjTags> tags = qkjTagsDao.findTagsByObjIdAndObjType(item.getId(), 5);
            if (tags != null && !tags.isEmpty()) {
                map.put("tags", tags);
            }
            return map;
        }).collect(Collectors.toList());

        Integer totalCount = qkjCourseWareDao.findListCountPpt(memCard);
        //传入当前页、一页显示条数及总条数，获取分页所需要的起始结束值
        Page<Object> pageBean = new Page<Object>(page, size, totalCount);


        return new ResultPage(collect, true,"200", pageBean.getTotalCount(), pageBean.getTotalPage(), pageBean.getPageSize(), pageBean.getCurrentPage());
    }

    @Override
    public Result add(QkjCourseWareDto resources) {
        QkjCourseWare courseWare = new QkjCourseWare();
        BeanUtils.copyProperties(resources, courseWare);

        courseWare.setVdownloadMembers(0);
        if (courseWare.getDurationValidity() == null) {
            courseWare.setDurationValidity(100*12*30);
        }
        if (courseWare.getDownloadMembers() == null) {
            courseWare.setDownloadMembers((int)(Math.random() * 51));
        }
        if (courseWare.getPointFlag() == 0 ){
            courseWare.setPoint(0);
        }
        courseWare.setCreateTime(new Timestamp(System.currentTimeMillis()));
        //赋值默认 自传的默认只有课件
        courseWare.setFileType(1);
        //文件
        courseWare.setTitle(courseWare.getFileName());
        //默认上线
        courseWare.setStatus(1);
        //是否可见：默认为对用户可见 0 不可见  1 可见  2 上传者自己可见
        courseWare.setIsVisiable(2);
        //封面
        courseWare.setCoverImg(CourseWareConsts.DEFAULT_PPT);
        //在哪个端展示：默认全部
        courseWare.setMOrPc(2);


        QkjCourseWare save = qkjCourseWareDao.save(courseWare);
        // 保存标签
        if (resources.getTagId() != null && resources.getTagId().size() > 0) {
            int i = 1;
            for (Integer id : resources.getTagId()) {
                QkjTagsDetail detail = new QkjTagsDetail();
                QkjTags qkjTags = qkjTagsDao.findById(id.longValue()).orElseGet(QkjTags::new);
                detail.setCatalogOneId(qkjTags.getCatalogOneId());
                detail.setCatalogTwoId(qkjTags.getCatalogTwoId());
                detail.setTagId(qkjTags.getId());
                detail.setObjId(save.getId());
                detail.setObjType(5);
                detail.setSqn(i);
                qkjTagsDetailDao.save(detail);
                i++;
            }
        }
        // 保存分类
        if (resources.getCids() != null && resources.getCids().size() > 0) {
            int i = 1;
            for (SelectVO vo:resources.getCids()) {
                QkjCatalogsDetail detail = new QkjCatalogsDetail();
                detail.setObjType(5);
                detail.setFuId(null);
                detail.setCatalogsId(vo.getId());
                detail.setObjId(save.getId());
                detail.setSqn(i);
                qkjCatalogsDetailDao.save(detail);
                i++;
            }
        }
        return Result.success(BizCodeEnum.SUCCESS);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result deleteAll(List<Long> ids) {
        for (Long id : ids) {
            QkjCourseWare qkjCourseware = qkjCourseWareDao.getQkjCourseWare(id);
            if(Objects.isNull(qkjCourseware)){
                continue;
            }
            qkjCourseware.setStatus(2);
            qkjCourseWareDao.save(qkjCourseware);
            // 删除标签关联
            qkjTagsDetailDao.deleteByObjIdAndObjType(id, 5);
            // 删除分类
            List<QkjCatalogsDetail> catalogsDetail = qkjCatalogsDetailDao.findObjectByObjTypeAndObjId(5, qkjCourseware.getId());
            if (catalogsDetail != null) {
                qkjCatalogsDetailDao.deleteAll(catalogsDetail);
            }
            // 查询有无推荐位
            List<QkjRecommend> recommendList = qkjRecommendDao.findListByObjIdAndType(id, 7);
            if (recommendList!= null && recommendList.size()>0) {
                for (QkjRecommend rec:recommendList) {
                    rec.setStatus(0);
                    qkjRecommendDao.save(rec);
                }
            }
        }
        return Result.success(BizCodeEnum.SUCCESS);
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public Result downFileForPPt(HttpServletResponse response,  String memCard, Long id) {
        QkjCourseWare courseWare = qkjCourseWareDao.findById(id).get();
        try {
            URL url = new URL(courseWare.getDownloadPath());
            URLConnection conn = url.openConnection();
            InputStream inputStream = conn.getInputStream();
            response.setContentType(conn.getContentType());
            response.setCharacterEncoding("UTF-8");
            String downloadPath = courseWare.getDownloadPath();
            String[] split = downloadPath.split("\\.");
            for (int i = 0; i <split.length ; i++) {
                System.out.println(split[i]);
            }
            if(split.length==1){
                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(courseWare.getFileName(), "UTF-8"));
            }else {
                // 在线打开方式 文件名应该编码成UTF-8
                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(courseWare.getFileName()+"."+split[split.length-1], "UTF-8"));
            }
            byte[] buffer = new byte[2048];
            int len;
            OutputStream outputStream = response.getOutputStream();
            while ((len = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, len);
            }
            inputStream.close();
            outputStream.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Result downFileForPPtBatch(HttpServletResponse response, List<Integer> ids) {

        List<QkjCourseWare> courseWares = qkjCourseWareDao.listQkjCourseWare(ids);

        if(CollectionUtils.isEmpty(courseWares)){
            return Result.failed("没有下载的文件");
        }

        Map<String, String> map = courseWares.stream().collect(Collectors.toMap(QkjCourseWare::getDownloadPath, QkjCourseWare::getFileName, (v1, v2) -> v1));
        //设置zip属性
        String zipName = LocalDateTimeUtil.getTimestampOfDateTime(LocalDateTime.now()) + ".zip";
        response.setHeader("content-type", "application/octet-stream");
        response.setHeader("Content-disposition", "attachment;filename=" + zipName);
        response.setCharacterEncoding("utf-8");

        try  {
            ServletOutputStream outputStream = response.getOutputStream();
            ZipOutputStream zipOut = new ZipOutputStream(outputStream);
            for (Map.Entry<String, String> entry : map.entrySet()) {
                String iUrl = entry.getKey();
                String fileName = entry.getValue();
                URL url = new URL(iUrl);

                //定义每个的名字
                // new ZipEntry(FilenameUtils.getName(iUrl));
                String name = FilenameUtils.getName(iUrl);
                String[] split = name.split("\\.");
                //得到后缀
                String suffix = Strings.EMPTY;
                if (split.length >= 2) {
                    suffix = split[split.length - 1];
                }
                String join = StringUtils.join(fileName,".", suffix);
                ZipEntry zipEntry = new ZipEntry(join);
                zipOut.putNextEntry(zipEntry);
                InputStream in = new BufferedInputStream(url.openStream());
                byte[] bytes = IOUtils.toByteArray(in);
                zipOut.write(bytes);

                zipOut.closeEntry();
                in.close();
            }
            outputStream.close();
        } catch (Exception e) {
            log.error("导出相册压缩包失败", e);
        }
        return null;
    }


    //判断课件是否过期
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    protected boolean judgePurchased(Integer id, String memCard) {
        QkjPurchasedRecords records = orderService.findPurchasedRecords(memCard,4,id,1);
        Boolean isPurchased = false;
        if(records != null){
            isPurchased = true;
        }
        return isPurchased;
    }

    //判断课件是否购买
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    protected Integer isSubscribe(Integer id, String memCard) {
        List<SalesOrdersMain> tqcourseOrderList = salesOrdersMainDao.findTqcourseOrderList(memCard, 4, id);
        Integer isSubscribe = 0;
        if(!ListUtils.isEmpty(tqcourseOrderList)){
            isSubscribe = 1;
        }
        return isSubscribe;
    }
}

