package com.gnhz.clinic.eitc_erm_app.sightGlass;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.media.Image;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;

import androidx.core.app.ActivityCompat;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MyXUtil {

    public static final boolean DEBUGMODE = false;
    private static final String TAG = "czb";
    public static String devIP = "192.168.1.1";
    public static String nowIP = "192.168.1.1";
    public static ArrayList<Integer> portList = new ArrayList<Integer>(Arrays.asList(40003, 40031, 40121, 40101));
    //public static ArrayList<Integer> portList = new ArrayList<Integer>(Arrays.asList(40031, 40121, 40101, 40003));
    public static int nowPort = 40003;
    public static boolean h264PlayFlag = false;
    public static boolean ketThreadFlag = false;

    public static void setDevIP(String devIP) {
        MyXUtil.devIP = devIP;
    }

    public static String getDevIP() {
        return getDeviceIP();
    }

    //发送查找信号
    public static void sendSearchIPOrder() {
        Log.e(TAG, "MyXUtil.sendSearchIPOrder");
        com.gnhz.clinic.eitc_erm_app.sightGlass.ThreadPoolHelper.executeTask(new Runnable() {
            @Override
            public void run() {
                DatagramSocket socket = null;
                try {
                    socket = new DatagramSocket();
                } catch (SocketException e) {
                    e.printStackTrace();
                    return;
                }
                byte[] buf = new byte[20];
                buf[0] = 0x3f;
                buf[1] = 0x2f;
                //将数据打包
                DatagramPacket packet = null;
                try {
                    packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("255.255.255.255"), 40011);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                    socket.close();
                    return;
                }
                try {
                    socket.send(packet);
                } catch (IOException e) {
                    e.printStackTrace();
                    socket.close();
                    return;
                }
                socket.close();
                Log.e(TAG, "run: udp发送已经关闭******************");
            }
        });
    }

    private static String getDeviceIP() {
        Log.e(TAG, "MyXUtil.getDeviceIP");
        DatagramSocket recvClient = null;
        byte[] buffer = new byte[20];
        int port = 40012;
        String deviceIP = null;
        try {
            recvClient = new DatagramSocket(port);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
        sendSearchIPOrder();
        try {
            recvClient.setSoTimeout(3000);
        } catch (SocketException e) {
            e.printStackTrace();
        }
        try {
            recvClient.receive(packet);
        } catch (IOException e) {
            e.printStackTrace();
            recvClient.close();
            Log.e(TAG, "getDeviceIP: 接收超时--");
            return null;
        }
        deviceIP = packet.getAddress().toString().substring(1);
        recvClient.close();
        Log.e(TAG, "run: udp接收已经关闭******************");

        if (!recvClient.isClosed()) {
            recvClient.close();
            Log.e(TAG, "finally run: udp接收已经关闭******************");
        }
        return deviceIP;
    }

    /**
     * 判断当前设备是手机还是平板，代码来自 Google I/O App for Android
     *
     * @param context
     * @param context 上下文
     * @return 平板返回 True，手机返回 False
     * <p>
     * public static boolean isPad(Context context) {
     * return isPad_normal(context) && isPad_size(context);
     * }
     * <p>
     * private static boolean isPad_normal(Context context) {
     * return (context.getResources().getConfiguration().screenLayout
     * & Configuration.SCREENLAYOUT_SIZE_MASK)
     * >= Configuration.SCREENLAYOUT_SIZE_LARGE;
     * }
     * <p>
     * /**
     * 大小判断是否是平板
     * @return 是平板则返回true，反之返回false
     */
    private static boolean isPad_size(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        display.getMetrics(dm);
        double x = Math.pow(dm.widthPixels / dm.xdpi, 2);
        double y = Math.pow(dm.heightPixels / dm.ydpi, 2);
        double screenInches = Math.sqrt(x + y); // 屏幕尺寸
        return screenInches >= 7.3;   //华为mate20x的尺寸时7.2，应该是最大的了吧。。。
    }

    public static void compressToJpeg2(String fileName, Image image) {
        FileOutputStream outStream;
        try {
            outStream = new FileOutputStream(fileName);
        } catch (IOException ioe) {
            throw new RuntimeException("Unable to create output file " + fileName, ioe);
        }
        Rect rect = image.getCropRect();
        YuvImage yuvImage = toYuvImage(image);
        yuvImage.compressToJpeg(rect, 100, outStream);
        try {
            outStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private static YuvImage toYuvImage(Image image) {
        if (image.getFormat() != ImageFormat.YUV_420_888) {
            throw new IllegalArgumentException("Invalid image format");
        }

        int width = image.getWidth();
        int height = image.getHeight();

        // Order of U/V channel guaranteed, read more:
        // https://developer.android.com/reference/android/graphics/ImageFormat#YUV_420_888
        Image.Plane yPlane = image.getPlanes()[0];
        Image.Plane uPlane = image.getPlanes()[1];
        Image.Plane vPlane = image.getPlanes()[2];

        ByteBuffer yBuffer = yPlane.getBuffer();
        ByteBuffer uBuffer = uPlane.getBuffer();
        ByteBuffer vBuffer = vPlane.getBuffer();

        // Full size Y channel and quarter size U+V channels.
        int numPixels = (int) (width * height * 1.5f);
        byte[] nv21 = new byte[numPixels];
        int index = 0;

        // Copy Y channel.
        int yRowStride = yPlane.getRowStride();
        int yPixelStride = yPlane.getPixelStride();
        for (int y = 0; y < height; ++y) {
            for (int x = 0; x < width; ++x) {
                nv21[index++] = yBuffer.get(y * yRowStride + x * yPixelStride);
            }
        }

        // Copy VU data; NV21 format is expected to have YYYYVU packaging.
        // The U/V planes are guaranteed to have the same row stride and pixel stride.
        int uvRowStride = uPlane.getRowStride();
        int uvPixelStride = uPlane.getPixelStride();
        int uvWidth = width / 2;
        int uvHeight = height / 2;

        for (int y = 0; y < uvHeight; ++y) {
            for (int x = 0; x < uvWidth; ++x) {
                int bufferIndex = (y * uvRowStride) + (x * uvPixelStride);
                // V channel.
                nv21[index++] = vBuffer.get(bufferIndex);
                // U channel.
                nv21[index++] = uBuffer.get(bufferIndex);
            }
        }
        return new YuvImage(nv21, ImageFormat.NV21, width, height, /* strides= */ null);
    }


    private static final int COLOR_FormatI420 = 1;
    private static final int COLOR_FormatNV21 = 2;

    private static boolean isImageFormatSupported(Image image) {
        int format = image.getFormat();
        switch (format) {
            case ImageFormat.YUV_420_888:
            case ImageFormat.NV21:
            case ImageFormat.YV12:
                return true;
        }
        return false;
    }

    private static byte[] getDataFromImage(Image image, int colorFormat) {
        if (colorFormat != COLOR_FormatI420 && colorFormat != COLOR_FormatNV21) {
            throw new IllegalArgumentException("only support COLOR_FormatI420 " + "and COLOR_FormatNV21");
        }
        if (!isImageFormatSupported(image)) {
            throw new RuntimeException("can't convert Image to byte array, format " + image.getFormat());
        }
        Rect crop = image.getCropRect();
        int format = image.getFormat();
        int width = crop.width();
        int height = crop.height();
        Image.Plane[] planes = image.getPlanes();
        byte[] data = new byte[width * height * ImageFormat.getBitsPerPixel(format) / 8];
        byte[] rowData = new byte[planes[0].getRowStride()];
        int channelOffset = 0;
        int outputStride = 1;
        for (int i = 0; i < planes.length; i++) {
            switch (i) {
                case 0:
                    channelOffset = 0;
                    outputStride = 1;
                    break;
                case 1:
                    if (colorFormat == COLOR_FormatI420) {
                        channelOffset = width * height;
                        outputStride = 1;
                    } else if (colorFormat == COLOR_FormatNV21) {
                        channelOffset = width * height + 1;
                        outputStride = 2;
                    }
                    break;
                case 2:
                    if (colorFormat == COLOR_FormatI420) {
                        channelOffset = (int) (width * height * 1.25);
                        outputStride = 1;
                    } else if (colorFormat == COLOR_FormatNV21) {
                        channelOffset = width * height;
                        outputStride = 2;
                    }
                    break;
            }
            ByteBuffer buffer = planes[i].getBuffer();
            int rowStride = planes[i].getRowStride();
            int pixelStride = planes[i].getPixelStride();
            int shift = (i == 0) ? 0 : 1;
            int w = width >> shift;
            int h = height >> shift;
            buffer.position(rowStride * (crop.top >> shift) + pixelStride * (crop.left >> shift));
            for (int row = 0; row < h; row++) {
                int length;
                if (pixelStride == 1 && outputStride == 1) {
                    length = w;
                    buffer.get(data, channelOffset, length);
                    channelOffset += length;
                } else {
                    length = (w - 1) * pixelStride + 1;
                    buffer.get(rowData, 0, length);
                    for (int col = 0; col < w; col++) {
                        data[channelOffset] = rowData[col * pixelStride];
                        channelOffset += outputStride;
                    }
                }
                if (row < h - 1) {
                    buffer.position(buffer.position() + rowStride - length);
                }
            }
        }
        return data;
    }

    public static void compressToJpeg(String fileName, Image image) {
        FileOutputStream outStream;
        try {
            outStream = new FileOutputStream(fileName);
        } catch (IOException ioe) {
            Log.e(TAG, "compressToJpeg: 创建fileoutputstream失败");
            throw new RuntimeException("Unable to create output file " + fileName, ioe);
        }
        Rect rect = image.getCropRect();
        Log.e(TAG, "compressToJpeg: yuvimag之前");
        YuvImage yuvImage = new YuvImage(getDataFromImage(image, COLOR_FormatNV21), ImageFormat.NV21, rect.width(), rect.height(), null);
        Log.e(TAG, "compressToJpeg: yuvimag之后");
        yuvImage.compressToJpeg(rect, 100, outStream);
        try {
            outStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    // 隐藏键盘
    public static void hideKeyBoard(Activity activity) {
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(activity.getWindow().getDecorView().getWindowToken(), 0);
        }
    }

/*    public static void showDevGrop(DevGroup devGroup) {
        Log.e(TAG, "showDevGrop: " + devGroup.devid0 + "------" + devGroup.devid0ip);
        Log.e(TAG, "showDevGrop: " + devGroup.devid1 + "------" + devGroup.devid1ip);
        Log.e(TAG, "showDevGrop: " + devGroup.devid2 + "------" + devGroup.devid2ip);
        Log.e(TAG, "showDevGrop: " + devGroup.devid3 + "------" + devGroup.devid3ip);
        Log.e(TAG, "showDevGrop: " + devGroup.devid4 + "------" + devGroup.devid4ip);
    }*/

    public static String getSdPath(Context context) {
        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        //  int version = android.os.Build.VERSION.SDK_INT;
        if (sdCardExist) {
            File externalStorageDirectory = Environment.getExternalStorageDirectory();
            return externalStorageDirectory.toString() + "/Download/WIFISDK/";
        }
        return null;
    }

    public static String getSdPath() {
        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        //  int version = android.os.Build.VERSION.SDK_INT;
        if (sdCardExist) {
            File externalStorageDirectory = Environment.getExternalStorageDirectory();
            return externalStorageDirectory.toString() + "/Download/WIFISDK/";
        }
        return null;
    }

    public static List<String> getFilesAllName(String path) {
        //传入指定文件夹的路径
        Log.e("debug", "getFilesAllName: " + path);
        File file = new File(path);
        File[] files = file.listFiles();
        if (files != null) {
            List<String> imagePaths = new ArrayList<>();
            for (File value : files) {
                if (checkIsImageFile(value.getPath())) {
                    imagePaths.add(value.getPath());
                }
            }
            return imagePaths;
        } else {
            Log.e(TAG, "getFilesAllName: ++++++++++++里面啥都没有！！");
        }
        return null;
    }

    /**
     * 判断是否是照片
     */
    public static boolean checkIsImageFile(String fName) {
        //获取拓展名
        String fileEnd = fName.substring(fName.lastIndexOf(".") + 1).toLowerCase();
        return "jpg".equals(fileEnd) || "png".equals(fileEnd) || "jpeg".equals(fileEnd) || "bmp".equals(fileEnd);
    }

    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};

    /**
     * Checks if the app has permission to write to device storage
     * If the app does not has permission then the user will be prompted to grant permissions
     */

    public static void verifyStoragePermissions(Activity activity) {
        // Check if we have write permission
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
        }
    }


}
