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

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import net.vtstar.scada.base.equipmgt.domain.EquipDataChannel;
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.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.Arrays;
import java.util.List;
import java.util.Map;

@Service
public class EquipmentService {

    @Autowired
    private EquipmentDataMapper dataMapper;
    @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"));
        Class searchCode = classNameCache.get(pageFilter.getString("searchCode"), Class.class);
        if(searchCode == null){
            return new ArrayList<>();
        }
        return dataMapper.findJoin(searchService.pageFilter2Filter(pageFilter, new WhereFilter(){{
            addFilter("status", Operation.EQUAL_GREATER_THAN, 1);
        }}), searchCode);
    }

    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 void putFile(ProgramTransferVO transferVO) {
        EquipDataChannel equipDataChannel = equipDataChannelService.getByEquipCode(transferVO.getEquipCode());
        SmbFileUtil.smbPut("smb://10.1.4.107/数控下料/", transferVO.getFilePath());
//        SmbFileUtil.smbPut("smb://" + equipDataChannel.getIp() +" /数控下料/", transferVO.getFilePath());
    }

    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;
    }
}
