package com.huyi.service.rel.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huyi.service.base.entity.SysCompany;
import com.huyi.service.base.entity.SysCompanyRel;
import com.huyi.service.base.entity.SysCompanySpare;
import com.huyi.service.base.service.ISysCompanyRelService;
import com.huyi.service.base.service.ISysCompanyService;
import com.huyi.service.base.service.ISysCompanySpareService;
import com.tianhu.common.core.utils.CommonUtil;
import com.tianhu.common.core.utils.DateUtils;
import com.tianhu.common.core.utils.IdUtils;
import com.tianhu.common.core.utils.file.ExcelFileUtils;
import com.tianhu.common.core.web.controller.BaseController;
import com.tianhu.common.core.web.domain.AjaxResult;
import com.tianhu.common.log.annotation.Log;
import com.tianhu.common.log.enums.BusinessType;
import com.tianhu.common.security.annotation.PreAuthorize;
import com.tianhu.common.security.service.TokenService;
import com.tianhu.system.api.domain.SysUser;
import com.tianhu.system.api.model.LoginUser;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 链属导入Controller
 * 
 * @author keao
 * @date 2020-12-16
 */
@RestController
@RequestMapping("/relImport")
public class CompanyRelImportController extends BaseController
{
    private static final Logger log = LoggerFactory.getLogger(CompanyRelImportController.class);

    @Autowired
    private ISysCompanyRelService iSysCompanyRelService;

    @Autowired
    private ISysCompanyService iSysCompanyService;

    @Autowired
    private ISysCompanySpareService iSysCompanySpareService;

    @Autowired
    private TokenService tokenService;

    /**
     * 企业正常状态
     */
    private String NORMAL_STATE = "00";

    /**
     * 停用状态
     */
    private String CONFIRM_STATE = "01";

    /**
     * 拒绝链属
     */
    private String REFUSE_STATE = "02";

    /**
     * 删除状态
     */
    private String DELETE_STATE = "99";


    /**
     * 链属模板导出
     * @param scyId
     * @param response
     */
    @PostMapping("/importTemplate")
    public void importTemplate(String scyId, HttpServletResponse response)
    {
        String sheetName = "链属模板";
        String fileName = "链属模板";
        //行宽度
        List<Integer> columnWidth = new ArrayList<>();

        //获取当前操作人员
        LoginUser userInfo = tokenService.getLoginUser();
        SysUser use = userInfo.getSysUser();
        String companyId = use.getCompanyId();
        //模板企业名称
        String companyName = "";
        //模板企业统一代码
        String companyCode = "";
        if(CommonUtil.isEmpty(scyId)) {
            LambdaQueryWrapper<SysCompany> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysCompany::getScyId, companyId);
            List<SysCompany> companyList = iSysCompanyService.findSysCompanys(queryWrapper);
            companyName = companyList.get(0).getScyName();
            companyCode = companyList.get(0).getScySocialCode();
        }
        if(CommonUtil.isNotEmpty(scyId)){
            LambdaQueryWrapper<SysCompany> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysCompany::getScyId, scyId);
            List<SysCompany> companyList = iSysCompanyService.findSysCompanys(queryWrapper);
            companyName = companyList.get(0).getScyName();
            companyCode = companyList.get(0).getScySocialCode();
        }

        List<String> list = new ArrayList<>();
        //列表表头
        List<String> firstColumnName = new ArrayList<>();
        firstColumnName.add(companyName);
        firstColumnName.add(companyCode);
        int firstColumnNumber = firstColumnName.size();

        List<String> columnName = new ArrayList<>();
        columnName.add("*供应商企业全称");
        columnName.add("*供应商企业社会统一代码");
        columnName.add("联系人名称");
        columnName.add("联系人手机号码");
        int columnNumber = columnName.size();
        for(String width:columnName){
            columnWidth.add(20);
        }
        try {
            HSSFWorkbook wb = exportNoResponse(sheetName, fileName, firstColumnNumber,
                    columnNumber, columnWidth, firstColumnName, columnName, list);
            response.setCharacterEncoding("UTF-8");
            // 设置contentType为excel格式
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            //默认Excel名称
            response.setHeader("Content-disposition", "attachment;filename=" + "链属模板"+ URLEncoder.encode(fileName + ".xls", "UTF-8"));
            response.flushBuffer();
            OutputStream outputStream = response.getOutputStream();
            wb.write(outputStream);
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException var) {
                    var.printStackTrace();
                }
            }
        } catch (Exception varLog) {
            log.error("导出Excel异常{}", varLog.getMessage());
        }
    }

    /**
     * 链属导入
     * @param file  链属文件
     * @return
     * @throws Exception
     */
    @Log(title = "链属导入", businessType = BusinessType.IMPORT)
    @PreAuthorize(hasAnyPermi = "service:relImport:importData")
    @Transactional(rollbackFor=Exception.class)
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file) throws Exception
    {
        //获取当前操作人员
        LoginUser userInfo = tokenService.getLoginUser();
        SysUser use = userInfo.getSysUser();
        String companyId = use.getCompanyId();
        String userId = String.valueOf(use.getUserId());

        //MultipartFile转File
        File files = multipartFileToFile(file);
        //获取第一行数据
        String hId = "";
        try {
            FileInputStream fis = new FileInputStream(files);
            HSSFWorkbook wb = new HSSFWorkbook(fis);
            HSSFSheet s = wb.getSheet("链属模板");
            HSSFRow row = s.getRow(0);
            HSSFCell cell = row.getCell((short) 0);
            HSSFCell hssfCell = row.getCell((short) 1);
            String name = cell.getStringCellValue();
            String code = hssfCell.getStringCellValue();
            LambdaQueryWrapper<SysCompany> com = new LambdaQueryWrapper<>();
            com.eq(SysCompany::getScyName,name);
            com.eq(SysCompany::getScySocialCode,code);
            List<SysCompany> list = iSysCompanyService.findSysCompanys(com);
            hId = list.get(0).getScyId();
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //列表对应字段
        List<String> columnName = new ArrayList<>();
        columnName.add("scyName");
        columnName.add("scySocialCode");
        columnName.add("scrContarct");
        columnName.add("scrContarctPhone");
        //excel数据
        List<Map<String,String>> templateData = ExcelFileUtils.readExecleasy(file,columnName,2);
        if(templateData.size() == 0){
            return AjaxResult.error("导入数据不能为空");
        }
        //未添加成功的list
        String userNameList = "";
        //链属集合
        List<SysCompanyRel> relList = new ArrayList<>();
        //链属企业信息
        List<SysCompanySpare> spareList = new ArrayList<>();
        //个税详情表集合
        //返回结果信息
        StringBuilder failureMsg = new StringBuilder();
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        int successNum = 0;
        //循环处理excel数据
        for (int i = 0; i < templateData.size(); i++){
            Map<String,String> map = templateData.get(i);
            //供应商企业全称
            String scyName = CommonUtil.objToString(map.get("scyName"));
            //供应商企业社会统一代码
            String scySocialCode = CommonUtil.objToString(map.get("scySocialCode"));
            //联系人
            String scrContarct = CommonUtil.objToString(map.get("scrContarct"));
            //联系人手机号
            String scrContarctPhone = CommonUtil.objToString(map.get("scrContarctPhone"));

            //供应商企业全称
            if(CommonUtil.isNotEmpty(scyName)){
                if(scyName.length() <= 60){
                }else{
                    userNameList += scyName+",";
                    failureNum++;
                    failureMsg.append("<br/>第" + (i+1) + "行数据导入失败,供应商企业全称不能大于60位");
                    log.error("新增" + scyName + "的链属失败，供应商企业全称不能大于60位");
                    continue;
                }
            }else{
                userNameList += scyName+",";
                failureNum++;
                failureMsg.append("<br/>第" + (i+1) + "行数据导入失败,供应商企业全称不能为空");
                log.error("新增" + scyName + "的链属失败，供应商企业全称不能为空");
                continue;
            }
            //供应商企业社会统一代码
            if(CommonUtil.isNotEmpty(scySocialCode)){
                if(scyName.length() <= 100){
                }else{
                    userNameList += scyName+",";
                    failureNum++;
                    failureMsg.append("<br/>第" + (i+1) + "行数据导入失败,企业社会统一代码不能大于60位");
                    log.error("新增" + scyName + "的链属失败，企业社会统一代码不能大于60位");
                    continue;
                }
                //社会统一代码正则校验
                String checkSocialCode = "^([0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}|[1-9]\\d{14})$";
                Pattern regeSocialCode = Pattern.compile(checkSocialCode);
                Matcher matcherSocialCode = regeSocialCode.matcher(scySocialCode);
                boolean isMatSocialCode = matcherSocialCode.matches();
                if(!isMatSocialCode){
                    userNameList += scyName+",";
                    failureNum++;
                    failureMsg.append("<br/>第" + (i+1) + "行数据导入失败,企业社会统一代码格式错误");
                    log.error("新增" + scyName + "的链属失败，企业社会统一代码格式错误");
                    continue;
                }
            }else{
                userNameList += scyName+",";
                failureNum++;
                failureMsg.append("<br/>第" + (i+1) + "行数据导入失败,企业社会统一代码不能为空");
                log.error("新增" + scyName + "的链属失败，企业社会统一代码不能为空");
                continue;
            }
            //联系人
//            if(CommonUtil.isNotEmpty(scrContarct)){
//                if(scrContarct.length() <= 30){
//                }else{
//                    userNameList += scyName+",";
//                    failureNum++;
//                    failureMsg.append("<br/>第" + (i+1) + "行数据导入失败,联系人不能大于30位");
//                    log.error("新增" + scyName + "的链属失败，联系人不能大于30位");
//                    continue;
//                }
//            }else{
//                userNameList += scyName+",";
//                failureNum++;
//                failureMsg.append("<br/>第" + (i+1) + "行数据导入失败,联系人不能为空");
//                log.error("新增" + scyName + "的链属失败，联系人不能为空");
//                continue;
//            }
            //联系人手机号
//            if(CommonUtil.isNotEmpty(scrContarctPhone)){
//                //手机号
//                String checkPhone = "^1[3|4|5|6|7|8|9][0-9]\\d{8}$";
//                Pattern phonePattern = Pattern.compile(checkPhone);
//                boolean phoneResult = phonePattern.matcher(scrContarctPhone).matches();
//                if(!phoneResult){
//                    userNameList += scyName+",";
//                    failureNum++;
//                    failureMsg.append("<br/>第" + (i+1) + "行数据导入失败,联系人手机号格式不正确");
//                    log.error("新增" + scyName + "的链属失败，联系人手机号格式不正确");
//                    continue;
//                }
//                if(scrContarctPhone.length() > 11){
//                    userNameList += scyName+",";
//                    failureNum++;
//                    failureMsg.append("<br/>第" + (i+1) + "行数据导入失败,联系人手机号不能超过11位");
//                    log.error("新增" + scyName + "的链属失败，联系人手机号不能超过11位");
//                    continue;
//                }
//            }else{
//                userNameList += scyName+",";
//                failureNum++;
//                failureMsg.append("<br/>第" + (i+1) + "行数据导入失败,联系人手机号不能为空");
//                log.error("新增" + scyName + "的链属失败，联系人手机号不能为空");
//                continue;
//            }
            //查询链属企业信息
            LambdaQueryWrapper<SysCompany> queryWrapper = new LambdaQueryWrapper<>();
            //统一社会信用代码
            queryWrapper.eq(SysCompany::getScySocialCode,scySocialCode);
            //企业名称
            queryWrapper.like(SysCompany::getScyName,scyName);
            //状态00
            queryWrapper.ne(SysCompany::getScyStatus,DELETE_STATE);
            List<SysCompany> list = iSysCompanyService.findSysCompanys(queryWrapper);
            //主键
            String id = IdUtils.fastSimpleUUID();

            String scyId = "";
            if(list.size() > 0) {
                scyId = list.get(0).getScyId();
                String finalScyId = scyId;
                //判断两者是否已经链属
                LambdaQueryWrapper<SysCompanyRel> wrapper = new LambdaQueryWrapper<>();
                String finalHId = hId;
                wrapper.and(j->j.eq(SysCompanyRel::getScrLaunchCompanyId, finalHId).or().eq(SysCompanyRel::getScrReceiveCompanyId, finalHId));
                wrapper.and(j->j.eq(SysCompanyRel::getScrLaunchCompanyId, finalScyId).or().eq(SysCompanyRel::getScrReceiveCompanyId, finalScyId));
                wrapper.and(j->j.eq(SysCompanyRel::getScrStatus,NORMAL_STATE).or().eq(SysCompanyRel::getScrStatus,CONFIRM_STATE));
                List<SysCompanyRel> companyRelList = iSysCompanyRelService.findSysCompanyRels(wrapper);
                if(companyRelList.size() > 0){
                    throw new Exception("已经和此企业链属，不得重复链属");
                }
                SysCompanyRel sysCompanyRel = new SysCompanyRel();
                //主键
                sysCompanyRel.setScrId(id);
                //发起方
                sysCompanyRel.setScrLaunchCompanyId(hId);
                //接收方
                sysCompanyRel.setScrReceiveCompanyId(scyId);
                //联系人
                sysCompanyRel.setScrContarct(scrContarct);
                //联系电话
                sysCompanyRel.setScrContarctPhone(scrContarctPhone);
                //链属关系为供应商
                //发起方为核心企业01
                sysCompanyRel.setScrLaunchType(CONFIRM_STATE);
                //接收方为供应商00
                sysCompanyRel.setScrReceiveType(NORMAL_STATE);
                //状态 01:正常
                sysCompanyRel.setScrStatus(CONFIRM_STATE);
                //创建者
                sysCompanyRel.setCreateBy(userId);
                //创建时间
                sysCompanyRel.setCreateTime(DateUtils.getNowDate());
                relList.add(sysCompanyRel);
            }else {
                //新增链属公司信息
                SysCompanySpare sysCompanySpare = new SysCompanySpare();
                sysCompanySpare.setScpId(id);
                sysCompanySpare.setScpCompanyId(companyId);
                //企业名称
                sysCompanySpare.setScpName(scyName);
                //统一社会信用代码
                sysCompanySpare.setScpSocialCode(scySocialCode);
                //联系人
                sysCompanySpare.setScpContarct(scrContarct);
                //联系电话
                sysCompanySpare.setScpContarctPhone(scrContarctPhone);
                //企业类型 00:供应商
                sysCompanySpare.setScpType(NORMAL_STATE);
                //状态 00:正常
                sysCompanySpare.setScpStatus(NORMAL_STATE);
                //创建人
                sysCompanySpare.setCreateBy(userId);
                //创建时间
                sysCompanySpare.setCreateTime(DateUtils.getNowDate());
                spareList.add(sysCompanySpare);
            }
            successNum++;
        }
        if(CommonUtil.isNotEmpty(userNameList)){
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            return AjaxResult.success(failureMsg.toString());
        }
        //统一校验完成后再进行数据添加
        //链属表表
        for(SysCompanyRel rel : relList){
            iSysCompanyRelService.createSysCompanyRel(rel);
        }
        //链属企业信息表
        for(SysCompanySpare spare : spareList){
            //todo 短信通知
            iSysCompanySpareService.createSysCompanySpare(spare);
        }
        successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条");
        return AjaxResult.success(successMsg.toString());
    }

    /**
     * 导出模板
     * @param sheetName
     * @param fileName
     * @param columnNumber
     * @param columnWidth
     * @param firstColumnName
     * @param columnName
     * @param dataList
     * @return
     * @throws Exception
     */
    public static HSSFWorkbook exportNoResponse(String sheetName, String fileName, int firstColumnNumber, int columnNumber, List<Integer> columnWidth, List<String> firstColumnName,List<String> columnName, List<String> dataList) throws Exception {
        HSSFWorkbook wb = new HSSFWorkbook();
            HSSFSheet sheet = wb.createSheet(sheetName);

            for(int i = 0; i < firstColumnNumber; ++i) {
                for(int j = 0; j <= i; ++j) {
                    if (i == j) {
                        sheet.setColumnWidth(i, (Integer)columnWidth.get(j) * 256);
                    }
                }
            }

            for(int i = 0; i < columnNumber; ++i) {
                for(int j = 0; j <= i; ++j) {
                    if (i == j) {
                        sheet.setColumnWidth(i, (Integer)columnWidth.get(j) * 256);
                    }
                }
            }

        HSSFRow firstRow = sheet.createRow(0);
        firstRow.setHeightInPoints(37.0F);
        HSSFCellStyle firstStyle = wb.createCellStyle();
        firstStyle.setWrapText(true);
        firstStyle.setAlignment(HorizontalAlignment.CENTER);
        firstStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        firstStyle.setBottomBorderColor(IndexedColors.BLACK.index);
        firstStyle.setBorderBottom(BorderStyle.THIN);
        firstStyle.setBorderLeft(BorderStyle.THIN);
        firstStyle.setBorderRight(BorderStyle.THIN);
        firstStyle.setBorderTop(BorderStyle.THIN);
        HSSFFont firstHeaderFont = wb.createFont();
        firstHeaderFont.setBold(true);
        firstHeaderFont.setFontName("黑体");
        firstHeaderFont.setFontHeightInPoints((short)10);
        firstStyle.setFont(firstHeaderFont);

            HSSFRow row = sheet.createRow(1);
            row.setHeightInPoints(37.0F);
            HSSFCellStyle style = wb.createCellStyle();
            style.setWrapText(true);
            style.setAlignment(HorizontalAlignment.CENTER);
            style.setVerticalAlignment(VerticalAlignment.CENTER);
            style.setBottomBorderColor(IndexedColors.BLACK.index);
            style.setBorderBottom(BorderStyle.THIN);
            style.setBorderLeft(BorderStyle.THIN);
            style.setBorderRight(BorderStyle.THIN);
            style.setBorderTop(BorderStyle.THIN);
            HSSFFont headerFont = wb.createFont();
            headerFont.setBold(true);
            headerFont.setFontName("黑体");
            headerFont.setFontHeightInPoints((short)10);
            style.setFont(headerFont);

            int i;
            for(int j = 0; j < firstColumnNumber; ++j) {
                HSSFCell firstCell = firstRow.createCell(j);
                firstCell.setCellValue((String)firstColumnName.get(j));
                firstCell.setCellStyle(firstStyle);
            }
            for(i = 0; i < columnNumber; ++i) {
                HSSFCell cell = row.createCell(i);
                cell.setCellValue((String)columnName.get(i));
                cell.setCellStyle(style);
            }

            for(i = 0; i < dataList.size(); ++i) {
                row = sheet.createRow(i + 3);
                HSSFCellStyle zidonghuanhang = wb.createCellStyle();
                zidonghuanhang.setWrapText(true);
                zidonghuanhang.setVerticalAlignment(VerticalAlignment.CENTER);
                zidonghuanhang.setBottomBorderColor(IndexedColors.BLACK.index);
                zidonghuanhang.setBorderBottom(BorderStyle.THIN);
                zidonghuanhang.setBorderLeft(BorderStyle.THIN);
                zidonghuanhang.setBorderRight(BorderStyle.THIN);
                zidonghuanhang.setBorderTop(BorderStyle.THIN);
                HSSFCellStyle zidonghuanhang2 = wb.createCellStyle();
                zidonghuanhang2.setWrapText(true);
                zidonghuanhang2.setVerticalAlignment(VerticalAlignment.CENTER);
                zidonghuanhang2.setAlignment(HorizontalAlignment.CENTER);
                zidonghuanhang2.setBottomBorderColor(IndexedColors.BLACK.index);
                zidonghuanhang2.setBorderBottom(BorderStyle.THIN);
                zidonghuanhang2.setBorderLeft(BorderStyle.THIN);
                zidonghuanhang2.setBorderRight(BorderStyle.THIN);
                zidonghuanhang2.setBorderTop(BorderStyle.THIN);
                HSSFCell datacell = null;
                datacell = row.createCell(1);
                datacell.setCellValue((String)dataList.get(i));
                datacell.setCellStyle(zidonghuanhang2);
            }
        return wb;
    }

    /**
     * MultipartFile 转 File
     *
     * @param file
     * @throws Exception
     */
    public static File multipartFileToFile(MultipartFile file) throws Exception {

        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除本地临时文件
     * @param file
     */
    public static void delteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }

}
