package com.mvc.service.produce;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mvc.dao.TProductionPlanMapper;
import com.mvc.entity.TProductionPlan;
import com.mvc.entity.TProductionPlanExample;
import com.mvc.model.DeviceAccModel;
import com.mvc.model.ResPageModel;
import com.mvc.model.TaskReviewModel;
import com.mvc.model.produce.*;
import com.mvc.netty.dealconstant.ResourceTag;
import com.mvc.service.taizhang.DeviceAccService;
import com.mvc.utils.DateUtil;
import com.mvc.utils.ImageUtil;
import com.mvc.utils.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.util.Matrix;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

@Service
@Transactional
public class TProductionPlanService {

    @Resource
    private TProductionPlanMapper productionPlanMapper;

    @Resource
    private TProductionPlanDetailService productDetailService;

    @Resource
    private TDeviceSnManagementService deviceSnManagementService;

    @Resource
    private DicProductionPartService dicProductionPartService;

    @Resource
    private DeviceAccService deviceAccService;

    public ResPageModel findAllTProductionPlan(TProductionPlanModel queryModel) {
        TProductionPlanExample example = new TProductionPlanExample();
        TProductionPlanExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotEmpty(queryModel.getPlanName())) {
            criteria.andPlanNameLike(StringUtil.getLikeFormat(queryModel.getPlanName()));
        }
        if (StringUtils.isNotEmpty(queryModel.getCreateMan())) {
            criteria.andCreateManLike(StringUtil.getLikeFormat(queryModel.getCreateMan()));
        }
        if (StringUtils.isNotEmpty(queryModel.getProducer())) {
            criteria.andProducerLike(StringUtil.getLikeFormat(queryModel.getProducer()));
        }
        if (StringUtils.isNotEmpty(queryModel.getActualProducer())) {
            criteria.andActualProducerLike(StringUtil.getLikeFormat(queryModel.getActualProducer()));
        }
        if (StringUtils.isNotEmpty(queryModel.getStatus())) {
            criteria.andStatusEqualTo(queryModel.getStatus());
        }

        example.setOrderByClause(" CREATE_TIME desc ");
        Page<Object> pageObject = PageHelper.startPage(queryModel.getPageNum(), queryModel.getPageSize());
        List<TProductionPlan> list = productionPlanMapper.selectByExample(example);
        List<TProductionPlanModel> resList = new ArrayList<>();

        for (TProductionPlan TProductionPlan : list) {
            TProductionPlanModel model = new TProductionPlanModel();
            BeanUtils.copyProperties(TProductionPlan, model);
            setDetails(model);
            resList.add(model);
        }

        ResPageModel resPageModel = new ResPageModel(resList, pageObject);
        return resPageModel;
    }

    private void setDetails(TProductionPlanModel model) {
        List<TProductionPlanDetailModel> detailModels = productDetailService.findTProductionPlanDetail(model.getId());
        model.setDetails(detailModels);

        Map<Integer, String> map = detailModels.stream().collect(Collectors.toMap(TProductionPlanDetailModel::getDicPartParentId,
                temp -> Integer.toString(temp.getDicPartId())));
        model.setPartMap(map);
    }

    public TProductionPlanModel saveTProductionPlan(TProductionPlanModel model) {
        model.setCreateTime(new Date());
        model.setStatus("0");
        TProductionPlan productionPlan = new TProductionPlan();
        BeanUtils.copyProperties(model, productionPlan);
        productionPlanMapper.insert(productionPlan);
        model.setId(productionPlan.getId());
        saveProductionPlanDetails(model);
        return model;
    }

    /**
     * 保存计划明细
     *
     * @param model
     * @return
     */
    private int saveProductionPlanDetails(TProductionPlanModel model) {
        if (model.getPartMap() == null || model.getPartMap().isEmpty()) return 0;
        int num = 0;
        for (Integer key : model.getPartMap().keySet()) {
            String valeu = model.getPartMap().get(key);
            if (StringUtils.isEmpty(valeu)) {
                continue;
            }
            TProductionPlanDetailModel detailModel = new TProductionPlanDetailModel();
            detailModel.setProductionPlanId(model.getId());
            detailModel.setDicPartParentId(key);
            detailModel.setDicPartId(Integer.valueOf(valeu));
            if (productDetailService.saveTProductionPlanDetail(detailModel) != null) {
                num++;
            }
        }
        return num;
    }

    public TProductionPlanModel updateTProductionPlan(TProductionPlanModel model) {
        TProductionPlan productionPlan = productionPlanMapper.selectByPrimaryKey(model.getId());
        List<TProductionPlanDetailModel> details = productDetailService.findTProductionPlanDetail(model.getId());

        String statusType = "0";//状态类型(记录变为完成或终止)
        if (productionPlan.getStatus().equals("0") && model.getStatus().equals("1")) {//状态从未开始变为生产
            model.setProductionTime(new Date());//更新生产时间
            statusType = model.getStatus();
        } else if (productionPlan.getStatus().equals("1") && model.getStatus().equals("2")) {//从生成变为完成
            model.setFinishedTime(new Date());
            statusType = model.getStatus();
        } else if (!productionPlan.getStatus().equals("3") && model.getStatus().equals("3")) {//从非终止状态变为终止
            model.setFinishedTime(new Date());
            statusType = model.getStatus();
        }

        Map<Integer, String> map = details.stream().collect(Collectors.toMap(TProductionPlanDetailModel::getDicPartParentId,
                temp -> Integer.toString(temp.getDicPartId())));

        if (!map.equals(model.getPartMap())) {//明细有变更,重新保存
            productDetailService.deleteTProductionPlanDetailByPlanId(model.getId());
            saveProductionPlanDetails(model);
        }

        BeanUtils.copyProperties(model, productionPlan);
        int i = productionPlanMapper.updateByPrimaryKey(productionPlan);
        if (i > 0) {
            //当计划从未开始变为生产时，生成设备编码
            if (statusType.equals("1")) {
                deviceSnManagementService.generateDeviceSnByProductionPlan(model);
            } else if (statusType.equals("3")) {//从非终止状态变为终止
                deviceSnManagementService.deleteTDeviceSnManagementByProductionPlanId(model.getId());
            }
        }
        return model;
    }

    public int deleteTProductionPlan(int id) {
        int i = productionPlanMapper.deleteByPrimaryKey(id);
        if (i > 0) {
            productDetailService.deleteTProductionPlanDetailByPlanId(id);//删除明细
        }
        return i;
    }

    /**
     * 根据id查询计划
     *
     * @param id
     * @return
     */
    public TProductionPlanModel getTProductionPlanById(int id) {
        TProductionPlan productionPlan = productionPlanMapper.selectByPrimaryKey(id);
        if (productionPlan != null) {
            TProductionPlanModel model = new TProductionPlanModel();
            BeanUtils.copyProperties(productionPlan, model);
            setDetails(model);
            return model;
        }
        return null;
    }

    /**
     * 根据设备编码查询生产计划PDF格式数据
     *
     * @param deviceSn
     * @return
     */
    public ProductionPlanPdfModel findProductionPlanPdfDataByDeviceSn(String deviceSn) {
        DeviceAccModel deviceAccModel = deviceAccService.findDeviceAccBysn(deviceSn);
        if (deviceAccModel != null && deviceAccModel.getDeviceSnManagementId() != null) {
            TDeviceSnManagementModel deviceSnModel = deviceSnManagementService.findTDeviceSnManagementModelById(deviceAccModel.getDeviceSnManagementId());
            if (deviceSnModel != null && deviceSnModel.getProducttionId() != null) {
                return findProductionPlanForPdf(deviceSnModel.getProducttionId());
            }
        }
        return new ProductionPlanPdfModel();
    }

    /**
     * 查询前台PDF格式的数据
     *
     * @param planId
     * @return
     */
    public ProductionPlanPdfModel findProductionPlanForPdf(int planId) {
        List<TProductionPlanDetailModel> details = productDetailService.findTProductionPlanDetail(planId);

        TProductionPlanModel planModel = getTProductionPlanById(planId);
        ProductionPlanPdfModel pdfModel = new ProductionPlanPdfModel(planModel);

        List<ProductionPlanPdfModel.DetailModel> pdfModels = new ArrayList<>();
        Map<Integer, DicProductionPartModel> partMap = dicProductionPartService.getAllDicProductionPartMap();

        if (planModel.getStatus().equals("1") || planModel.getStatus().equals("2")) {//开始生产或已经完成
            TDeviceSnManagementModel deviceSnModel = deviceSnManagementService.findTDeviceSnManagementModelByPlanId(planId);
            pdfModel.setStartDeviceSn(deviceSnModel.getStartCode());
            pdfModel.setEndDeviceSn(deviceSnModel.getEndCode());
        } else {
            pdfModel.setStartDeviceSn("-");
            pdfModel.setEndDeviceSn("-");
        }

        String key = "";
        String value = "";
        ProductionPlanPdfModel.DetailModel pdfDetailModel = null;

        int colIndex = 1;
        for (int i = 0; i < details.size(); i++) {
            TProductionPlanDetailModel detail = details.get(i);

            if (!partMap.containsKey(detail.getDicPartId())) {
                continue;
            }

            //单独处理系统保留属性(涉及SN编码规则)
            if (partMap.get(detail.getDicPartParentId()).getSystemFlag() == 1) {
                pdfModel.setTypeName(partMap.get(detail.getDicPartId()).getPartName());
                continue;
            }

            key = partMap.get(detail.getDicPartParentId()).getPartName();
            value = partMap.get(detail.getDicPartId()).getPartName();

            if (colIndex == 1) {
                pdfDetailModel = new ProductionPlanPdfModel.DetailModel();
                pdfDetailModel.setKey1(key);
                pdfDetailModel.setValue1(value);
            } else if (colIndex == 2) {
                pdfDetailModel.setKey2(key);
                pdfDetailModel.setValue2(value);
                pdfModels.add(pdfDetailModel);
            } /*else if (colIndex == 3) {
                pdfDetailModel.setKey3(key);
                pdfDetailModel.setValue3(value);

            }*/
            colIndex++;
            if (colIndex > 2) {
                colIndex = 1;
            }
        }

        //数量不被3整除的情况
        if (pdfDetailModel != null && !pdfModels.contains(pdfDetailModel)) {
            pdfModels.add(pdfDetailModel);
        }

        pdfModel.setDetails(pdfModels);

        return pdfModel;
    }

    public static void main(String[] args) throws Exception {

    }
}
