package net.northking.cctp.upperComputer.webSocket.thread;

import com.alibaba.fastjson.JSONObject;
import net.northking.cctp.upperComputer.constants.ResponseCmd;
import net.northking.cctp.upperComputer.utils.SessionUtils;
import net.northking.cctp.upperComputer.webSocket.entity.CmdRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;

import javax.websocket.Session;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * @author : yineng.huang
 * @date : 2023/10/18 16:17
 */
public class IosScreenCompressHandleThread extends Thread {

    private static Logger logger = LoggerFactory.getLogger(IosScreenCompressHandleThread.class);

    private Session wsSession;  //发送数据到后端的session

    private int width;  //宽

    private int height;  //高

    private float compressQuality = 0.75f;

    private BlockingDeque<byte[]> dataQueues = new LinkedBlockingDeque<>();

    private CmdRequest screenOnRequest;  //只是第一次连接需要，发送给前端代表连接成功

    private String serial;

    private byte[] lastData;

    private byte[] lastSendData;

    private boolean isAlive;

    private IosScreenRecordThread screenRecordThread;

    private String recordingType = "0";  //录屏类型0-未录，1-真机录屏，2-自动化执行任务录屏

//    final ImageReader imageReader;
//    final ImageWriter imageWriter;
//    final ImageWriteParam imageWriteParam;
//    final ByteArrayOutputStream chunkOutputStream = new ByteArrayOutputStream();

    @Override
    public void run() {
        //发送连接设备成功的消息到前端
        if (null != wsSession) {
            Map<String, Object> result = new HashMap<>();
            result.put("status", "connected");
            SessionUtils.sendMessageInitiative(wsSession, ResponseCmd.DEVICE_STATUS, serial, result, "设备连接成功");
        }
        while (!isInterrupted() && isAlive) {
            try {
                lastData = dataQueues.take();
            } catch (InterruptedException e) {
                interrupt();
                break;
            }
            if (null != screenOnRequest) {  //只发第一次screen_on指令
                SessionUtils.sendSuccessData(wsSession, screenOnRequest, null, "开启屏幕成功");
                setScreenOnRequest(null);
            }
            //录屏
            if (null != screenRecordThread && !screenRecordThread.isInterrupted() && screenRecordThread.isAlive()) {
                screenRecordThread.addImgToVideo(lastData);
            }
            //发送前端
            if (null != wsSession) {
                lastSendData = compressScreenPicture(lastData);
                SessionUtils.sendBinary(wsSession, lastSendData);
            }
        }
        logger.warn("设备【{}】压缩线程退出。。。。。。。。。。。。。。。", serial);
    }

    private byte[] compressScreenPicture(byte[] data) {
        logger.debug("图片大小：{}",data.length);
//        //压缩
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//        try {
////            Thumbnails.of(new ByteArrayInputStream(data)).forceSize(width,height).outputQuality(compressQuality).toOutputStream(outputStream);
////            // 读取原始图片
////            ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
////            BufferedImage sourceImage = ImageIO.read(inputStream);
////
////            // 创建目标大小的缓冲图像
////            BufferedImage compressedImage = new BufferedImage(591, 1050, BufferedImage.TYPE_INT_RGB);
////
////            // 绘制原始图片到缓冲图像，并进行压缩
////            Graphics2D g2d = compressedImage.createGraphics();
////            g2d.drawImage(sourceImage, 0, 0, 591, 1050, null);
////            g2d.dispose();
////            // 保存压缩后的图片
////            ImageIO.write(compressedImage, "jpg", outputStream);
////
////            //压缩
//////            byte[] byteArray = outputStream.toByteArray();
//////            inputStream.reset();
//////            outputStream.reset();
//////            inputStream = new ByteArrayInputStream(byteArray);
//////            sourceImage = ImageIO.read(inputStream);
//////
//////            ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
//////            ImageWriteParam param = writer.getDefaultWriteParam();
//////            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
//////            param.setCompressionQuality(0.8f);
//////            writer.setOutput(javax.imageio.ImageIO.createImageOutputStream(outputStream));
//////            writer.write(null, new javax.imageio.IIOImage(sourceImage, null, null), param);
//////
//////            writer.dispose();
//            stopWatch.stop();
//            logger.debug("处理时间：{}ms",stopWatch.getTotalTimeMillis());
//            lastSendData = outputStream.toByteArray();
//            logger.debug("图片大小：{}",lastSendData.length);
//        } catch (IOException e) {
//            logger.warn("压缩图片出现异常",e);
//        }
        return lastSendData;


//        try {
//            imageReader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(data)), true);
//            IIOMetadata meta = imageReader.getImageMetadata(0);
//            BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(data));
//            IIOImage iIOImage;
//            int scaleWidth = (int) (bufferedImage.getWidth() * 0.5);
//            int scaleHeight = (int) (bufferedImage.getHeight() * 0.5);
//            BufferedImage scaledBufferImage = new BufferedImage(scaleWidth, scaleHeight, BufferedImage.TYPE_INT_RGB);
//            for (int x = 0; x < scaleWidth; x++) {
//                for (int y = 0; y < scaleHeight; y++) {
//                    scaledBufferImage.setRGB(x, y, bufferedImage.getRGB(x * 2, y * 2));
//                }
//            }
//            iIOImage = new IIOImage(scaledBufferImage, null, meta);
//            chunkOutputStream.reset();
//            imageWriter.setOutput(new MemoryCacheImageOutputStream(chunkOutputStream));
//            imageWriter.write(null, iIOImage, imageWriteParam);
//            lastSendData = chunkOutputStream.toByteArray();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        stopWatch.stop();
//        logger.debug("处理时间：{}ms",stopWatch.getTotalTimeMillis());
//        return lastSendData;
    }

    public IosScreenCompressHandleThread(String udid){
        this.serial = udid;
        this.isAlive = true;
        setName("[" + serial + "]compress");
    }

    public IosScreenCompressHandleThread(Session wsSession, String udid) {
        this.wsSession = wsSession;
        this.serial = udid;
        this.isAlive = true;
        setName("[" + serial + "]compress");
//        setName("ChunkHandleThread");
//        Iterator<ImageReader> imageReaders = ImageIO.getImageReadersByFormatName("jpg");
//        if (!imageReaders.hasNext()) {
//            throw new IllegalStateException(("不支持jpg编码"));
//        }
//        imageReader = imageReaders.next();
//        Iterator<ImageWriter> imageWriters = ImageIO.getImageWritersByFormatName("jpg");
//        if (!imageWriters.hasNext()) {
//            throw new IllegalStateException("不支持jpg编码");
//        }
//        imageWriter = imageWriters.next();
//        imageWriteParam = imageWriter.getDefaultWriteParam();
//        imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
//        imageWriteParam.setCompressionQuality(compressQuality);
    }

    public void setScreenSize(int width, int height) {
        this.width = width;
        this.height = height;
        if (null != lastData) {
            byte[] screenData = compressScreenPicture(lastData);
            if (null != wsSession) {
                SessionUtils.sendBinary(wsSession, screenData);
            }
        }
    }

    public void setCompressQuality(float compressQuality) {
        this.compressQuality = compressQuality;
        if (null != lastData) {
            byte[] screenData = compressScreenPicture(lastData);
            if (null != wsSession) {
                SessionUtils.sendBinary(wsSession, screenData);
            }
        }
    }

    public void setScreenOnRequest(CmdRequest screenOnRequest) {
        this.screenOnRequest = screenOnRequest;
    }

    public void addData(byte[] data) {
        this.dataQueues.add(data);
    }

    public void stopAndExit() {
        String videoUrl = stopRecord();
        if (null != videoUrl) {
            Map<String, Object> result = new HashMap<>();
            result.put("videoInfo", videoUrl);
            SessionUtils.sendMessageInitiative(wsSession,ResponseCmd.RECORD_FINISH,serial, result, "结束录屏成功");
        }
        this.isAlive = false;
        this.lastSendData = null;
        this.dataQueues.clear();
        this.lastData = null;
        interrupt();
    }

//    public void startRecordScreen(String tenantId, int width, int height,String recordType) {
//        this.recordingType = recordType;
//        if (null != screenRecordThread && screenRecordThread.isAlive()) {
//            screenRecordThread.killRecord();
//        }
//        SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
//        String dateFormat = format.format(new Date());
//        String videoName =  this.serial + "_" + dateFormat + ".mp4";
//        screenRecordThread = new IosScreenRecordThread(this.serial, videoName, tenantId,width, height);
//        screenRecordThread.start();
//    }

    public String stopRecord() {
        this.recordingType = "0";
        if (null == screenRecordThread || screenRecordThread.isInterrupted() || !screenRecordThread.isAlive()) {
            return null;
        }
        String result = screenRecordThread.endRecord();
        screenRecordThread = null;
        return result;
    }

//    public String stopRecord(String tenantId) {
//        this.recordingType = "0";
//        if (null == screenRecordThread || screenRecordThread.isInterrupted() || !screenRecordThread.isAlive()) {
//            return null;
//        }
//        String result = screenRecordThread.endRecord(tenantId);
//        JSONObject object = JSONObject.parseObject(result, JSONObject.class);
//        screenRecordThread = null;
//        String videoUrl = object.getString("videoUrl");
//        logger.debug("上传录屏的地址：{}",videoUrl);
//        return videoUrl;
//    }

    public void setWsSession(Session wsSession) {
        this.wsSession = wsSession;
    }

    public boolean isRecordingToAuto() {
        return recordingType.equals("2");
    }

    public void exitSendWebData() {
        this.wsSession = null;
    }

    public boolean isSendingDataToWeb() {
        return this.wsSession != null;
    }
}
