package com.winsun.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.winsun.auth.core.annotion.Permission;
import com.winsun.auth.core.base.controller.BaseController;
import com.winsun.auth.core.common.model.ResponseData;
import com.winsun.auth.core.shiro.ShiroUser;
import com.winsun.auth.core.util.IOUtils;
import com.winsun.bean.NetworkInfo;
import com.winsun.bean.School;
import com.winsun.mapper.NetworkInfoMapper;
import com.winsun.mapper.SchoolMapper;
import com.winsun.utils.ExcelDealUtils;
import com.winsun.utils.ImportExcel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

/**
 * @Author: chenhaojian
 * @Date: 2021/3/15 11:47
 */
@Slf4j
@RestController
@RequestMapping("/networkPlace")
public class NetworkPlaceController extends BaseController {
    /**
     * 导入
     */
    private static final int HEADER_NUM = -1;
    private static final int SHEET_INDEX = 0;


//    	headMap.put("网点编码（必填）", "networkCode");
//		headMap.put("网点名（必填）", "networkName");
//		headMap.put("学校（必填）", "schoolName");
//		headMap.put("县分（必填）", "areaName");
//		headMap.put("前置开始时间", "springStartTime");
//		headMap.put("开学时间", "springEndTime");
//		headMap.put("充值大于50奖励", "greaterFifty");
//		headMap.put("充值大于100奖励", "greaterHundred");


    private static String NETWORK_CODE = "网点编码（必填）";
    private static String NETWORK_NAME = "网点名（必填）";
    private static String SCHOOL_NAME = "学校（必填）";
    private static String AREA_NAME = "县分（必填）";
    private static String SPRING_START_TIME = "前置开始时间";
    private static String SPRING_END_TIME = "开学时间";
    private static String GREATER_FIFTY = "充值大于50奖励";
    private static String GREATER_HUNDRED = "充值大于100奖励";

    @Autowired
    private SchoolMapper schoolMapper;

    @Autowired
    private NetworkInfoMapper networkInfoMapper;

    @Permission(menuname = "获取网点列表数据", value = "list", method = RequestMethod.POST)
    public ResponseData<Page<Map<String,Object>>> getOrderConversionInfo(@RequestParam("networkCode")String networkCode,
                                                 @RequestParam("networkName")String networkName,
                                                 @RequestParam("schoolName")String schoolName,
                                                 @RequestParam("areaName")String areaName,
                                                 @RequestParam(name = "pageNo") int pageNo,
                                                 @RequestParam(name = "pageSize") int pageSize){

        ShiroUser user = getShiroUser();
        if (!user.getRoleNames().stream().anyMatch(roleName -> StringUtils.equalsAny(roleName, "超级管理员", "县分管理员（订单）"))) {
            return ResponseData.error("无权限查询订单");
        }
        Wrapper<NetworkInfo> wrapper = new EntityWrapper();
        wrapper.eq(StringUtils.isNotBlank(networkCode),"network_code",networkCode);
        wrapper.like(StringUtils.isNotBlank(networkName),"network_name",networkName, SqlLike.DEFAULT);
        wrapper.like(StringUtils.isNotBlank(schoolName),"school_name",schoolName, SqlLike.DEFAULT);
        wrapper.eq(StringUtils.isNotBlank(areaName),"area_name",areaName);
        Page<Map<String,Object>> page = new Page<>(pageNo, pageSize);
        List<Map<String,Object>> aPackage = networkInfoMapper.selectMapsPage(page, wrapper);
        //查询县分列表
        Wrapper<School> wrapperSubName = new EntityWrapper();
        wrapperSubName.setSqlSelect("sub_name as subNameList").groupBy("sub_name");
        List<Map<String, Object>> selectMaps = schoolMapper.selectMaps(wrapperSubName);
        //查询县分列表
        Wrapper<School> wrapperSchoolName = new EntityWrapper();
        wrapperSchoolName.setSqlSelect("school_name as schoolNameList").groupBy("school_name");
        List<Map<String, Object>> selectSchoolMaps = schoolMapper.selectMaps(wrapperSchoolName);
        //存放县分下拉列表和单宽学校名称下拉列表
        if (!CollectionUtils.isEmpty(aPackage)){
            aPackage.get(0).put("subNameList",selectMaps);
            aPackage.get(0).put("schoolNameList",selectSchoolMaps);
        }
        page.setRecords(aPackage);
        return ResponseData.success(page,"查询成功！");
    }

    @Permission(menuname = "添加", value = "insertData", method = RequestMethod.POST)
    public ResponseData insertData(@RequestParam("networkCode")String networkCode,
                               @RequestParam("networkName")String networkName,
                               @RequestParam("schoolName")String schoolName,
                               @RequestParam("areaName")String areaName,
                               @RequestParam(value = "springStartTime",required = false)String springStartTime,
                               @RequestParam(value = "springEndTime",required = false)String springEndTime,
                               @RequestParam(value = "greaterFifty",required = false)Integer greaterFifty,
                               @RequestParam(value = "greaterHundred",required = false)Integer greaterHundred){
        ShiroUser user = getShiroUser();
        if (!user.getRoleNames().stream().anyMatch(roleName -> StringUtils.equalsAny(roleName, "超级管理员", "县分管理员（订单）"))) {
            ResponseData.error("无权限");
        }
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        try{
            Wrapper<NetworkInfo> wrapper = new EntityWrapper<>() ;
            wrapper.eq(StringUtils.isNotBlank(networkCode),"network_code",networkCode);
            List<NetworkInfo> networkInfos = networkInfoMapper.selectList(wrapper);
            if(networkInfos !=null && networkInfos.size()!=0){
                ResponseData.error("无权限");
            }
            NetworkInfo networkInfo = new NetworkInfo();
            networkInfo.setNetworkCode(networkCode);
            networkInfo.setNetworkName(networkName);
            networkInfo.setSchoolName(schoolName);
            networkInfo.setAreaName(areaName);
            if(StringUtils.isNotBlank(springStartTime)){
                date = formatter.parse(springStartTime);
                networkInfo.setSpringStartTime(date);
            }
            if(StringUtils.isNotBlank(springEndTime)){
                date = formatter.parse(springEndTime);
                networkInfo.setSpringEndTime(date);
            }
            if(greaterFifty != null && StringUtils.isNotBlank(greaterFifty.toString())){
                networkInfo.setGreaterFifty(greaterFifty);
            }
            if(greaterHundred != null && StringUtils.isNotBlank(greaterHundred.toString())){
                networkInfo.setGreaterHundred(greaterHundred);
            }
            networkInfoMapper.insert(networkInfo);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseData.error("添加失败");
        }
        return ResponseData.success();
    }

    @Permission(menuname = "添加", value = "updateData", method = RequestMethod.POST)
    public ResponseData updateData(@RequestParam("id")String id,
                                   @RequestParam("networkCode")String networkCode,
                                   @RequestParam("networkName")String networkName,
                                   @RequestParam("schoolName")String schoolName,
                                   @RequestParam("areaName")String areaName,
                                   @RequestParam(value = "springStartTime",required = false)String springStartTime,
                                   @RequestParam(value = "springEndTime",required = false)String springEndTime,
                                   @RequestParam(value = "greaterFifty",required = false)Integer greaterFifty,
                                   @RequestParam(value = "greaterHundred",required = false)Integer greaterHundred){
        ShiroUser user = getShiroUser();
        if (!user.getRoleNames().stream().anyMatch(roleName -> StringUtils.equalsAny(roleName, "超级管理员", "县分管理员（订单）"))) {
            ResponseData.error("无权限");
        }
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

        try{
            NetworkInfo networkInfo = new NetworkInfo();
            networkInfo.setNetworkCode(networkCode);
            networkInfo.setNetworkName(networkName);
            networkInfo.setSchoolName(schoolName);
            networkInfo.setAreaName(areaName);
            if(StringUtils.isNotBlank(springStartTime)){
                date = formatter.parse(springStartTime);
                networkInfo.setSpringStartTime(date);
            }
            if(StringUtils.isNotBlank(springEndTime)){
                date = formatter.parse(springEndTime);
                networkInfo.setSpringEndTime(date);
            }
            if(greaterFifty != null && StringUtils.isNotBlank(greaterFifty.toString())){
                networkInfo.setGreaterFifty(greaterFifty);
            }
            if(greaterHundred != null && StringUtils.isNotBlank(greaterHundred.toString())){
                networkInfo.setGreaterHundred(greaterHundred);
            }
            Wrapper<NetworkInfo> wrapper = new EntityWrapper<>();
            wrapper.eq("id",id);
            networkInfoMapper.update(networkInfo,wrapper);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseData.error("修改失败");
        }
        return ResponseData.success();
    }

    @Permission(menuname = "导出网点数据", value = "reportDownload", method = RequestMethod.POST)
    public void outOrderConversionInfo(@RequestParam("networkCode")String networkCode,
                                       @RequestParam("networkName")String networkName,
                                       @RequestParam("schoolName")String schoolName,
                                       @RequestParam("areaName")String areaName){
        ShiroUser user = getShiroUser();
        if (!user.getRoleNames().stream().anyMatch(roleName -> StringUtils.equalsAny(roleName, "超级管理员", "县分管理员（订单）"))) {
            ResponseData.error("无权限查询订单");
        }
        Wrapper<NetworkInfo> wrapper = new EntityWrapper();
        wrapper.eq(StringUtils.isNotBlank(networkCode),"network_code",networkCode);
        wrapper.like(StringUtils.isNotBlank(networkName),"network_name",networkName, SqlLike.DEFAULT);
        wrapper.like(StringUtils.isNotBlank(schoolName),"school_name",schoolName, SqlLike.DEFAULT);
        wrapper.eq(StringUtils.isNotBlank(areaName),"area_name",areaName);
        List<NetworkInfo> aPackage = networkInfoMapper.selectList(wrapper);
        ServletOutputStream os = null;
        List<Map<String, Object>> newList = new ArrayList<Map<String,Object>>();
        for (NetworkInfo networkInfo:aPackage){
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("networkCode",networkInfo.getNetworkCode());
            map.put("networkName",networkInfo.getNetworkName());
            map.put("schoolName",networkInfo.getSchoolName());
            map.put("areaName",networkInfo.getAreaName());
            map.put("springStartTime",networkInfo.getSpringStartTime());
            map.put("springEndTime",networkInfo.getSpringEndTime());
            map.put("greaterFifty",networkInfo.getGreaterFifty());
            map.put("greaterHundred",networkInfo.getGreaterHundred());
            newList.add(map);
        }

        XSSFWorkbook workbook = ExcelDealUtils.getWorkBook(ExcelDealUtils.networkExcel("网点列表"), newList);
        try {
            HttpServletResponse response = getHttpServletResponse();
            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream");
            os = response.getOutputStream();
            workbook.write(os);
            os.flush();
        } catch (Exception e) {
            log.error("文件出错！" + e.getMessage(), e);
        } finally {
            IOUtils.closeQuite(workbook, os);
        }
    }
    @Permission(menuname = "下载上传模板", value = "excelMBOut", method = RequestMethod.POST)
    public void excelMBOut(){
        Map<String,Object> map = new HashMap<>();
        map.put("networkCode","(例：GZXY*******)");
        map.put("networkName","(例：**学院)");
        map.put("schoolName","(例：广州****学院)");
        map.put("areaName","(例：从化)");
        map.put("springStartTime","(例：2020-01-01)");
        map.put("springEndTime","(例：2020-02-28)");
        map.put("greaterFifty","(例：25)");
        map.put("greaterHundred","(例：35)");
        List<Map<String, Object>> maps =  new ArrayList<Map<String,Object>>();
        maps.add(map);
        ServletOutputStream os = null;
        XSSFWorkbook workbook = ExcelDealUtils.getWorkBook(ExcelDealUtils.networkExcel("校园模板"), maps);
        try {
            HttpServletResponse response = getHttpServletResponse();
            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream");
            os = response.getOutputStream();
            workbook.write(os);
            os.flush();
        } catch (Exception e) {
            log.error("文件出错！" + e.getMessage(), e);
        } finally {
            IOUtils.closeQuite(workbook, os);
        }
    }
    /**
     * 受理订单
     *
     * @param file 上传的数据文件
     * @return
     */
    @Permission(menuname = "上传数据", value = "importDate", method = RequestMethod.POST)
    public ResponseData<String> updateDatas(@RequestParam(name = "file") MultipartFile file) {
        StringBuffer error = new StringBuffer();
        if (!StringUtils.endsWithAny(file.getOriginalFilename(), "xlsx", "xls")) {
            return ResponseData.error("手工上传数据仅支持Excel文件，其他格式不支持！");
        }
        if ( (double)file.getSize()/1048576 > 100) {
            return ResponseData.error("文件过大，无法上传");
        }
        ShiroUser user = getShiroUser();
        // 当前是否有数据权限
        boolean hasDataPermission = user.getRoleNames().stream().anyMatch(data -> StringUtils.equalsAny(data, "超级管理员"));
        if (!hasDataPermission) {
            return ResponseData.error("无数据权限！");
        }
        ImportExcel importExcel = null;
        try {
            importExcel = new ImportExcel(file, HEADER_NUM, SHEET_INDEX);
        } catch (Exception e) {
            log.error("受理单导入异常", e.getMessage());
            return ResponseData.error("导入异常！");
        }
        List<Map<String, Object>> listMap = importExcel.getDataListMap();
        if (listMap.size() == 1) {
            return ResponseData.error("文件不能为空");
        }
        if (!listMap.get(0).get("a").toString().equals(NETWORK_CODE)) {
            return ResponseData.error("模板不对，请选择正确的模板！");
        }
        if (!listMap.get(0).get("b").toString().equals(NETWORK_NAME)) {
            return ResponseData.error("模板不对，请选择正确的模板！");
        }
        if (!listMap.get(0).get("c").toString().equals(SCHOOL_NAME)) {
            return ResponseData.error("模板不对，请选择正确的模板！");
        }
        if (!listMap.get(0).get("d").toString().equals(AREA_NAME)) {
            return ResponseData.error("模板不对，请选择正确的模板！");
        }
        if (!listMap.get(0).get("e").toString().equals(SPRING_START_TIME)) {
            return ResponseData.error("模板不对，请选择正确的模板！");
        }
        if (!listMap.get(0).get("f").toString().equals(SPRING_END_TIME)) {
            return ResponseData.error("模板不对，请选择正确的模板！");
        }
        if (!listMap.get(0).get("g").toString().equals(GREATER_FIFTY)) {
            return ResponseData.error("模板不对，请选择正确的模板！");
        }
        if (!listMap.get(0).get("h").toString().equals(GREATER_HUNDRED)) {
            return ResponseData.error("模板不对，请选择正确的模板！");
        }
        if (listMap.get(0).size() != 8) {
            return ResponseData.error("模板不对，请选择正确的模板！");
        }
        //校验数据
        try {
            //校验数据
            for (int i = 1; i < listMap.size(); i++) {
                Map<String, Object> temp = listMap.get(i);
                if (!temp.containsKey("a")) {
                    return ResponseData.error("第" + (i + 1) + "行的所属县份不能为空");
                }
                if (StringUtils.isBlank(temp.get("a").toString())) {
                    return ResponseData.error("第" + (i + 1) + "行的所属县份不能为空");
                }
                if (!temp.containsKey("b")) {
                    return ResponseData.error("第" + (i + 1) + "行的学校名称不能为空");
                }
                if (StringUtils.isBlank(temp.get("b").toString())) {
                    return ResponseData.error("第" + (i + 1) + "行的学校名称不能为空");
                }
                if (!temp.containsKey("c")) {
                    return ResponseData.error("第" + (i + 1) + "行的学校名称不能为空");
                }
                if (StringUtils.isBlank(temp.get("c").toString())) {
                    return ResponseData.error("第" + (i + 1) + "行的学校名称不能为空");
                }
                if (!temp.containsKey("d")) {
                    return ResponseData.error("第" + (i + 1) + "行的学校名称不能为空");
                }
                if (StringUtils.isBlank(temp.get("d").toString())) {
                    return ResponseData.error("第" + (i + 1) + "行的学校名称不能为空");
                }
                if (!temp.containsKey("e")) {
                    listMap.get(i).put("e","");
                }
                if (!temp.containsKey("f")) {
                    listMap.get(i).put("f","");
                }
                if (!temp.containsKey("g")) {
                    listMap.get(i).put("g","");
                }
                if (!temp.containsKey("h")) {
                    listMap.get(i).put("h","");
                }
            }
            //检查excel表中是否有重复人员编号
            int size = listMap.size();
            Set<String> accountSet = new HashSet<>(size);
            for (int i = 0; i < size; i++) {
                Map<String, Object> temp = listMap.get(i);
                accountSet.add((String) temp.get("a"));
            }
            if (accountSet.size() != size) {
                return ResponseData.error("文件中有重复的网点，请确认网点不能重复!");
            }
        } catch (Exception e) {
            log.error("学校导入异常", e.getMessage());
            return ResponseData.error("导入异常！");
        }
        int number = 0;
        Date acceptDate = new Date();
        Date successTime = acceptDate;
        StringBuffer networkCode = new StringBuffer();
        StringBuffer networkName = new StringBuffer();
        StringBuffer schoolName = new StringBuffer();
        StringBuffer areaName = new StringBuffer();
        Integer integer = 0;
        Map<String,Object> networkMap = new HashMap<>();

        for (int i = 1; i < listMap.size(); i++) {
            Map<String, Object> map = listMap.get(i);
            networkCode = new StringBuffer(map.get("a").toString());
            integer = 0;

            networkMap = networkInfoMapper.queryMap(networkCode.toString());

            try{
                if(networkMap != null && networkMap.size() != 0){
                    integer = networkInfoMapper.updateMap(map);
                }else {
                    integer = networkInfoMapper.insertMap(map);
                }

            }catch (Exception e){
                e.printStackTrace();
            }

            if (integer == 1) {
                number++;
            } else {
                error.append("第" + (i + 1) + "行的更新失败,");
            }
        }
        error.append("成功更新" + number + "条数据！");
        return ResponseData.success(error.toString(), "导入完成");
    }


    @Permission(menuname = "删除网点", value = "deleteId", method = RequestMethod.POST)
    public ResponseData<Object> deleteId(@Param("id") String id) {
        ShiroUser user = getShiroUser();
        if (!user.getRoleNames().stream().anyMatch(roleName -> StringUtils.equalsAny(roleName, "超级管理员", "县分管理员（订单）"))) {
            ResponseData.error("无权限查询订单");
        }
        int num = 0;
        try{
            num = networkInfoMapper.deleteById(id);
        }catch (Exception e){
            e.printStackTrace();
        }
        if(num > 0) {
            return ResponseData.success("删除成功");
        }
        return ResponseData.success("删除失败");
    }
}
