package net.vtstar.zhongtong.avi.equipment.service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import jcifs.smb.NtlmPasswordAuthentication;
import net.vtstar.scada.base.equipmgt.service.EquipDataChannelService;
import net.vtstar.user.mybatis.provider.Operation;
import net.vtstar.user.mybatis.provider.WhereFilter;
import net.vtstar.user.search.service.SearchService;
import net.vtstar.utils.asserts.ParamAssert;
import net.vtstar.zhongtong.avi.equipment.domain.EquipInfo;
import net.vtstar.zhongtong.avi.equipment.domain.Program;
import net.vtstar.zhongtong.avi.equipment.domain.vo.ProgramTransferVO;
import net.vtstar.zhongtong.avi.equipment.mapper.BasicInfoMapper;
import net.vtstar.zhongtong.avi.equipment.mapper.EquipmentDataMapper;
import net.vtstar.zhongtong.avi.equipment.mapper.RuntimeRecordMapper;
import net.vtstar.zhongtong.avi.gateway.painting.domain.PolishingRoomMachine;
import net.vtstar.zhongtong.avi.global.web.domain.ShowField;
import net.vtstar.zhongtong.avi.monitoring.domain.StationPassInfo;
import net.vtstar.zhongtong.avi.monitoring.mapper.StationPassInfoMapper;
import net.vtstar.zhongtong.avi.utils.SmbFileUtil;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class EquipmentService {

    @Autowired
    private EquipmentDataMapper dataMapper;
    @Autowired
    private RuntimeRecordMapper runtimeRecordMapper;
    @Resource(name = "classNameCache")
    private Cache classNameCache;
    @Resource(name = "showFieldCache")
    private Cache showFieldCache;
    @Autowired
    private SearchService searchService;
    @Autowired
    private BasicInfoMapper basicInfoMapper;
    @Autowired
    private EquipDataChannelService equipDataChannelService;

    @Autowired
    private StationPassInfoMapper passInfoMapper;

    private String baseUrl = "D:/scada/program/";

    public List<Map<String, Object>> findRealTimeData(JSONObject pageFilter) {
        PageHelper.startPage(pageFilter.getIntValue("pageNum"), pageFilter.getIntValue("pageSize"));
        String searchCode = pageFilter.getString("searchCode");
        Class searchCodeClazz = classNameCache.get(searchCode, Class.class);
        if (searchCode == null) {
            return new ArrayList<>();
        }
        if ("POLISHING_ROOM".equals(searchCode)) {
            return runtimeRecordMapper.findJoin(searchService.pageFilter2Filter(pageFilter, new WhereFilter() {{
                addJoin(PolishingRoomMachine.class, "machine_id", EquipInfo.class, "id");
                addFilter(PolishingRoomMachine.class, "status", Operation.IS, "null");
                addFilter(PolishingRoomMachine.class, "group_code", Operation.EQUAL, "1");
            }}), searchCodeClazz);

        }
        return dataMapper.findJoin(searchService.pageFilter2Filter(pageFilter, new WhereFilter() {{
            addFilter("status", Operation.EQUAL_GREATER_THAN, 1);
        }}), searchCodeClazz);
    }

    public void orderExport(JSONObject pageFilter, HttpServletResponse response) throws IOException {
        String searchCode = pageFilter.getString("searchCode");
        List<ShowField> showFields = showFieldCache.get(searchCode, ArrayList<ShowField>::new);
        Class itemClazz = classNameCache.get(searchCode, Class.class);
        List<Map<String, Object>> result = dataMapper.findJoin(searchService.pageFilter2Filter(pageFilter), itemClazz);
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet("采集数据");
        CellStyle cellStyle = wb.createCellStyle();
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cellStyle.setBorderTop(BorderStyle.DASHED);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);

        cellStyle.setTopBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        cellStyle.setBottomBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        cellStyle.setLeftBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        cellStyle.setRightBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());

        XSSFFont titleFont = wb.createFont();
        titleFont.setFontHeight(24);
        titleFont.setBold(true);

        int rowNumber = 0;
        XSSFRow row = sheet.createRow(rowNumber);
        for (int i = 0; i < showFields.size(); i++) {
            sheet.setColumnWidth(i, 5000);
            row.createCell(i).setCellValue(showFields.get(i).getLabel());
        }
        for (Map<String, Object> item : result) {
            rowNumber++;
            XSSFRow xssfRow = sheet.createRow(rowNumber);
            for (int i = 0; i < showFields.size(); i++) {
                Object value = item.get(showFields.get(i).getValue());
                xssfRow.createCell(i).setCellValue(null == value ? "" : String.valueOf(value));
            }
        }
        response.setCharacterEncoding("utf-8");
        String name = classNameCache.get(searchCode + "name", String.class);
        if (StringUtils.isEmpty(name)) {
            name = "监控数据表";
        }
        String filename = URLEncoder.encode(name, "utf-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename=" + filename + ".xlsx");
        response.setHeader("filename", filename + ".xlsx");

        try {
            ServletOutputStream outputStream = response.getOutputStream();
            wb.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            throw new IOException("报表导出失败!");
        }
    }

    public List<EquipInfo> findMachineByType(String equipType) {
        return basicInfoMapper.findList(new WhereFilter() {{
            addFilter("equip_type", Operation.EQUAL, equipType);
        }}, EquipInfo.class);
    }

    public Program saveNcFile(MultipartFile ncFile) {
        ParamAssert.isTrue(ncFile != null && !ncFile.isEmpty(),
                "文件不能为空！");
        File fileHome = new File(baseUrl);
        if (!fileHome.exists()) {
            fileHome.mkdirs();
        }
        String fileName = ncFile.getOriginalFilename();
        File saveNcFile = new File(baseUrl + fileName);
        if (saveNcFile.exists()) {
            saveNcFile.delete();
        }
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(saveNcFile);
            outputStream.write(ncFile.getBytes());
            outputStream.flush();
            Program program = new Program();
            program.setName(fileName);
            program.setPath(baseUrl + fileName);
            return program;
        } catch (Exception e) {
            throw new IllegalArgumentException("文件上传失败！");
        } finally {
            if (null != outputStream) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    throw new IllegalArgumentException("IO错误!");
                }
            }
        }
    }

    public boolean putFile(ProgramTransferVO transferVO) {
        String ip = "";
        String path = "";
        NtlmPasswordAuthentication auth = null;
        switch (transferVO.getEquipCode()) {
            case "071603-19":
                ip = "10.1.4.120";
                path = "smb://" + ip + "/数控下料/";
                break;
            case "071603-28":
                //PING不通
                ip = "10.1.25.114";
                path = "smb://" + ip + "/数控下料/";
                break;
            case "071603-14":
                ip = "10.1.4.107";
                path = "smb://" + ip + "/数控下料/";
                break;
            case "071603-25":
                ip = "10.1.4.129";
                path = "smb://admin:123456@" + ip + "/数控下料/";
                break;
            //TODO: 网口不通
            case "071603-13":
                ip = "10.1.4.108";
                path = "smb://" + ip + "/数控下料/";
                break;
            case "071603-17":
                ip = "10.1.4.106";
                path = "smb://" + ip + "/数控下料/";
                break;
            //三维激光切割机
            case "076707-105":
                ip = "10.1.25.175";
                path = "smb://" + ip + "/NCPrg/";
                break;
            //激光切管机
            case "076707-146":
                ip = "10.1.25.177";
                path = "smb://" + ip + " /NCPrg/";
                break;
            //激光切管机
            case "076707-166":
                ip = "10.1.25.176";
                path = "smb://" + ip + "/NCProg/";
                break;
            //平板激光切割机
            case "076707-114":
                //NCPrg, PA8000
                ip = "10.1.25.178";
                path = "smb://" + ip + "/NCPrg/";
                break;
            //平板激光切割机
            case "076707-167":
                ip = "10.1.25.179";
                path = "smb://" + ip + "/NCPrg/";
                break;
            //平板激光切割机
            case "076707-178":
                ip = "10.1.25.180";
                path = "smb://" + ip + "/NcProg/";
                break;
            //平板激光切割机
            case "076707-177":
                ip = "10.1.25.181";
                path = "smb://" + ip + "/NcProng/";
                break;
        }
        return SmbFileUtil.smbPut(path, transferVO.getFilePath(), auth);
    }

    public List<EquipInfo> findByShopCode(String workshopCode) {
        if (StringUtils.isEmpty(workshopCode)) {
            return basicInfoMapper.findList(new WhereFilter(), EquipInfo.class);
        }
        return basicInfoMapper.findList(new WhereFilter() {{
            addFilter("workshop_code", Operation.EQUAL, workshopCode);
        }}, EquipInfo.class);
    }

    public List<Map<String, Object>> findRealTimeDataMes(String searchCode) {
        Class searchCodeClass = classNameCache.get(searchCode, Class.class);
        if (StringUtils.isEmpty(searchCode)) {
            return new ArrayList<>();
        }
        List<Map<String, Object>> list = dataMapper.findJoin(new WhereFilter() {{
            addFilter("status", Operation.EQUAL, 1);
        }}, searchCodeClass);
        for (Map<String, Object> map : list) {
            map.put("status", "9");
            dataMapper.updateByClass(map, searchCodeClass);
        }
        return list;
    }

    public List<StationPassInfo> getStationPassInfo(String vin) {
        List<StationPassInfo> list = passInfoMapper.findList(new WhereFilter() {{
            addFilter("VIN", Operation.EQUAL, vin);
        }}, StationPassInfo.class);
        return list;
    }
}
