package net.northking.cctp.element.mobile.utils.phoneUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.appium.java_client.AppiumDriver;
import net.northking.cctp.element.core.IExecuteContext;
import net.northking.cctp.element.core.exception.EnvironmentException;
import net.northking.cctp.element.core.exception.ExecuteException;
import net.northking.cctp.element.mobile.constants.ConfigPath;
import net.northking.cctp.element.mobile.utils.HttpUtils;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

public class IosUtil {

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

    private static final String PROXY_POR_TKEY = "webDriverAgentUrl";

    private static final String iosWindowSize = "http://%s:%s/window/size";

    private static final String iosSendKeys = "http://%s:%s/wda/cctpInput";

    private static final String WINDOWS_SCALE = "http://%s:%s/%s";


    public static Double getWindowsSize(AppiumDriver<WebElement> driver,String resolution) {
        if (null == driver) {
            logger.error("driver获取为空");
            throw new EnvironmentException("设备自动化驱动连接已断开，请检查驱动程序是否正常");
        }
        String host = driver.getRemoteAddress().getHost();
        Capabilities capabilities = driver.getCapabilities();
        String wdaUrl = (String) capabilities.getCapability(PROXY_POR_TKEY);
        String proxyPort = wdaUrl.substring(wdaUrl.lastIndexOf(":") + 1);
        String deviceId = (String) capabilities.getCapability("deviceName");
        String windowsUrl = String.format(iosWindowSize,host,proxyPort);
        logger.debug("请求ios窗口地址：{}", windowsUrl);
        Double scale = 2.0;
        try {
            JSONObject object = HttpUtils.doGet(new URI(windowsUrl), JSONObject.class);
            JSONObject value = object.getJSONObject("value");
            Double widthScreen = value.getDouble("width");
            //转换比例
            String[] split = resolution.split("\\*");
            Integer width = Integer.parseInt(split[0]);
            Integer height = Integer.parseInt(split[1]);

            Integer realityWidth = width;
            if (width > height) {  //宽高反了的情况，调换
                realityWidth = height;
            }
            scale = realityWidth.doubleValue() / widthScreen.doubleValue();
            logger.info("手机【{}】的宽高比例：{}",deviceId,scale);
            return scale;
        } catch (Exception e) {
            logger.error("获取手机【{}】宽高比例失败:{}",deviceId, e);
            throw new ExecuteException("获取手机宽高比例失败");
        }
    }

    public static Double getWindowsSize(IExecuteContext context,AppiumDriver<WebElement> driver) {
        if (null == driver) {
            logger.error("driver获取为空");
            throw new EnvironmentException("设备自动化驱动连接已断开，请检查驱动程序是否正常");
        }
        String windowsScaleAddress = context.getProperty(ConfigPath.GET_WINDOW_SCALE_KEY);
        Map<String, Object> deviceInfo = context.getDeviceInfo();
        String resolution = (String) deviceInfo.get("resolution");
        Capabilities capabilities = driver.getCapabilities();
        String host  = driver.getRemoteAddress().getHost(); //上位机IP
        String port = (String) deviceInfo.get("port");   //上位机端口
        String finalScaleAddr = String.format(WINDOWS_SCALE,host,port,windowsScaleAddress);
        logger.debug("获取完整屏幕缩放比地址：{}",finalScaleAddr);
        String deviceId = (String) capabilities.getCapability("deviceName");
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("deviceId", deviceId);
        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(paramMap);
        Double scale = 2.0;
        try {
            JSONObject screenSzie = HttpUtils.doPost(finalScaleAddr, entity,JSONObject.class);
            Double widthScreen = screenSzie.getDouble("width");
            Double heightScreen = screenSzie.getDouble("height");
            if (widthScreen > heightScreen) {
                widthScreen = heightScreen;
            }
            //转换比例
            String[] split = resolution.split("\\*");
            Integer width = Integer.parseInt(split[0]);
            Integer height = Integer.parseInt(split[1]);

            Integer realityWidth = width;
            if (width > height) {  //宽高反了的情况，调换
                realityWidth = height;
            }
            scale = realityWidth.doubleValue() / widthScreen.doubleValue();
            logger.info("手机【{}】的宽高比例：{}",deviceId,scale);
            return scale;
        } catch (Exception e) {
            logger.error("获取手机【{}】宽高比例失败:{}",deviceId, e);
            throw new ExecuteException("获取手机宽高比例失败");
        }
    }

    public static Integer getScale(AppiumDriver<WebElement> driver) {
        if (null == driver) {
            logger.error("driver获取为空");
            throw new EnvironmentException("设备自动化驱动连接已断开，请检查驱动程序是否正常");
        }
        String host  = driver.getRemoteAddress().getHost(); //上位机IP
        Capabilities capabilities = driver.getCapabilities();
        String wdaUrl = (String) capabilities.getCapability(PROXY_POR_TKEY);
        String proxyPort = wdaUrl.substring(wdaUrl.lastIndexOf(":") + 1);
        String finalScaleAddr = String.format(iosWindowSize,host,proxyPort);
        logger.debug("获取完整屏幕缩放比地址：{}",finalScaleAddr);
        Integer scale = 2;
        JSONObject obj = null;
        try {
            obj = HttpUtils.doGet(new URI(finalScaleAddr), JSONObject.class);
            if (null != obj) {
                JSONObject value = obj.getJSONObject("value");
                if (null != value) {
                    scale = value.getInteger("scale");
                }
            }
            logger.debug("手机缩放比：{}",scale);
            return scale;
        } catch (Exception e) {
            logger.error("获取手机缩放比失败:{}", e);
            throw new ExecuteException("获取手机缩放比失败");
        }
    }

    public static void sendKeys(String inputStr, int frequency, AppiumDriver driver) {
        if (inputStr.length() > 1000) {
            throw new ExecuteException("输入的字符串不能超过1000字符");
        }
        String host = driver.getRemoteAddress().getHost();
        Capabilities capabilities = driver.getCapabilities();
        String wdaUrl = (String) capabilities.getCapability(PROXY_POR_TKEY);
        String proxyPort = wdaUrl.substring(wdaUrl.lastIndexOf(":") + 1);
        String sendKeyUrl = String.format(iosSendKeys,host,proxyPort);
        logger.debug("ios输入文本地址：{}", sendKeyUrl);
        HashMap<String, Object> body = new HashMap<>();
        body.put("value", inputStr);
        body.put("frequency", frequency);
        HttpEntity<Map> httpEntity = new HttpEntity<>(body, null);
        try {
            JSONObject jsonObject = HttpUtils.doPost(sendKeyUrl, httpEntity, JSONObject.class);
            logger.info("wda输入完成，响应结果：{}", JSON.toJSONString(jsonObject));
        } catch (Exception e) {
            throw new ExecuteException(String.format("输入文本【%s】失败！", inputStr));
        }
    }

    public static void activeIosApp(IExecuteContext context, AppiumDriver<WebElement> driver, String appPackage) {
        String activeAppPath = context.getProperty(ConfigPath.ACTIVE_IOS_APP_ADDRESS_KEY);
        Map<String, Object> deviceInfo = context.getDeviceInfo();
        String host = driver.getRemoteAddress().getHost();  //上位机地址
        String port = (String) deviceInfo.get("port");   //上位机端口
        String url = String.format(ConfigPath.HTTP_FORMAT, host, port, activeAppPath);
        Capabilities capabilities = driver.getCapabilities();
        String deviceId = (String) capabilities.getCapability("deviceName");
        HashMap<String, Object> body = new HashMap<>();
        body.put("deviceId", deviceId);
        body.put("appPackage", appPackage);
        body.put("platform", "1");
        HttpEntity<Map> httpEntity = new HttpEntity<>(body, null);
        try {
            logger.debug("启动app的路径：{}",url);
            Boolean result = HttpUtils.doPost(url, httpEntity, Boolean.class);
            logger.info("app启动完成，响应结果：{}", result);
        } catch (Exception e) {
            throw new ExecuteException(String.format("设备【{}】app【{}】启动失败！", deviceId,appPackage));
        }
    }
}
