package com.ruoyi.web.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.ExamType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.syzy.domain.BBusiWishRecords;
import com.ruoyi.syzy.domain.BBusiWishUniversities;
import com.ruoyi.syzy.domain.BBusiWishUniversitySubmitRecruitPlan;
import com.ruoyi.syzy.dto.SubmitWishRecordDTO;
import com.ruoyi.web.domain.Constant;
import com.ruoyi.web.domain.ZytbDto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;
import org.springframework.http.MediaType;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class VolunteerExporter {
    public static void export(String location, BBusiWishRecords record, SubmitWishRecordDTO.SubmitWishRecordDetail detail, Integer currYear, Integer currSubmitYear,
                              Integer seat, List<ZytbDto.ZytbVolunteerRes> volunteerResList, HttpServletResponse response) {
        if (volunteerResList == null) {
            response.setStatus(404);
            return;
        }
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        try {
            String course = ExamType.VHS.equals(sysUser.getExamType()) ? detail.getMode()
                    : Arrays.asList(detail.getMode().split(",")).stream().map(t -> t.substring(0, 1)).collect(Collectors.joining());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            String score = String.valueOf(Math.round(detail.getScore()));
            String realFileName = detail.getYear() + "_" + location + "_" + record.getBatchName() + "_" + score + "分_"
                    + "_" + course + "_" + record.getName() + "_" + sdf.format(new Date()) + ".xlsx";
            // _湖南_本科_590分_物化生_志愿表7_20230221181347.xlsx
            InputStream is = VolunteerExporter.class.getResourceAsStream("/templates/wish_template.xlsx");
            Context context = new Context();
            // 志愿表7  湖南    女  本科  590分  -位  物/化/生
            String title = record.getName() + "  " + location + "    " + normalSex(sysUser.getSex()) + "  " + record.getBatchName() + "  "
                    + score + "分  " + (null != seat ? seat : "-") + "位  " + course;
            context.putVar("title", title);
            context.putVar("planTitle", detail.getYear() + "(招生计划)");
            context.putVar("years", Lists.newArrayList(String.valueOf(currSubmitYear), String.valueOf(currSubmitYear - 1), String.valueOf(currSubmitYear - 2)));
            context.putVar("records", buildData(detail.getBatch().getHighlightMajorIds(), volunteerResList));
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, realFileName);
            // OutputStream os = new FileOutputStream("D:\\data\\wish_output.xls");
            JxlsHelper.getInstance().processTemplate(is, response.getOutputStream(), context);
        } catch (UnsupportedEncodingException e) {
            response.setStatus(404);
        } catch (Exception e) {
            response.setStatus(404);
        }
        return;
    }

    private static List<VolunteerRes> buildData(List<String> highlightMajorIds, List<ZytbDto.ZytbVolunteerRes> volunteerResList) {
        List<VolunteerRes> dataList = Lists.newArrayList();
        StringBuilder sb = new StringBuilder();
        Set<String> highlightMajorIdSet = null != highlightMajorIds ? Sets.newHashSet(highlightMajorIds) : Sets.newHashSet();
        for (ZytbDto.ZytbVolunteerRes zytbVolunteer : volunteerResList) {
            VolunteerRes res = new VolunteerRes();
            BBusiWishUniversities u = zytbVolunteer.getUniversity();
            BBusiWishUniversitySubmitRecruitPlan rp = zytbVolunteer.getRecruitPlan();
            dataList.add(res);
            res.setSeq(dataList.size());
            res.setEnrollRatio(zytbVolunteer.getEnrollRatio() + "%");
            res.setCollegeCode(rp.getCollegeCode());
            sb.setLength(0);
            sb.append(u.getName());
            if (StringUtils.isNotBlank(rp.getGroup())) {
                sb.append("(").append(rp.getGroup()).append(")");
            }
            if (StringUtils.isNotBlank(rp.getSpecialProject())) {
                sb.append("(").append(rp.getSpecialProject()).append(")");
            }
            res.setUniversityName(sb.toString());
            res.setLevel(StringUtils.join(u.getFeatures().split(","), "\n"));
            res.setLocation(u.getLocation() + "/" + u.getCityName());
            res.setType(u.getType());
            res.setNatureType(u.getNatureTypeCN());
            res.setRank(null!=u.getRanking() ? (0==u.getRanking()?null:u.getRanking()) : null);
            res.setCourse(rp.getCourse());

            List<Major> majors = Lists.newArrayList();
            for (ZytbDto.ZytbVoluntaryMarjorDetail md : zytbVolunteer.getMarjorList()) {
                Major m = new Major();
                m.setEnrollRatio(md.getEnrollRatio() + "%");
                m.setMarjorId(StringUtils.trimToEmpty(md.getMarjorId()));
                m.setMarjorMatched(highlightMajorIdSet.contains(m.getMarjorId()));
                m.setMarjorName((StringUtils.isNotBlank(md.getMarjorBelongs()) ? md.getMarjorName() + "(" + md.getMarjorBelongs() + ")" : md.getMarjorName()) + StringUtils.trimToEmpty(md.getMarjorDirection()));
                m.setPlanCount(md.getPlanCount());
                m.setXuefei(md.getXuefei());
                m.setXuezhi(md.getXuezhi());
                List<MajorSubmit> hiList = Arrays.stream(md.getHistories()).map(t ->
                        new MajorSubmit(normal(t.getNumReal()), normal(t.getLineDiff()), normal(t.getScore()), normal(t.getSeat()))).collect(Collectors.toList());
                m.setHistories(hiList);
                majors.add(m);
            }
            res.setMajors(majors);
        }
        return dataList;
    }

    public static String normalSex(String v) {
        return "0".equals(v) ? "男" : ("1".equals(v) ? "女" : "-");
    }

    public static String normal(Long v) {
        return null == v || v.equals(0L) ? "-" : String.valueOf(v);
    }
    public static String normal(String v) {
        return StringUtils.isBlank(v) ? "-" : v;
    }

    @Data
    public static class VolunteerRes {
        Integer seq;
        String enrollRatio;
        String collegeCode;
        String universityName;
        String level;
        String location;
        String type;
        String natureType;
        Integer rank;
        String course;
        List<Major> majors;
    }

    @Data
    public static class Major {
        String enrollRatio;
        String marjorId;
        Boolean marjorMatched;
        String marjorName;
        Integer planCount;
        String xuefei;
        String xuezhi;
        List<MajorSubmit> histories;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class MajorSubmit {
        String numReal;
        String diff;
        String score;
        String seat;
    }
}
