package com.sunda.spmsweb.ordercontroller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmsorder.entity.MaterialCategory;
import com.sunda.spmsorder.entity.MaterialSap;
import com.sunda.spmsorder.entity.MaterialSpms;
import com.sunda.spmsorder.service.IFileOperationService;
import com.sunda.spmsorder.service.IMaterialCategoryService;
import com.sunda.spmsorder.service.IMaterialSapService;
import com.sunda.spmsorder.service.IMaterialSpmsService;
import com.sunda.spmsweb.util.JWTUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * <p>
 * 物料表SAP 前端控制器
 * </p>
 *
 * @author Wayne
 * @since 2020-11-13
 */
@RestController
@RequestMapping("/materialSap")
@Api(tags = "SAP 物料基本信息接口", description = "物料基本信息接口")
public class MaterialSapController {

    @Autowired
    IMaterialSapService iMaterialSapService;
    
    @Autowired
    private IFileOperationService iFileOperationService;
    
    @Autowired
    private IMaterialCategoryService iMaterialCategoryService;
    
    @Autowired
    private IMaterialSpmsService iMaterialSpmsService;

    @GetMapping("/getMaterialSapXM")
    @ApiOperation(value="获取SAP物料信息",notes ="获取SAP物料信息")
    public ResponseResult getMaterialSapXM(@RequestParam String materialNo){
        return iMaterialSapService.getMaterialSapXM(materialNo);
    }

    @RequestMapping("/getMaterialSap")
    @ApiOperation(value = "获取SAP物料目录信息", notes = "1.获取SAP一个物料所属目录信息，实例 materialNo = 210023579，返回所属目录结构信息；\n" +
            "2.如果该物料目录信息为空，则返回该物料详细信息；\n" +
            "3.传入空字符串，则返回所有没有目录的物料详细信息；\n" +
            "4.增加搜索限制 AND SAP.SPMS_MARK = 'X' AND SAP.IS_DELETE != 'X' AND SAP.MATERIAL_STATUS = ' ' \n" +
            "20220225 修改，此接口可按照物料描述模糊搜索，请求参数不变，可接受描述搜索", httpMethod = "POST")
    @RequiresPermissions("materialSap-getMaterialSap")
    public ResponseResult getMaterialSap(@RequestParam(defaultValue = "") String materialNo,
                                         @RequestParam(defaultValue = "1") int pageNo,
                                         @RequestParam(defaultValue = "20") int pageSize) {
        try {
            return iMaterialSapService.getMaterialSap(materialNo, pageNo, pageSize);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error("请求数据失败").add("error", e.getMessage());
        }
    }

    /**
     * 20210318 弃用 - Wayne Wu
     *
     * @RequestMapping("/searchMaterialSap")
     * @ApiOperation(value = "模糊/精确查询物料信息(无库存 含长协)", notes = "模糊/精确查询物料信息，分页,\n" +
     * "可选输入字段，目录编号：categoryId = 100101 \n" +
     * "可选输入物料编号精确查找：materialNoList = 210023454,210036868,130011856\n" +
     * "可选输入 materialZhDesc，materialEnDesc，模糊查询", httpMethod = "POST")
     * public ResponseResult searchMaterialSap(@RequestParam(defaultValue = "1") int pageNo,
     * @RequestParam(defaultValue = "20") int pageSize,
     * @RequestParam(required=false) String categoryId,
     * @RequestParam(required=false) String materialNoList,
     * @RequestParam(required = false) String materialZhDesc,
     * @RequestParam(required=false) String materialEnDesc){
     * try {
     * if (pageNo <= 0 || pageSize <= 0){
     * return ResponseResult.error("参数错误请重试！");
     * }
     * return ResponseResult.success().add("materialSapList", iMaterialSapService.searchMaterialSap(pageNo, pageSize, categoryId, materialNoList, materialZhDesc, materialEnDesc));
     * }catch (Exception e){
     * return ResponseResult.error(e.getMessage());
     * }
     * }
     */

    @RequestMapping("/searchMaterialSapNoContract")
    @ApiOperation(value = "模糊/精确查询物料信息(无库存 无长协)", notes = "模糊/精确查询物料信息，分页\n" +
            "可选输入字段，目录编号：categoryId = 100101\n" +
            "可选输入物料编号精确查找：materialNoList = 130011853,210023454\n" +
            "可选输入 materialZhDesc，materialEnDesc，模糊查询\n" +
            "增加搜索限制 AND SAP.SPMS_MARK = 'X' AND SAP.IS_DELETE != 'X' AND SAP.MATERIAL_STATUS = ' ' ", httpMethod = "POST")
    public ResponseResult searchMaterialSapNoContract(@RequestParam(defaultValue = "1") int pageNo,
                                                      @RequestParam(defaultValue = "20") int pageSize,
                                                      @RequestParam(required = false) String categoryId,
                                                      @RequestParam(required = false) String materialNoList,
                                                      @RequestParam(required = false) String materialZhDesc,
                                                      @RequestParam(required = false) String materialEnDesc,
                                                      @RequestParam(required = false) String productLevelDesc,
                                                      @RequestParam(required = false) String specs,
                                                      @RequestParam(required = false) String brand,
                                                      @RequestParam(required = false) String purchaseLocation) {
        try {
            if (pageNo <= 0 || pageSize <= 0) {
                return ResponseResult.error("参数错误请重试！");
            }
            return ResponseResult.success().add("materialSapList", iMaterialSapService.searchMaterialSapNoContract(pageNo, pageSize, categoryId, materialNoList, materialZhDesc, materialEnDesc,productLevelDesc,specs,brand, purchaseLocation));
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }

    @RequestMapping("/searchMaterialSapNoContractGlobal")
    @ApiOperation(value = "模糊查询物料信息(无库存 无长协 全局)", notes = "模糊查询物料信息，分页\n" +
            "可选输入物料编号模糊查找：materialNoList = 130011853\n" +
            "可选输入 materialZhDesc，materialEnDesc，模糊查询\n" +
            "增加搜索限制 AND SAP.SPMS_MARK = 'X' AND SAP.IS_DELETE != 'X' AND SAP.MATERIAL_STATUS = ' ' ", httpMethod = "POST")
    @RequiresPermissions("materialSap-searchMaterialSapNoContractGlobal")
    public ResponseResult searchMaterialSapNoContractGlobal(@RequestParam(defaultValue = "1") int pageNo,
                                                      @RequestParam(defaultValue = "20") int pageSize,
                                                      @RequestParam(required = false) String keyword,
                                                      @RequestParam(required = false) String searchInfos) {
        try {
            if (pageNo <= 0 || pageSize <= 0) {
                return ResponseResult.error("参数错误请重试！");
            }
            return ResponseResult.success().add("materialSapList", iMaterialSapService.searchMaterialSapNoContractGlobal(pageNo, pageSize, keyword, searchInfos));
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }

    @RequestMapping("/getMaterialSapInventory")
    @ApiOperation(value = "模糊/精确查询物料信息(含指定仓库库存 无长协)", notes = "模糊/精确查询物料信息(含库存 无长协)\n" +
            "可选输入字段，目录编号：categoryId = 100101 \n" +
            "工厂代码必输：werks = GH01\n" +
            "仓库代码可选输入，为空则忽略仓库代码字段；示例：whsList = 1001,1002\n" +
            "可选输入物料编号精确查找：materialNoList = 130011853,210023454\n" +
            "可选输入 materialZhDesc，materialEnDesc，模糊查询", httpMethod = "POST")
    public ResponseResult getMaterialSapInventory(@RequestParam(defaultValue = "1") int pageNo,
                                                  @RequestParam(defaultValue = "20") int pageSize,
                                                  @RequestParam(required = true) String werks,
                                                  @RequestParam(required = false) String whsStr,
                                                  @RequestParam(required = false) String categoryId,
                                                  @RequestParam(required = false) String materialNoList,
                                                  @RequestParam(required = false) String materialZhDesc,
                                                  @RequestParam(required = false) String materialEnDesc,
                                                  @RequestParam(required = false) String productLevelDesc,
                                                  @RequestParam(required = false) String specs,
                                                  @RequestParam(required = false) String brand) {
        try {
            if (pageNo <= 0 || pageSize <= 0 || werks.trim().length() == 0) {
                return ResponseResult.error("参数错误请重试！");
            }
            return ResponseResult.success().add("materialSapList", iMaterialSapService.getMaterialSapInventory(pageNo, pageSize, werks, whsStr, categoryId, materialNoList, materialZhDesc, materialEnDesc,productLevelDesc,specs,brand));
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }

    /** 20210318 弃用 - Wayne Wu
     @RequestMapping("/getMaterialSapInventoryInfo")
     @ApiOperation(value = "模糊/精确查询物料信息(含库存 含长协)", notes = "模糊/精确查询物料信息(含库存 含长协)\n" +
     "可选输入字段，目录编号：categoryId = 100101 \n" +
     "工厂代码必输：werks = GH01\n" +
     "可选输入物料编号精确查找：materialNoList = 130011853,210023454\n" +
     "可选输入 materialZhDesc，materialEnDesc，模糊查询", httpMethod = "POST")
     public ResponseResult getMaterialSapInventoryInfo(@RequestParam(defaultValue = "1") int pageNo,
     @RequestParam(defaultValue = "20") int pageSize,
     @RequestParam(required = true) String werks,
     @RequestParam(required=false) String categoryId,
     @RequestParam(required=false) String materialNoList,
     @RequestParam(required = false) String materialZhDesc,
     @RequestParam(required=false) String materialEnDesc){
     try {
     if (pageNo <= 0 || pageSize <= 0 || werks.trim().length() == 0){
     return ResponseResult.error("参数错误请重试！");
     }
     return ResponseResult.success().add("materialSapList", iMaterialSapService.getMaterialSapInventoryInfo(pageNo, pageSize, werks, categoryId, materialNoList, materialZhDesc, materialEnDesc));
     }catch (Exception e){
     return ResponseResult.error(e.getMessage());
     }
     }
     */

    @GetMapping("/getMaterialDataFromSap")
    @ApiOperation(value="实时从SAP获取物料更新接口",notes ="实时从SAP获取物料更新接口\n" +
            "入参为用户输入日期：dataDate = 2021-05-27")
    @RequiresPermissions("materialSap-getMaterialDataFromSap")
    public ResponseResult getMaterialDataFromSap(String dataDate){
        String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
        return iMaterialSapService.getMaterialDataFromSap(dataDate, userId);
    }

    @PostMapping("/getMaterialDataFromSapRecord")
    @ApiOperation(value="查询物料获取接口操作记录",notes ="查询物料获取接口操作记录\n" +
            "示例参数：\n" +
            "{\n" +
            "\t\"userId\": \"999947\",\n" +
            "\t\"beginDate\": \"\",\n" +
            "\t\"endDate\": \"\",\n" +
            "\t\"pageNo\": \"1\",\n" +
            "\t\"pageSize\": \"20\"\n" +
            "}")
    public ResponseResult getMaterialDataFromSapRecord(@RequestBody JSONObject doc){
        return iMaterialSapService.getMaterialDataFromSapRecord(doc);
    }

    @GetMapping("/getAllMaterialX")
    @ApiOperation(value="获取SPMS系统全部备件物料信息",notes ="实时从SAP获取物料更新接口\n")
    public ResponseResult getAllMaterialX(){
        //String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
        return iMaterialSapService.getAllMaterialX();
    }
    
    @SuppressWarnings({ "resource", "deprecation"})
	@RequestMapping("/uploadMaterialSpmsCategory")
    @ApiOperation(value = "EXCEL导入备件物料分类", notes = "请求参数示例：{ avatar: file}", httpMethod = "POST")
    @RequiresPermissions("materialSap-uploadMaterialSpmsCategory")
    @ResponseBody
    public ResponseResult uploadMaterialSpmsCategory(@RequestParam(value = "avatar") MultipartFile avatar){
    	if (avatar.isEmpty()) {
            return ResponseResult.error("不能上传空文件");
        }else {
        	Sheet sheet = null;
            Row row;
            File temp = null;
            InputStream is;
            try {
            	// 另存文件名
                SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
                Calendar calendar = Calendar.getInstance();
                String fileName = df.format(calendar.getTime()) + avatar.getOriginalFilename();
                // 1.附件缓存路径
                String filePath = iFileOperationService.saveMaterialApplicationPic(avatar, fileName);
                temp = new File(filePath);
                is = new FileInputStream(temp);
                Workbook wb;
                if (temp.getName().toLowerCase().endsWith(".xls")) {
                    wb = new HSSFWorkbook(is);
                    sheet = wb.getSheetAt(0);// 读取第一个sheet
                } else if (temp.getName().toLowerCase().endsWith(".xlsx")) {
                    wb = new XSSFWorkbook(is);
                    sheet = wb.getSheetAt(0);// 读取第一个sheet
                } else {
                    return ResponseResult.error("只支持excel格式文件！");
                }
                // 得到总行数
                int rowNum = sheet.getLastRowNum();
                if (rowNum <= 1) {
                    return ResponseResult.error("请检查文件内容是否为空！");
                }
                try {
                	List<MaterialSpms> insertList = new ArrayList<MaterialSpms>();
                	for (int i = 2; i <= rowNum; i++) {//
                        row = sheet.getRow(i);
                        // 手工转化
                        if (row == null){
                            continue;
                        }
                        MaterialSpms vo = new MaterialSpms();
                        // 物料编码
                        Cell cell0 = row.getCell(0);
                        if (cell0 == null) {
                        	return ResponseResult.error("第"+(i+1)+"行“物料编码”不能为空！");
                        }
                        cell0.setCellType(CellType.STRING);
                        String materialNo = cell0.getRichStringCellValue().getString();
                        // 判断物料号是否存在
                        MaterialSap materialInfo = iMaterialSapService.getMaterialInfo(materialNo);
                        if (materialInfo == null) {
                        	return ResponseResult.error("第"+(i+1)+"行物料未同步SPMS，请检查");
                        }
                        vo.setMaterialNo(materialNo);
                        // 一级目录
                        Cell cell2 = row.getCell(2);
                        if (cell2 == null) {
                        	return ResponseResult.error("第"+(i+1)+"行“一级目录”不能为空！");
                        }
                        cell2.setCellType(CellType.STRING);
                        String firstCategoryName = cell2.getRichStringCellValue().getString();
                        // 查询一级目录是否存在
                        MaterialCategory firstCate = iMaterialCategoryService.getOne(new QueryWrapper<MaterialCategory>()
                        		.eq("CATEGORY_LEVEL", 1).eq("CATEGORY_NAME", firstCategoryName));
                        if (firstCate == null) {
                        	return ResponseResult.error("第"+(i+1)+"行“一级目录”不存在，请检查");
                        }
                        // 二级目录
                        Cell cell3 = row.getCell(3);
                        if (cell3 == null) {
                        	return ResponseResult.error("第"+(i+1)+"行“二级目录”不能为空！");
                        }
                        cell3.setCellType(CellType.STRING);
                        String secondCategoryName = cell3.getRichStringCellValue().getString();
                        MaterialCategory secondCate = iMaterialCategoryService.getOne(new QueryWrapper<MaterialCategory>()
                        		.eq("CATEGORY_LEVEL", 2).eq("CATEGORY_NAME", secondCategoryName).eq("PARENT_ID", firstCate.getCategoryId()));
                        if (secondCate == null) {
                        	return ResponseResult.error("第"+(i+1)+"行“二级目录”不存在，请检查");
                        }
                        // 三级目录
                        Cell cell4 = row.getCell(4);
                        if (cell4 == null) {
                        	return ResponseResult.error("第"+(i+1)+"行“三级目录”不能为空！");
                        }
                        cell4.setCellType(CellType.STRING);
                        String thirdCategoryName = cell4.getRichStringCellValue().getString();
                        MaterialCategory thirdCate = iMaterialCategoryService.getOne(new QueryWrapper<MaterialCategory>()
                        		.eq("CATEGORY_LEVEL", 3).eq("CATEGORY_NAME", thirdCategoryName).eq("PARENT_ID", secondCate.getCategoryId()));
                        if (thirdCate == null) {
                        	return ResponseResult.error("第"+(i+1)+"行“三级目录”不存在，请检查");
                        }
                        vo.setCategoryId(thirdCate.getCategoryId());
                        vo.setUuid(UUID.randomUUID().toString().replaceAll("-","").toLowerCase());
                        insertList.add(vo);
                	}  
                	if (CollectionUtils.isNotEmpty(insertList)) {
                		// 根据物料号去重
                		List<String> materialList = insertList.stream().map(MaterialSpms::getMaterialNo).distinct().collect(Collectors.toList());
                		// 根据物料号删除物料分类信息
                		iMaterialSpmsService.deleteByMaterialNoList(materialList);
                		// 根据三级目录ID、物料号去重，防止EXCEL中有重复的数据
                		ArrayList<MaterialSpms> collect = insertList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item->item.getCategoryId()+"_"+item.getMaterialNo()))), ArrayList::new));
                		iMaterialSpmsService.saveBatch(collect);
                	}
                	return ResponseResult.success("导入成功");
                } catch (Exception e) {
                    return ResponseResult.error(e.getMessage());
                }
            }catch (Exception e) {
                return ResponseResult.error(e.getMessage());
            } finally {
                if (temp != null) {
                    boolean newFile = temp.delete();
                    if(!newFile){
                    }
                }
            }
        }
    }

}
