package com.foreverwin.mesnac.production.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foreverwin.mesnac.common.dto.UsrDto;
import com.foreverwin.mesnac.common.enums.HandleEnum;
import com.foreverwin.mesnac.common.service.UserService;
import com.foreverwin.mesnac.common.util.StringUtil;
import com.foreverwin.mesnac.meapi.mapper.SfcMapper;
import com.foreverwin.mesnac.meapi.model.Sfc;
import com.foreverwin.mesnac.production.mapper.SfcScrapMapper;
import com.foreverwin.mesnac.production.mapper.SplitSfcMapper;
import com.foreverwin.mesnac.production.model.SfcScrap;
import com.foreverwin.mesnac.production.service.PodTemplateService;
import com.foreverwin.mesnac.production.service.SfcScrapService;
import com.foreverwin.modular.core.exception.BaseException;
import com.foreverwin.modular.core.meext.MEServices;
import com.foreverwin.modular.core.util.CommonMethods;
import com.foreverwin.modular.core.util.FrontPage;
import com.sap.me.production.ScrapDeleteServiceInterface;
import com.sap.me.production.ScrapSfcRequest;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 产品报废 服务实现类
 * </p>
 *
 * @author zjw
 * @since 2021-07-30
 */
@Service
@Transactional(rollbackFor = Exception.class)
@ConditionalOnProperty(prefix = "exportDocument", value = {"enabled"}, matchIfMissing = true)
public class SfcScrapServiceImpl extends ServiceImpl<SfcScrapMapper, SfcScrap> implements SfcScrapService {


    @Value("${exportDocument.filePath}")
    private String filePath;

    @Value("${exportDocument.outputPath}")
    private String outputPath;

    @Value("${exportDocument.template}")
    private String templateDocument;

    @Autowired
    private SfcScrapMapper sfcScrapMapper;

    @Autowired
    private SfcMapper sfcMapper;

    @Autowired
    private PodTemplateService podTemplateService;

    @Autowired
    private UserService userService;

    @Autowired
    private SplitSfcMapper splitSfcMapper;

    @Value("${ws.erp.enabled}")
    private boolean enabled;

    @Override
    public IPage<SfcScrap> selectPage(FrontPage<SfcScrap> frontPage, SfcScrap sfcScrap) {
        QueryWrapper<SfcScrap> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(sfcScrap);
        return super.page(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<SfcScrap> selectList(SfcScrap sfcScrap) {
        QueryWrapper<SfcScrap> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(sfcScrap);
        return super.list(queryWrapper);
    }



    @Override
    public List<SfcScrap> scrap(HashMap<String,Object> param) {
        String user = CommonMethods.getUser();
        LocalDateTime now = LocalDateTime.now();
        String reason = (String)param.get("reason");
        String site = (String)param.get("site");

        //类型
        List<String> _type = (List<String>)param.get("type");
        StringBuilder type = new StringBuilder();
        for (int i = 0; i < _type.size(); i++) {
            if(i == _type.size() - 1){
                type.append(_type.get(i));
            }else{
                type.append(_type.get(i)).append(",");
            }
        }

        String str = JSONUtil.toJsonStr(param.get("sfcScrap"));
        List<SfcScrap> _sfcScrapList = JSONArray.parseArray(str, SfcScrap.class);
        List<SfcScrap> sfcScrapsList = new ArrayList<>();


        ScrapDeleteServiceInterface scrapDeleteServiceInterface = null;
        //mes的公共接口
        try{
            scrapDeleteServiceInterface = MEServices.create("com.sap.me.production", "ScrapDeleteService", CommonMethods.getSite());
        }catch (Exception e){
            throw new BaseException("调用mes公共接口失败"+e.getMessage());
        }

        for (SfcScrap sfcScraps :
                _sfcScrapList) {
            SfcScrap sfcScrap = new SfcScrap();
            sfcScrap.setHandle(HandleEnum.SFC_SCRAP.getHandle(site,sfcScraps.getSfc()));
            sfcScrap.setSite(site);
            sfcScrap.setSfc(sfcScraps.getSfc());
            //设置数量用,并判断该sfc是否有效
            Sfc sfc = sfcMapper.selectById(HandleEnum.SFC.getHandle(site,sfcScrap.getSfc()));
            if(sfc == null){
                throw new BaseException("该sfc不存在，不能报废");
            }

            if(!StringUtil.isBlank(sfcScraps.getOperation())){
                String[] split = sfcScraps.getOperation().split("/");
                sfcScrap.setOperation(split[0]);
                sfcScrap.setStepId(split[1]);
            }
            sfcScrap.setType(type.toString());
            sfcScrap.setReason(reason);
            //判断该SFC的数量是否>=0;
            if(sfc.getQty() <= 0){
                throw new BaseException("该sfc的数量为0，不能报废");
            }
            sfcScrap.setQty(sfc.getQty());
            sfcScrap.setDutyUser(sfcScraps.getDutyUser());
            sfcScrap.setCreatedUser(user);
            sfcScrap.setCreatedDateTime(now);
            sfcScrap.setModifiedUser(user);
            sfcScrap.setModifiedDateTime(now);

            //向生产派工那边发送数据
            if (enabled) {
                podTemplateService.sendErp(sfcScrap.getSfc(), sfcScrap.getStepId(), BigDecimal.valueOf(0L), BigDecimal.valueOf(sfcScrap.getQty()), BigDecimal.valueOf(0L));
            }
            try{
                //调用mes公共接口，报废
                ScrapSfcRequest scrapSfcRequest = new ScrapSfcRequest();
                scrapSfcRequest.setSfcRef(sfc.getHandle());
                scrapSfcRequest.setQuantity(BigDecimal.valueOf(sfcScrap.getQty()));
                scrapDeleteServiceInterface.scrapSfc(scrapSfcRequest);
            }catch (Exception e){
                throw new BaseException("调用mes公共接口失败"+e.getMessage());
            }

            sfcScrapsList.add(sfcScrap);
        }
        //保存
        this.saveBatch(sfcScrapsList);
        return sfcScrapsList;
    }


    @Override
    public void generatorWord(String shopOrder, String sfc, HttpServletResponse response, HttpServletRequest request) {
        String site = CommonMethods.getSite();
        String user = CommonMethods.getUser();
        String locale = LocaleContextHolder.getLocale().getLanguage();

        //判断该产品条码是否已经报废
        if(sfcScrapMapper.selectById(HandleEnum.SFC_SCRAP.getHandle(site,sfc)) == null){
            throw new BaseException("该产品还没有报废");
        }


        /**
         * 年  YEAR
         * 月 MONTH
         * 日 DAY
         * SHOP_ORDER 生产订单号
         * WORK_CENTER 部门
         * OPERATION 操作者
         * ITEM 物料编码
         * WORK_ORDER 工作令
         * 产品名称 SFC
         * 零件图号 DWG_NO
         * 零件名称 ITEM_DESCRIPTION
         * 废品件数 QTY
         * 责任者
         * 报废工序 OPERATION
         * 废品原因 REASON
         * 废品标记 SCRAP_MARK
         * 工废 GF
         * 料废 LF
         * 其他 QT
         * 工件重量 WEIGHT
         * 评定意见 OPINION
         *
         */
        LocalDateTime now = LocalDateTime.now();
        int year = now.getYear();
        int month = now.getMonth().getValue();
        int day = now.getDayOfMonth();
        Map<String, String> wordMap = sfcScrapMapper.generatorWord(site,locale ,shopOrder, sfc);
        wordMap.put("SCRAP_MARK","线下质量贴红色标签");

        List<UsrDto> list = userService.findList(user);
        if(list.size() > 0){
            wordMap.put("OPERATOR",list.get(0).getFullName());
        }
        wordMap.put("GF",(wordMap.get("TYPE").contains("GF"))? "✔": " ");
        wordMap.put("LF",(wordMap.get("TYPE").contains("LF"))? "✔": " ");
        wordMap.put("OT",(wordMap.get("TYPE").contains("OT"))? "✔": " ");
        wordMap.put("OPINION","报废");
        wordMap.put("YEAR",year + "");
        wordMap.put("MONTH",month + "");
        wordMap.put("DAY",day + "");
        File outFile = null;
        try{

            Configuration configuration = new Configuration(new Version("2.3.30"));
            configuration.setDefaultEncoding("utf-8");
            //指定文件所在的路径
            configuration.setDirectoryForTemplateLoading(new File(filePath));
            //输出文档路径即名称
            outFile = new File(outputPath+sfc+".doc");
            //如果输出目标文件夹不存在，则创建
            if (!outFile.getParentFile().exists()){
                outFile.getParentFile().mkdirs();
            }
            //以utf-8的编码读取ftl文件
            Template template = configuration.getTemplate(templateDocument, "utf-8");
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 1024000);
            template.process(wordMap, out);
            out.close();
        }catch(Exception e){
            throw new BaseException("导出word文档失败"+e.getMessage());
        }


        String fileName = outFile.getName();
        String downLoadPath = outFile.getPath();
        java.io.BufferedInputStream bis = null;
        java.io.BufferedOutputStream bos = null;
        try{
            if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else {
                fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try {
            long fileLength = new File(downLoadPath).length();
            response.setContentType("application/x-msdownload;");
            response.setHeader("Content-disposition", "attachment; filename=" + fileName);
            response.setHeader("Content-Length", String.valueOf(fileLength));
            response.setContentType("application/octet-stream;charset=UTF-8");
            bis = new BufferedInputStream(new FileInputStream(downLoadPath));
            bos = new BufferedOutputStream(response.getOutputStream());
            byte[] buff = new byte[2048];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
        } catch (Exception e) {
//            errorMessage=e.getMessage();
            e.printStackTrace();
        } finally {
            if (bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}