package com.videogo.openapi;

import android.app.Application;
import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;

import com.ezviz.sdk.configwifi.touchAp.GetAccessDeviceInfoCallback;
import com.ezviz.sdk.configwifi.touchAp.GetDeviceWifiListCallback;
import com.ezviz.sdk.configwifi.touchAp.GetTokenCallback;
import com.ezviz.sdk.configwifi.touchAp.QueryPlatformBindStatusCallback;
import com.ezviz.sdk.configwifi.touchAp.StartNewApConfigCallback;
import com.hikvision.wifi.configuration.DeviceDiscoveryListener;
import com.videogo.auth.EZAuthApi;
import com.videogo.ezdclog.EZDcLogManager;
import com.videogo.openapi.bean.EZAccessTokenInternal;
import com.videogo.util.LocalInfo;
import com.videogo.constant.Config;
import com.videogo.errorlayer.ErrorLayer;
import com.videogo.errorlayer.ErrorOpenSDKProxy;
import com.videogo.exception.BaseException;
import com.videogo.main.AppManager;
import com.videogo.openapi.bean.EZAccessToken;
import com.videogo.openapi.bean.EZAlarmInfo;
import com.videogo.openapi.bean.EZAreaInfo;
import com.videogo.openapi.bean.EZCloudRecordFile;
import com.videogo.openapi.bean.EZDeviceCloudServiceInfo;
import com.videogo.openapi.bean.EZDeviceInfo;
import com.videogo.openapi.bean.EZDeviceRecordFile;
import com.videogo.openapi.bean.EZDeviceUpgradeStatus;
import com.videogo.openapi.bean.EZDeviceVersion;
import com.videogo.openapi.bean.EZHiddnsDeviceInfo;
import com.videogo.openapi.bean.EZLeaveMessage;
import com.videogo.openapi.bean.EZProbeDeviceInfo;
import com.videogo.openapi.bean.EZProbeDeviceInfoResult;
import com.videogo.openapi.bean.EZStorageStatus;
import com.videogo.openapi.bean.EZUserInfo;
import com.videogo.util.LogUtil;
import com.videogo.wificonfig.APWifiConfig;
import com.videogo.wificonfig.ConfigWifiSdkManager;

import java.util.Calendar;
import java.util.List;

/**
 * 开放平台海外版本
 * 海外开发者接入时关注此接口(EZOpenSDK是面向国内开发者的)
 * <p>
 * Global version of the open platform SDK.
 * Overseas developers should use this interface (EZOpenSDK is for domestic developers).
 * <p>
 * Created by yudan on 16/7/7.
 */
public final class EZGlobalSDK extends EZOpenSDK {

    private static final String TAG = "EZGlobalSDK";
    private static final String API_URL = "https://open.ezvizlife.com";
    private static final String WEB_URL = "https://openauth.ezvizlife.com";

//    static {
//        System.loadLibrary("stlport_shared");
//        System.loadLibrary("marsxlog");
//    }

    private EZGlobalSDK(Application application, String appKey) {
        super(application, appKey);
        LogUtil.i(TAG, "construct EZGlobalSDK, version: " + getVersion());
    }

    public static EZGlobalSDK getInstance() {
        return (EZGlobalSDK) mEZOpenSDK;
    }

    // 据底底层库同事描述该接口主要用于热更新，SDK暂无此需求，因此移除该接口
//    /**
//     * SDK 初始化
//     *
//     * @param application  客户端app的 Application 對象
//     * @param appKey  客户端app申請的app key
//     * @param loadLibraryAbsPath  如果将so库放到sd卡上，此处指定.so库在sd卡的路径
//     *
//     * @return  true 表示成功，false 表示失败
//     */
//    public static boolean initLib(Application application, String appKey, String loadLibraryAbsPath) {
//        if (TextUtils.isEmpty(appKey)){
//            LogUtil.e(TAG,"initLib EZOpenSDK, appKey is null");
//            return false;
//        }
//        // 创建LocalInfo对象并初始化
//        LocalInfo.init(application);
//        LocalInfo.getInstance().setServAddr(API_URL);
//        LocalInfo.getInstance().setAuthServAddr(WEB_URL);
//        if (!TextUtils.isEmpty(loadLibraryAbsPath)) {
//            EzvizAPI.init(application, appKey, loadLibraryAbsPath);
//        } else {
//            EzvizAPI.init(application, appKey);
//        }
//        EzvizAPI.getInstance().setServerUrl(API_URL, WEB_URL);
//        EzvizAPI.getInstance().setAccessToken(LocalInfo.getInstance().getEZAccesstoken().getAccessToken());
//        EzvizAPI.platformType = EZConstants.EZPlatformType.EZPlatformTypeGLOBALSDK;
//        AppManager.getInstance().getEZSDKConfigurationSyn();
//        if (mGlobalSDK == null) {
//            mGlobalSDK = new EZGlobalSDK();
//        }
//
//        return true;
//    }

    /**
     * @deprecated 不再支持加载外置so库，仅保留形式兼容老版本sdk
     * @deprecated Loading external .so libraries is no longer supported. Kept only for backward compatibility.
     */
    @Deprecated
    public static boolean initLib(Application application, String appKey, String loadLibraryAbsPath) {
        return initLib(application, appKey);
    }

    /**
     * SDK 初始化
     * SDK initialization
     *
     * @param application 客户端app的 Application 对象 / The Application object of the client app
     * @param appKey      客户端app申请的app key / The app key applied by the client app
     * @return true 表示成功，false 表示失败 / true indicates success, false indicates failure
     */
    public static boolean initLib(Application application, String appKey) {
        if (TextUtils.isEmpty(appKey)) {
            LogUtil.e(TAG, "initLib EZOpenSDK, appKey is null");
            return false;
        }

        ErrorLayer.setErrorProxy(ErrorOpenSDKProxy.getInstance());

        // 创建LocalInfo对象并初始化
        LocalInfo.init(application, appKey);
        LocalInfo.getInstance().setServAddr(API_URL);
        LocalInfo.getInstance().setAuthServAddr(WEB_URL);
        EzvizAPI.init(application, appKey, true);
        EzvizAPI.getInstance().setServerUrl(API_URL, WEB_URL);
        EzvizAPI.getInstance().preSetToken();
//        EZDcLogManager.getInstance().setUsingGlobalSDK(true);
        EZAuthApi.platformType = EZPlatformType.EZPlatformTypeGLOBALSDK;

        AppManager.getInstance().getEZSDKConfigurationSyn();
        mEZOpenSDK = new EZGlobalSDK(application, appKey);

        showSDKLog(Config.LOGGING);

        return true;
    }

    /**
     * 打开云存储H5页面
     * 仅适用于单通道设备，如IPC，不建议使用
     * Open cloud storage H5 page.
     * Only applicable to single-channel devices such as IPC. Not recommended.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @throws BaseException 调用失败的异常信息 / Exception information when the call fails
     * @deprecated 仅保留接口兼容老用户，请尽快换用void openCloudPage(String deviceSerial, int cameraNo)
     *             Kept only for backward compatibility. Please switch to openCloudPage(String deviceSerial, int cameraNo) as soon as possible.
     */
    @Deprecated
    public void openCloudPage(String deviceSerial) throws BaseException {
        mEzvizAPI.openCloudPage(deviceSerial, 1);
    }

    /**
     * 打开云存储H5页面
     * Open cloud storage H5 page.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     camera序号，EZCameraInfo.cameraNo / Camera index, EZCameraInfo.cameraNo
     * @throws BaseException 调用失败的异常信息 / Exception information when the call fails
     * @since 4.8.8 增加camera序号 / Added camera index
     */
    public void openCloudPage(String deviceSerial, int cameraNo) throws BaseException {
        mEzvizAPI.openCloudPage(deviceSerial, cameraNo);
    }

    /**
     * 释放sdk资源
     * Release SDK resources.
     */
    public static void finiLib() {
        LogUtil.i(TAG, "FiniLib EZGlobalSDK, version: " + getVersion());
    }

    public static String getVersion() {
        return Config.VERSION;
    }

    /**
     * 设置是否支持P2P取流，默认是不支持的
     * P2P取流可以降低转发取流的比例，但是在多人同时观看时对设备端的带宽要求也更高，设备端带宽不够的情况下，影响播放体验
     * 对于可能多人同时观看的场景，建议不支持
     * 对于家用监控类的场景，建议支持P2P
     * 此函数可以在任意时刻调用
     * Set whether P2P streaming is supported. Disabled by default.
     * P2P streaming can reduce the proportion of relay streaming, but requires higher bandwidth on the device side
     * when multiple users are watching simultaneously, which may affect playback experience.
     * For scenarios where multiple users may watch simultaneously, it is recommended to disable P2P.
     * For home surveillance scenarios, it is recommended to enable P2P.
     * This method can be called at any time.
     *
     * @param bEnable true-支持p2p false-不支持p2p / true - enable P2P, false - disable P2P
     */
    public static void enableP2P(boolean bEnable) {
        Config.ENABLE_P2P = bEnable;
    }

    /**
     * 授权登录以后给EZOpenSDK设置AccessToken
     * Set the AccessToken for EZOpenSDK after authorized login.
     *
     * @param accessToken 授权登录获取的accessToken / The accessToken obtained from authorized login
     */
    public void setAccessToken(String accessToken) {
        mEzvizAPI.setAccessToken(accessToken);
    }

    /**
     * 获取登录token
     * Get the login token.
     *
     * @return token包含2个字段，
     * 一个是token string本身，另外一个表示过期时间，单位为秒
     * The token contains 2 fields: the token string itself and the expiration time in seconds.
     */
    public EZAccessToken getEZAccessToken() {
        return mEzvizAPI.getEZAccessToken();
    }

    /**
     * 获取区域列表
     * 接口中有网络操作，需要在线程中调用
     * Get the area/region list.
     * This interface involves network operations and must be called in a thread.
     *
     * @return 区域列表 / Area/region list
     * @throws BaseException
     * @see EZAreaInfo
     */
    public List<EZAreaInfo> getAreaList() throws BaseException {
        return mEzvizAPI.getAreaList();
    }

    /**
     * 打开授权登录中间页面,用于获取Accesstoken
     * Open the authorization login page to obtain the AccessToken.
     *
     * @param areaId 区域ID / Area/region ID
     */
    public void openLoginPage(int areaId) {
        mEzvizAPI.gotoLoginPage(false, areaId, -1);
    }

    /**
     * 打开授权登录中间页面,用于获取Accesstoken
     * Open the authorization login page to obtain the AccessToken.
     *
     * @param areaId 区域ID / Area/region ID
     * @param flag   页面跳转flag 类似Intent.FLAG_ACTIVITY_CLEAR_TOP / Page navigation flag, similar to Intent.FLAG_ACTIVITY_CLEAR_TOP
     */
    public void openLoginPage(int areaId, int flag) {
        mEzvizAPI.gotoLoginPage(false, areaId, flag);
    }

    /**
     * 登出账号
     * Log out of the account.
     */
    public void logout() {
        mEzvizAPI.logout();
    }

    /**
     * 获取用户的设备列表，返回EZDeviceInfo的对象数组，只提供设备基础数据
     * 该接口为耗时操作，建议放在线程中调用
     * Get the user's device list, returning an array of EZDeviceInfo objects with basic device data only.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param pageIndex 查询页index，从0开始 / Page index for query, starting from 0
     * @param pageSize  每页数量（建议20以内） / Number of items per page (recommended within 20)
     * @return 返回的EZDeviceInfo / List of EZDeviceInfo objects
     * @throws BaseException
     */
    public List<EZDeviceInfo> getDeviceList(int pageIndex, int pageSize) throws BaseException {
        return mEzvizAPI.getDeviceList(pageIndex, pageSize, false);
    }

    /**
     * 尝试查询设备信息（用于添加设备之前, 简单查询设备信息，如是否在线，是否添加等）
     * 该接口为耗时操作，建议放在线程中调用
     * Try to query device info (used before adding a device, simple query for device info such as online status, whether added, etc.).
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param deviceSerial 需要查询的设备序列号 / The device serial number to query
     * @return 返回 EZProbeDeviceInfo 对象，包含设备简单信息，用于添加目的 / Returns an EZProbeDeviceInfo object containing basic device info for adding purposes
     * @throws BaseException
     * @deprecated 仅保留接口兼容老用户，请尽快换用EZProbeDeviceInfoResult probeDeviceInfo(String deviceSerial,String deviceType)
     *             Kept only for backward compatibility. Please switch to probeDeviceInfo(String deviceSerial, String deviceType) as soon as possible.
     */
    @Deprecated
    public EZProbeDeviceInfo probeDeviceInfo(String deviceSerial) throws BaseException {
        return mEzvizAPI.probeDeviceInfo(deviceSerial);
    }

    /**
     * 尝试查询设备信息（用于添加设备之前, 简单查询设备信息，如是否在线，是否添加等）
     * 接口中有网络操作，需要在线程中调用
     * Try to query device info (used before adding a device, simple query for device info such as online status, whether added, etc.).
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 需要查询的设备序列号 / The device serial number to query
     * @return 返回 EZProbeDeviceInfoResult 对象，包含查询的设备信息，以及异常情况
     *         Returns an EZProbeDeviceInfoResult object containing the queried device info and exception details
     */
    public EZProbeDeviceInfoResult probeDeviceInfo(String deviceSerial, String deviceType) {
        return mEzvizAPI.probeDeviceInfo(deviceSerial, deviceType);
    }

    /**
     * 获取告警信息列表
     * 接口中有网络操作，需要在线程中调用
     * Get the alarm information list.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号，为null时查询整个账户下的告警信息列表 / Device serial number. When null, queries the alarm list for the entire account.
     * @param pageIndex    分页当前页码（从0开始） / Current page index for pagination (starting from 0)
     * @param pageSize     分页每页数量（建议20以内） / Number of items per page (recommended within 20)
     * @param beginTime    搜索时间范围开始时间，开始时间和结束时间可以同时为空 / Search time range start time. Both start and end time can be null.
     * @param endTime      搜索时间范围结束时间 / Search time range end time
     * @return EZAlarmInfo对象列表 / List of EZAlarmInfo objects
     * @throws BaseException
     */
    public List<EZAlarmInfo> getAlarmList(String deviceSerial, int pageIndex, int pageSize, Calendar beginTime,
                                          Calendar endTime) throws BaseException {
        return mEzvizAPI.getAlarmList(deviceSerial, pageIndex, pageSize, beginTime, endTime);
    }

    /**
     * 设置告警为已读
     * 接口中有网络操作，需要在线程中调用
     * Set alarm status as read.
     * This interface involves network operations and must be called in a thread.
     *
     * @param alarmIdList 告警信息Id数组(设置单条告警为已读时，数组中可以只有一个Id) / Array of alarm IDs (can contain only one ID when setting a single alarm as read)
     * @param alarmStatus 告警状态,目前只支持设为已读功能 EZMessageStatusRead / Alarm status. Currently only supports setting as read (EZMessageStatusRead).
     * @return true 表示成功， false 表示失败 / true indicates success, false indicates failure
     * @throws BaseException
     */
    public boolean setAlarmStatus(List<String> alarmIdList, EZConstants.EZAlarmStatus alarmStatus) throws BaseException {
        return mEzvizAPI.setAlarmStatus(alarmIdList, alarmStatus);
    }

    /**
     * 批量删除告警
     * Batch delete alarms.
     *
     * @param alarmIdList 告警ID list / List of alarm IDs
     * @return true 表示成功， false 表示失败 / true indicates success, false indicates failure
     * @throws BaseException
     */
    public boolean deleteAlarm(List<String> alarmIdList) throws BaseException {
        return mEzvizAPI.deleteAlarm(alarmIdList);
    }

    /**
     * 查询远程SD卡存储录像信息列表
     * 当设备关联了NVR存储设备后，此时查找的是NVR设备中录像，不再提供查找设备SD卡中录像
     * 接口中有网络操作，需要在线程中调用
     * Query the list of remote SD card recording files.
     * When the device is associated with an NVR storage device, this queries recordings from the NVR, not the device SD card.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     camera的序号，EZCameraInfo.cameraNo / Camera index, EZCameraInfo.cameraNo
     * @param startTime    查询时间范围开始时间 / Query time range start time
     * @param endTime      查询时间范围结束时间 / Query time range end time
     * @return 远程SD卡存储录像信息列表 / List of remote SD card recording files
     * @throws BaseException
     */
    public List<EZDeviceRecordFile> searchRecordFileFromDevice(String deviceSerial, int cameraNo, Calendar startTime,
                                                               Calendar endTime) throws BaseException {
        return mEzvizAPI.searchRecordFileFromDevice(deviceSerial, cameraNo, startTime, endTime);
    }

    /**
     * 查询远程SD卡录像信息列表（支持获取浓缩录像）
     * 当设备关联了NVR存储设备后，此时查找的是NVR设备中录像，不再提供查找设备SD卡中录像
     * 该接口为耗时操作，必须在线程中调用
     * Query the list of remote SD card recording files (supports condensed recordings).
     * When the device is associated with an NVR storage device, this queries recordings from the NVR, not the device SD card.
     * This is a time-consuming operation and must be called in a thread.
     *
     * @param deviceSerial    设备序列号 / Device serial number
     * @param cameraNo        camera的序号，EZCameraInfo.cameraNo / Camera index, EZCameraInfo.cameraNo
     * @param startTime       查询时间范围开始时间 / Query time range start time
     * @param endTime         查询时间范围结束时间 / Query time range end time
     * @param videoRecordTypeEx 录像类型 / Recording type
     * @return 远程SD卡存储录像信息列表 / List of remote SD card recording files
     * @throws BaseException
     * @since v5.8
     */
    public List<EZDeviceRecordFile> searchRecordFileFromDeviceEx(String deviceSerial, int cameraNo, Calendar startTime, Calendar endTime, EZConstants.EZVideoRecordTypeEx videoRecordTypeEx)
            throws BaseException {
        return mEzvizAPI.searchRecordFileFromDeviceEx(deviceSerial, cameraNo, startTime, endTime, String.valueOf(videoRecordTypeEx.recordType));
    }

    /**
     * 添加设备
     * 接口中有网络操作，需要在线程中调用
     * Add a device.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param verifyCode   设备验证码，验证码位于设备机身上，6位大写字母 / Device verification code, located on the device body, 6 uppercase letters
     * @return true 表示成功， false 表示失败 / true indicates success, false indicates failure
     * @throws BaseException
     */
    public boolean addDevice(String deviceSerial, String verifyCode) throws BaseException {
        return mEzvizAPI.addDeviceBySerialNonTransfer(deviceSerial, verifyCode);
    }

    /**
     * 删除当前账号的设备
     * 接口中有网络操作，需要在线程中调用
     * Delete a device from the current account.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号, 9位数字 / Device serial number, 9-digit number
     * @return true 表示成功， false 表示失败 / true indicates success, false indicates failure
     * @throws BaseException
     */
    public boolean deleteDevice(String deviceSerial) throws BaseException {
        return mEzvizAPI.deleteDeviceNonTransfer(deviceSerial);
    }

    /**
     * PTZ 控制接口
     * 接口中有网络操作，需要在线程中调用
     * PTZ (Pan-Tilt-Zoom) control interface.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     通道号 / Channel number
     * @param command      ptz控制命令 / PTZ control command
     * @param action       控制启动/停止 / Control start/stop action
     * @param speed        速度（0-7） / Speed (0-7)
     * @return 操作成功或者失败(返回失败错误码) / Operation success or failure (returns failure error code)
     */
    public boolean controlPTZ(String deviceSerial, int cameraNo, EZConstants.EZPTZCommand command,
                              EZConstants.EZPTZAction action, int speed) throws BaseException {
        return mEzvizAPI.controlPTZ(deviceSerial, cameraNo, command, action, speed);
    }

    /**
     * 镜像 控制设备视频画面翻转。在摄像头倒装的时候，调用此接口可让画面正过来
     * 需要设备支持
     * 该接口为耗时操作，必须在线程中调用
     * Mirror/flip the device video image. When the camera is mounted upside down, calling this interface can correct the image.
     * Requires device support.
     * This is a time-consuming operation and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     camera的序号，EZCameraInfo.cameraNo / Camera index, EZCameraInfo.cameraNo
     * @param command      ptz控制命令 / PTZ display control command
     * @throws BaseException exception 操作失败会抛出异常，错误码 exception.getErrorCode / Throws exception on failure, error code via exception.getErrorCode
     * @deprecated 建议用http方式实现，使用说明请参考https://open.ys7.com/doc/zh/book/index/device_ptz.html#device_ptz-api3
     *             Recommended to use HTTP implementation. See https://open.ys7.com/doc/zh/book/index/device_ptz.html#device_ptz-api3
     */
    @Deprecated
    public void controlVideoFlip(String deviceSerial, int cameraNo, EZConstants.EZPTZDisplayCommand command) throws BaseException {
        mEzvizAPI.controlVideoFlip(deviceSerial, cameraNo, command);
    }

    /**
     * 解密数据，该接口可以用于解密告警图片
     * Decrypt data. This interface can be used to decrypt alarm images.
     *
     * @param inputData  解密前数据 / Data before decryption
     * @param verifyCode 密码，设备加密时通常为设备验证码 / Password, usually the device verification code when encrypted by the device
     */
    public byte[] decryptData(byte[] inputData, String verifyCode) {
        return mEzvizAPI.decryptData(inputData, verifyCode, 1);
    }

    /**
     * 解密数据，该接口可以用于解密告警图片
     * Decrypt data. This interface can be used to decrypt alarm images.
     *
     * @param inputData  解密前数据 / Data before decryption
     * @param verifyCode 密码，设备加密时通常为设备验证码，平台加密时为平台返回的checkSum
     *                   Password, usually the device verification code when encrypted by the device,
     *                   or the checkSum returned by the platform when encrypted by the platform
     * @param cryptType  加密类型 1-设备加密 2-平台加密 / Encryption type: 1 - device encryption, 2 - platform encryption
     */
    public byte[] decryptData(byte[] inputData, String verifyCode, int cryptType) {
        return mEzvizAPI.decryptData(inputData, verifyCode, cryptType);
    }

    /**
     * 设备设置布防状态，兼容A1和IPC设备的布防
     * 接口中有网络操作，需要在线程中调用
     * Set the device defence status. Compatible with A1 and IPC device defence.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param defence      布防状态, 摄像机布防状态只有0和1，告警器有0:睡眠 8:在家 16:外出
     *                     Defence status. Camera defence status is 0 or 1. Alarm device: 0-sleep, 8-at home, 16-away.
     * @return
     * @throws BaseException
     */
    public boolean setDefence(String deviceSerial, EZConstants.EZDefenceStatus defence) throws BaseException {
        return mEzvizAPI.setDefence(deviceSerial, defence);
    }

    /**
     * 刷新设备详细信息（修改验证码后调用）
     * 接口中有网络操作，需要在线程中调用
     * Refresh device detail information (call after modifying the verification code).
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     通道号 / Channel number
     * @throws BaseException
     */
    public void refreshDeviceDetailInfo(String deviceSerial, int cameraNo) throws BaseException {
        mEzvizAPI.refreshDeviceDetailInfoEx(deviceSerial, cameraNo);
    }

    /**
     * 获取摄像头实时图片的url接口，需要设备支持，萤石设备一般都能支持此协议。(该功能和萤石云视频app首页刷新封面的功能一致)
     * 该接口为耗时操作，建议放在线程中调用
     * Get the URL of the camera's real-time snapshot. Requires device support; EZVIZ devices generally support this protocol.
     * (This feature is the same as refreshing the cover on the EZVIZ Cloud Video app home page.)
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param channelNo    通道号 / Channel number
     * @return 图片url / Image URL
     * @throws BaseException
     */
    public String captureCamera(String deviceSerial, int channelNo) throws BaseException {
        return mEzvizAPI.capturePicture(deviceSerial, channelNo);
    }

    /**
     * 获取设备的版本信息接口
     * 接口中有网络操作，需要在线程中调用
     * Get the device version information.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @return 版本号EZDeviceVersion对象 / EZDeviceVersion object containing version info
     * @throws BaseException
     */
    public EZDeviceVersion getDeviceVersion(String deviceSerial) throws BaseException {
        return mEzvizAPI.getDeviceVersion(deviceSerial);
    }

    /**
     * 设备视频图片加解密开关接口
     * 接口中有网络操作，需要在线程中调用
     * Toggle device video/image encryption on or off.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param validateCode 设备验证码，开启加密无需验证码 / Device verification code. Not required when enabling encryption.
     * @param encrypt      是否加密 / Whether to enable encryption
     * @return
     * @throws BaseException
     */
    public boolean setDeviceEncryptStatus(String deviceSerial, String validateCode, boolean encrypt) throws BaseException {

        return mEzvizAPI.setDeviceEncryptStatus(deviceSerial, validateCode, encrypt);
    }

    /**
     * 修改设备名称接口
     * 接口中有网络操作，需要在线程中调用
     * Modify the device name.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param deviceName   修改后的设备名称 / The new device name
     * @return true 表示成功， false 表示失败 / true indicates success, false indicates failure
     * @throws BaseException
     */
    public boolean setDeviceName(String deviceSerial, String deviceName) throws BaseException {
        return mEzvizAPI.updateDeviceName(deviceSerial, deviceName);
    }

    /**
     * 获取用户信息；用户信息包含：用户名,头像地址等
     * 接口中有网络操作，需要在线程中调用
     * Get user information, including username, avatar URL, etc.
     * This interface involves network operations and must be called in a thread.
     *
     * @return 返回 EZUserInfo 对象 / Returns an EZUserInfo object
     * @throws BaseException
     */
    public EZUserInfo getUserInfo() throws BaseException {
        return mEzvizAPI.getEZUserInfo();
    }

    /**
     * 获取未读消息数
     * 接口中有网络操作，需要在线程中调用
     * Get the unread message count.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 需要获取的设备序列号，为空时返回账户下所有设备的未读消息数
     *                     Device serial number. When empty, returns the unread message count for all devices under the account.
     * @param messageType  消息类型：EZMessageTypeAlarm 告警消息，EZMessageTypeLeave 留言消息, 暂不支持
     *                     Message type: EZMessageTypeAlarm for alarm messages, EZMessageTypeLeave for leave messages (not yet supported)
     * @return 未读消息数
     *         Unread message count
     * @throws BaseException
     */
    public int getUnreadMessageCount(String deviceSerial, EZConstants.EZMessageType messageType) throws BaseException {
        return mEzvizAPI.getUnreadMessageCount(deviceSerial, messageType);
    }

    /**
     * 获取留言消息列表,默认为止查询语音留言信息
     * 该接口为耗时操作，建议放在线程中调用
     * Get the leave message list. By default, queries voice leave messages.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param deviceSerial 设备序列号（可为空），为空时返回账户下所有设备的留言消息
     *                     Device serial number (can be null). When null, returns leave messages for all devices under the account.
     * @param pageIndex    当前分页，从0开始 / Current page index, starting from 0
     * @param pageSize     分页大小 / Page size
     * @param beginTime    开始时间 / Start time
     * @param endTime      结束时间 / End time
     * @return 留言EZLeaveMessage列表 / List of EZLeaveMessage objects
     * @throws BaseException
     */
    public List<EZLeaveMessage> getLeaveMessageList(String deviceSerial, int pageIndex, int pageSize,
                                                    Calendar beginTime, Calendar endTime) throws BaseException {
        return mEzvizAPI.getLeaveMessageList(deviceSerial, pageIndex, pageSize, beginTime, endTime);
    }

    /**
     * 批量设置留言消息已读功能
     * 该接口为耗时操作，建议放在线程中调用
     * Batch set leave messages as read.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param msgIdList     留言消息Id数组(最大数量为10，允许只有1个) / Array of leave message IDs (max 10, can be just 1)
     * @param messageStatus 需要设置的留言状态，目前只支持 EZMessageStatusRead(已读); / The message status to set. Currently only supports EZMessageStatusRead (read).
     * @return true 表示成功， false 表示失败 / true indicates success, false indicates failure
     * @throws BaseException
     */
    public boolean setLeaveMessageStatus(List<String> msgIdList, EZConstants.EZMessageStatus messageStatus) throws BaseException {
        return mEzvizAPI.setLeaveMessageStatus(msgIdList, messageStatus);
    }

    /**
     * 批量删除留言消息
     * 该接口为耗时操作，建议放在线程中调用
     * Batch delete leave messages.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param msgIdList 留言消息Id数组(最大数量为10，允许只有1个) / Array of leave message IDs (max 10, can be just 1)
     * @return true 表示成功， false 表示失败 / true indicates success, false indicates failure
     * @throws BaseException
     */
    public boolean deleteLeaveMessages(List<String> msgIdList) throws BaseException {
        return mEzvizAPI.deleteLeaveMessages(msgIdList);
    }

    /**
     * 获取语音留言数据
     * 该接口为耗时操作，建议放在线程中调用
     * Get voice leave message data.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param handler  handler，用于发送成功或者失败消息, 301:下载留言失败 ;302:下载留言成功 消息obj为留言ID
     *                 Handler for sending success or failure messages. 301: download failed; 302: download succeeded. Message obj is the leave message ID.
     * @param msg      留言消息 / Leave message object
     * @param callback 获取留言消息数据回调 / Callback for getting leave message data
     */
    public void getLeaveMessageData(Handler handler, EZLeaveMessage msg,
                                    EZOpenSDKListener.EZLeaveMessageFlowCallback callback) {
        mEzvizAPI.getLeaveMessageData(handler, msg, callback);
    }


    /**
     * 获取存储介质状态(如是否初始化，格式化进度等)
     * 接口中有网络操作，需要在线程中调用
     * Get the storage media status (e.g., whether initialized, formatting progress, etc.).
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 需要获取的设备序列号 / Device serial number to query
     * @return 存储状态(EZStorageStatus)列表，列表每个item代表一个磁盘分区 / List of EZStorageStatus objects, each item represents a disk partition
     * @throws BaseException
     */
    public List<EZStorageStatus> getStorageStatus(String deviceSerial) throws BaseException {
        return mEzvizAPI.getStorageStatus(deviceSerial);
    }

    /**
     * 格式化分区(SD卡)
     * 接口中有网络操作，需要在线程中调用
     * Format a partition (SD card).
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial   需要格式化的设备序列号 / Device serial number to format
     * @param partitionIndex getStorageStatus查询返回的分区号 / Partition index returned by getStorageStatus query
     * @return true 表示成功， false 表示失败 / true indicates success, false indicates failure
     * @throws BaseException
     */
    public boolean formatStorage(String deviceSerial, int partitionIndex) throws BaseException {
        return mEzvizAPI.formatStorage(deviceSerial, partitionIndex);
    }

    /**
     * 开始升级设备
     * 接口中有网络操作，需要在线程中调用
     * Start upgrading the device firmware.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @throws BaseException
     */
    public void upgradeDevice(String deviceSerial) throws BaseException {
        mEzvizAPI.upgradeDevice(deviceSerial);
    }

    /**
     * 获取设备升级状态
     * 接口中有网络操作，需要在线程中调用
     * Get the device upgrade status.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @return EZDeviceUpgradeStatus对象 / EZDeviceUpgradeStatus object
     */
    public EZDeviceUpgradeStatus getDeviceUpgradeStatus(String deviceSerial) throws BaseException {
        return mEzvizAPI.getDeviceUpgradeStatus(deviceSerial);
    }

    /**
     * 打开修改密码页面
     * Open the change password page.
     */
    public void openChangePasswordPage() {
        mEzvizAPI.openChangePasswordPage();
    }

    /**
     * 开始WiFi配置
     * Start WiFi configuration.
     *
     * @param context      应用 activity context / Application activity context
     * @param deviceSerial 配置设备序列号 / Device serial number to configure
     * @param ssid         连接WiFi SSID / WiFi SSID to connect
     * @param password     连接  WiFi 密码 / WiFi password to connect
     * @param mode         配网的方式，EZWiFiConfigMode中列举的模式进行任意组合,例如:EZWiFiConfigMode.EZWiFiConfigSmart|EZWiFiConfigMode.EZWiFiConfigWave
     *                     WiFi configuration mode. Any combination of modes listed in EZWiFiConfigMode, e.g., EZWiFiConfigMode.EZWiFiConfigSmart | EZWiFiConfigMode.EZWiFiConfigWave
     * @param back         配置回调 / Configuration callback
     * @since 4.3.0
     */
    public void startConfigWifi(Context context, String deviceSerial, String ssid, String password, int mode,
                                EZOpenSDKListener.EZStartConfigWifiCallback back) {
        mEzvizAPI.startConfigWifi(context, deviceSerial, ssid, password, mode,null, back);
    }

    /**
     * 开始WiFi配置
     * Start WiFi configuration.
     *
     * @param context  应用 activity context / Application activity context
     * @param ssid     连接WiFi SSID / WiFi SSID to connect
     * @param password 连接WiFi 密码 / WiFi password to connect
     * @param l        回调，用于处理连接设备的WiFi配置状态 / Callback for handling the WiFi configuration status of the connected device
     * @return 返回值并没有特别的含义，根据回调判断是否配置wifi成功 / The return value has no special meaning; use the callback to determine WiFi configuration success.
     * @deprecated
     */
    @Deprecated
    public boolean startConfigWifi(Context context, String ssid, String password, DeviceDiscoveryListener l) {
        return mEzvizAPI.startConfigWifi(context, ssid, password, l);
    }

    /**
     * 停止Wifi配置
     * Stop WiFi configuration.
     *
     * @return true 表示成功， false 表示失败 / true indicates success, false indicates failure
     */
    public boolean stopConfigWiFi() {
        return mEzvizAPI.stopConfigWiFi();
    }

    /**
     * AP配网接口,默认为"EZVIZ_"+设备序列号,设备AP热点密码默认为"EZVIZ_"+设备验证码,默认自动连接设备热点，需要获取可扫描wifi的权限
     * AP WiFi configuration interface. Default hotspot name is "EZVIZ_" + device serial number, default hotspot password is "EZVIZ_" + device verification code. Auto-connects to device hotspot by default. Requires WiFi scanning permission.
     *
     * @param ssid             WiFi的ssid / WiFi SSID
     * @param password         WiFi的密码 / WiFi password
     * @param deviceSerial     设备序列号 / Device serial number
     * @param verifyCode       设备验证码 / Device verification code
     * @param apConfigCallback 结果回调 / Result callback
     */
    public void startAPConfigWifiWithSsid(final String ssid, final String password, String deviceSerial,
                                          final String verifyCode,
                                          final APWifiConfig.APConfigCallback apConfigCallback) {
        mEzvizAPI.startAPConfigWifiWithSsid(ssid, password, deviceSerial, verifyCode, apConfigCallback);
    }


    /**
     * AP配网接口
     * AP WiFi configuration interface.
     *
     * @param ssid                       WiFi的ssid / WiFi SSID
     * @param password                   WiFi的密码 / WiFi password
     * @param deviceSerial               设备序列号 / Device serial number
     * @param verifyCode                 设备验证码 / Device verification code
     * @param routerNamePre              设备热点名称，可传空，默认为"EZVIZ_"+设备序列号 / Device hotspot name. Can be null, defaults to "EZVIZ_" + device serial number.
     * @param routerPasswordPre          设备热点密码,可传空，默认为"EZVIZ_"+设备验证码 / Device hotspot password. Can be null, defaults to "EZVIZ_" + device verification code.
     * @param isAutoConnectDeviceHotSpot 是否自动连接设备热点,需要获取可扫描wifi的权限 / Whether to auto-connect to device hotspot. Requires WiFi scanning permission.
     * @param apConfigCallback           结果回调 / Result callback
     */
    public void startAPConfigWifiWithSsid(final String ssid, final String password, String deviceSerial,
                                          final String verifyCode, final String routerNamePre,
                                          final String routerPasswordPre, boolean isAutoConnectDeviceHotSpot,
                                          final APWifiConfig.APConfigCallback apConfigCallback) {
        mEzvizAPI.startAPConfigWifiWithSsid(ssid, password, deviceSerial, verifyCode, routerNamePre,
                routerPasswordPre, isAutoConnectDeviceHotSpot, apConfigCallback);
    }

    /**
     * 停止AP配网
     * Stop AP WiFi configuration.
     */
    public void stopAPConfigWifiWithSsid() {
        mEzvizAPI.stopAPConfigWifiWithSsid();
    }

    // ------------------------------ 接触式配网 New AP Config ------------------------------

    /**
     * 获取接触式AP配网token
     * Get the touch AP configuration token.
     *
     * @param callback 回调 / Callback
     */
    public void getNewApConfigToken(GetTokenCallback callback) {
        mEzvizAPI.getNewApConfigToken(callback);
    }

    /**
     * 设备配网（向设备发送wifi信息）
     * Device WiFi configuration (send WiFi info to the device).
     *
     * @param token 通过getNewApConfigToken接口获取的token / Token obtained from the getNewApConfigToken interface
     * @param ssid wifi名称 / WiFi name (SSID)
     * @param password wifi密码 / WiFi password
     * @param lbsDomain 通过requestConfigToken接口获取的注册地址 / Registration address obtained from the requestConfigToken interface
     * @param callback 回调 / Callback
     */
    public void startNewApConfigWithToken(String token, String ssid, String password, String lbsDomain, StartNewApConfigCallback callback) {
        mEzvizAPI.startNewApConfigWithToken(token, ssid, password, lbsDomain, callback);
    }

    /**
     * 获取设备信息（需连接设备热点）
     * Get device information (requires connection to device hotspot).
     *
     * @param callback 回调 / Callback
     */
    public void getAccessDeviceInfo(GetAccessDeviceInfoCallback callback){
        mEzvizAPI.getAccessDeviceInfo(callback);
    }

    /**
     * 获取设备环境wifi列表（需连接设备热点）
     * Get the list of WiFi networks around the device (requires connection to device hotspot).
     *
     * @param callback 回调 / Callback
     */
    public void getAccessDeviceWifiList(GetDeviceWifiListCallback callback){
        mEzvizAPI.getAccessDeviceWifiList(callback);
    }

    /**
     * 查询设备绑定状态
     * Query the device binding status on the platform.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param callback 回调 / Callback
     */
    public void queryPlatformBindStatus(String deviceSerial, QueryPlatformBindStatusCallback callback) {
        mEzvizAPI.queryPlatformBindStatus(deviceSerial, callback);
    }

    /**
     * 设置配网设备网关地址 可选
     * Set the gateway address for the device being configured. Optional.
     *
     * @param devRouteDomain 设备网关地址 / Device gateway address
     */
    public void setDevRouteDomain(String devRouteDomain) {
        mEzvizAPI.setDevRouteDomain(devRouteDomain);
    }

    /**
     * AP-Http配网接口
     * AP-HTTP WiFi configuration interface.
     *
     * @param configToken                配网token / Configuration token
     * @param ssid                       WiFi的ssid / WiFi SSID
     * @param password                   WiFi的密码 / WiFi password
     * @param routerName                 设备热点名称 / Device hotspot name
     * @param routerPassword             设备热点密码 / Device hotspot password
     * @param lbsDomain                  设备注册平台 / Device registration platform
     * @param isAutoConnectDeviceHotSpot 是否自动连接设备热点,需要获取可扫描wifi的权限 / Whether to auto-connect to device hotspot. Requires WiFi scanning permission.
     * @param apConfigCallback           结果回调 / Result callback
     */
    public void startAPHttpConfigWifiWithToken(final String configToken, final String ssid, final String password,
                                               final String routerName, final String routerPassword, final String lbsDomain,
                                               boolean isAutoConnectDeviceHotSpot, APWifiConfig.APConfigCallback apConfigCallback) {
        mEzvizAPI.startAPHttpConfigWifiWithToken(configToken, ssid, password, routerName,
                routerPassword, lbsDomain, isAutoConnectDeviceHotSpot, apConfigCallback);
    }

    /**
     * 停止AP-Http配网
     * Stop AP-HTTP WiFi configuration.
     */
    public void stopAPHttpConfigWifiWithToken() {
        mEzvizAPI.stopAPHttpConfigWifiWithToken();
    }

    /**
     * 根据视频广场url构造EZPlayer对象，用于视频广场的视频播放
     * Create an EZPlayer object from a video square URL for video playback in the video square.
     *
     * @param url 广场视频url / Video square URL
     * @return EZPlayer对象 / EZPlayer object
     */
    public EZPlayer createPlayerWithUrl(final String url) {
        return mEzvizAPI.createPlayerWithUrl(url);
    }

    /**
     * 创建局域网播放器
     * Create a LAN (local network) player.
     *
     * @param userId     设备登录成功后的userId / The userId after successful device login
     * @param cameraNo   设备预览的通道号 / Channel number for device preview
     * @param streamType 设备预览的码流类型 1:主码流;2:子码流 / Stream type for device preview. 1: main stream; 2: sub stream.
     * @return EZPlayer对象 / EZPlayer object
     */
    public EZPlayer createPlayerWithUserId(int userId, int cameraNo, int streamType) {
        return mEzvizAPI.createPlayerWithUserId(userId, cameraNo, streamType);
    }

    /**
     * 根据deviceSerial 和 cameraNo 构造EZPlayer对象
     * Create an EZPlayer object by device serial number and camera number.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     通道号 / Channel number
     * @return EZPlayer对象 / EZPlayer object
     */
    public EZPlayer createPlayer(final String deviceSerial, int cameraNo) {
        return mEzvizAPI.createPlayer(deviceSerial, cameraNo);
    }

    /**
     * 根据deviceSerial 和 cameraNo 和 useSubStream构造EZPlayer对象
     * 一个页面存在多个视频使用最小的码流，没有子码流的话还是使用主码流
     * Create an EZPlayer object by device serial number, camera number, and sub-stream preference.
     * When multiple videos exist on one page, use the minimum stream. Falls back to main stream if sub-stream is unavailable.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     通道号 / Channel number
     * @param useSubStream 是否使用子码流 / Whether to use sub-stream
     * @return EZPlayer对象 / EZPlayer object
     * @since V4.19.2
     */
    public EZPlayer createPlayer(final String deviceSerial, int cameraNo, boolean useSubStream) {
        return mEzvizAPI.createPlayerWithDeviceSerial(deviceSerial, cameraNo, useSubStream);
    }

    /**
     * 释放  EZPlayer 对象
     * Release an EZPlayer object.
     *
     * @param player 将要释放的EZPlayer对象 / The EZPlayer object to be released
     */
    public void releasePlayer(EZPlayer player) {
        mEzvizAPI.releasePlayer(player);
    }

    /**
     * 获取好友分享的设备列表，返回EZDeviceInfo的对象数组
     * 该接口为耗时操作，建议放在线程中调用
     * Get the list of devices shared by friends, returning an array of EZDeviceInfo objects.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param pageIndex 分页起始页，从0开始 / Page start index, starting from 0
     * @param pageSize  分页每页数量（建议20以内） / Number of items per page (recommended within 20)
     * @return
     * @throws BaseException
     * @since 4.2
     */
    public List<EZDeviceInfo> getSharedDeviceList(int pageIndex, int pageSize) throws BaseException {
        return mEzvizAPI.getSharedDeviceList(pageIndex, pageSize);
    }

    /**
     * 设置指定监控点视频清晰度
     * 接口中有网络操作，需要在线程中调用
     * Set the video quality level for a specified camera.
     * This interface involves network operations and must be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     设备通道号，默认为1 / Device channel number, default is 1
     * @param videoLevel   清晰度 0-流畅 1-均衡 2-高品质 / Video quality level: 0 - smooth, 1 - balanced, 2 - high quality
     * @return
     * @throws BaseException
     */
    public boolean setVideoLevel(String deviceSerial, int cameraNo, int videoLevel) throws BaseException {
        return mEzvizAPI.setDeviceVideoLevel(deviceSerial, cameraNo, videoLevel);
    }

    /**
     * 获取单个设备信息
     * 该接口为耗时操作，建议放在线程中调用
     * Get information for a single device.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @return 设备信息对象EZDeviceInfo，与getDeviceList中对象一致 / EZDeviceInfo object, same as the object in getDeviceList
     * @throws BaseException
     * @since 4.3
     */
    public EZDeviceInfo getDeviceInfo(String deviceSerial) throws BaseException {
        return mEzvizAPI.getDeviceInfo(deviceSerial, false);
    }

    /**
     * 获取终端（手机等）唯一识别码
     * Get the unique identifier of the terminal (phone, etc.).
     *
     * @return 终端唯一识别码 / Terminal unique identifier
     * @since 4.3.0
     */
    public String getTerminalId() {
        return mEzvizAPI.getTerminalId();
    }

//    /**
//     * 配置hiddns信息
//     * 该接口为耗时操作，建议放在线程中调用
//     *
//     * @param deviceSerial 序列号
//     * @param domain    设备域名,设备域名规则修改，不能为空，6-32位，可以为本身序列号，包含小写字母、数字、-，首位必须字母，末位不能为-
//     * @param upnp      upnp状态，1-手动，0-自动
//     * @param cmdPort   cmd端口
//     * @param httpPort  http端口
//     * @return
//     * @throws BaseException
//     * @since 4.3
//     */
//    public boolean deviceHiddnsConfigWithSerial(final String deviceSerial, final String domain, final int upnp,
//    final int cmdPort, final int httpPort ) throws BaseException {
//        return mEzvizAPI.deviceHiddnsConfigWithSerial(deviceSerial,domain,upnp,cmdPort,httpPort);
//    }

    /**
     * 清除取流时的缓存数据
     * Clear the cached data during stream fetching.
     *
     * @since 4.5.0
     */
    public void clearStreamInfoCache() {
        mEzvizAPI.clearStreamInfoCache();
    }


    /**
     * 获取设备DDNS信息
     * 该接口为耗时操作，建议放在线程中调用
     * 设备序列号，deviceSerial和domain不能全为空，
     * 如果deviceSerial和domain都不为空，优先查询deviceSerial设备的ddns信息
     * Get the device DDNS information.
     * This is a time-consuming operation and should be called in a thread.
     * deviceSerial and domain cannot both be empty.
     * If both are provided, deviceSerial takes priority.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param domain       设备域名 / Device domain name
     * @throws BaseException
     */

    public EZHiddnsDeviceInfo getDDNSWithDeviceSerial(final String deviceSerial, final String domain) throws BaseException {
        return mEzvizAPI.getDDNSWithDeviceSerial(deviceSerial, domain);
    }

    /**
     * 设置设备DDNS域名
     * 该接口为耗时操作，建议放在线程中调用
     * 设备序列号，deviceSerial和domain不能为空，
     * Set the device DDNS domain name.
     * This is a time-consuming operation and should be called in a thread.
     * deviceSerial and domain cannot be empty.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param domain       设备域名,设备域名规则修改，不能为空，6-32位，可以为本身序列号，包含小写字母、数字、-，首位必须字母，末位不能为-
     *                     Device domain name. Cannot be empty, 6-32 characters, can be the serial number itself, contains lowercase letters, digits, and hyphens. Must start with a letter and cannot end with a hyphen.
     * @throws BaseException
     */
    public void setDeviceDoamin(final String deviceSerial, final String domain) throws BaseException {
        mEzvizAPI.setDeviceDoamin(deviceSerial, domain);
    }

    /**
     * 设置设备DDNS自动映射
     * 该接口为耗时操作，建议放在线程中调用
     * Set the device DDNS to automatic mapping.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @throws BaseException
     */

    public void setDDNSAutomatic(final String deviceSerial) throws BaseException {
        mEzvizAPI.setDDNSAutomatic(deviceSerial);
    }

    /**
     * 设置设备DDNS手动映射
     * 该接口为耗时操作，建议放在线程中调用
     * Set the device DDNS to manual mapping.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cmdPort      cmd（服务）端口 / CMD (service) port
     * @param httpPort     http端口 / HTTP port
     * @throws BaseException
     */
    public void setDDNSManual(final String deviceSerial, final int cmdPort, final int httpPort) throws BaseException {
        mEzvizAPI.setDDNSManual(deviceSerial, cmdPort, httpPort);
    }

    /**
     * 获取账户下所有设备列表DDNS信息
     * 该接口为耗时操作，建议放在线程中调用
     * Get the DDNS information for all devices under the account.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param pageSize  分页大小，默认为10，最大为50 / Page size, default is 10, max is 50
     * @param pageStart 分页起始页，从0开始，默认为0 / Page start index, starting from 0, default is 0
     * @throws BaseException
     */
    public List<EZHiddnsDeviceInfo> getDDNSDeviceList(final int pageSize, final int pageStart) throws BaseException {
        return mEzvizAPI.getDDNSDeviceList(pageSize, pageStart);
    }


    /**
     * 分享设备DDNS信息,把单个设备的DDNS信息分享给其他账户
     * 该接口为耗时操作，建议放在线程中调用
     * Share device DDNS information. Share a single device's DDNS info with another account.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param account      被分享账户，可以是邮箱地址或手机号码（包含国家代码）或不是全数字的用户名
     *                     Target account to share with. Can be an email address, phone number (with country code), or a non-all-numeric username.
     * @throws BaseException
     */
    public void ShareDDNSDeviceList(final String deviceSerial, final String account) throws BaseException {
        mEzvizAPI.shareDDNSDeviceList(deviceSerial, account);
    }

    /**
     * 获取当前账号下的所有的其它账户分享给自己的设备DDNS信息
     * 该接口为耗时操作，建议放在线程中调用
     * Get all DDNS information of devices shared to the current account by other accounts.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param pageSize  分页大小，默认为10，最大为50 / Page size, default is 10, max is 50
     * @param pageStart 分页起始页，从0开始，默认为0 / Page start index, starting from 0, default is 0
     * @throws BaseException
     */
    public List<EZHiddnsDeviceInfo> getShareDDNSDeviceList(final int pageSize, final int pageStart) throws BaseException {
        return mEzvizAPI.getShareDDNSDeviceList(pageSize, pageStart);
    }

    /**
     * 是否已登录授权
     * Check whether the user is logged in and authorized.
     *
     * @since 4.8.3
     */
    public boolean isLogin() {

        return EZAuthApi.isLogin();
    }

    /**
     * 设置登录页的v参数，用于控制登录页样式
     * Set the v parameter for the login page to control the login page style.
     *
     * @param vParam 登录页样式（mobile-移动版、wap-pc版。。。） / Login page style (mobile - mobile version, wap - PC version, etc.)
     * @since 4.8.7
     */
    public void setVparamForLoginPage(String vParam) {
        mEzvizAPI.setVparamForLoginPage(vParam);
    }

    /**
     * 切换到指定服务区域
     * Switch to the specified service region.
     *
     * @param apiUrl 区域接口请求域名 / API request domain for the region
     * @param webUrl 区域WEB登录域名（默认可不填写） / Web login domain for the region (optional, can be left empty by default)
     * @since 4.11.0
     */
    public void setServerUrl(String apiUrl, String webUrl) {
        mEzvizAPI.setServerUrl(apiUrl, webUrl);
    }

    /**
     * 检查国家是否支持云存储服务，只支持海外
     * 该接口为耗时操作，建议放在线程中调用
     * Check whether the country supports cloud storage service. Only supported overseas.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @throws BaseException
     * @since 4.19.4
     */
    public boolean isSupportCloundService() throws BaseException {
        return mEzvizAPI.isSupportCloundService();
    }

    /**
     * 查询云存储设备通道套餐信息
     * 该接口为耗时操作，建议放在线程中调用
     * Query cloud storage device channel package information.
     * This is a time-consuming operation and should be called in a thread.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     默认为1 / Default is 1
     * @throws BaseException
     * @since 4.19.4
     */
    public EZDeviceCloudServiceInfo getCloundDevicePackageInfo(final String deviceSerial, final int cameraNo) throws BaseException {
        return mEzvizAPI.getCloundDevicePackageInfo(deviceSerial, cameraNo);
    }

    /**
     * 云存储功能暂停恢复
     * Pause or resume cloud storage service.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     默认为1 / Default is 1
     * @param enable       false-禁用，true-启用 / false - disable, true - enable
     * @throws BaseException
     * @since 4.19.4
     */
    public boolean setCloundServiceActive(final String deviceSerial, final int cameraNo, final boolean enable) throws BaseException {
        return mEzvizAPI.setCloundServiceActive(deviceSerial, cameraNo, enable);
    }

    /**
     * 查询某月中有视频文件的天(日期)
     * Query the days (dates) in a specific month that have video files.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     默认为1 / Default is 1
     * @param month        查询某月具有云存储的日期，格式为yyyyMM / Query the month for cloud storage dates, format: yyyyMM
     * @throws BaseException
     * @since 4.19.4
     */
    public List<String> getCloudVideoDays(final String deviceSerial, final int cameraNo, final String month) throws BaseException {
        return mEzvizAPI.getCloudVideoDays(deviceSerial, cameraNo, month);
    }

    /**
     * 按设备通道删除所有云存储录像片段
     * Delete all cloud storage recording segments by device channel.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     默认为1 / Default is 1
     * @throws BaseException
     * @since 4.19.4
     */
    public boolean deleteAllCloudVideo(final String deviceSerial, final int cameraNo) throws BaseException {
        return mEzvizAPI.deleteAllCloudVideo(deviceSerial, cameraNo);
    }

    /**
     * 按天增量查询云存储录像列表接口(概要信息)
     * Incrementally query cloud storage recording list by day (summary information).
     *
     * @param deviceSerial  设备序列号 / Device serial number
     * @param cameraNo      默认为1 / Default is 1
     * @param videoType     录像类型videoType / Recording type
     * @param searchDate    查找文件日期yyyy-MM-dd / Search date in yyyy-MM-dd format
     * @param maxCreateTime 查找文件的起始时间yyyy-MM-dd HH:mm:ss，要保证和searchDate是同一天，否则报错。默认从 yyyy-MM-dd 00:00:00开始，非必填，可传null
     *                      Start time for searching files in yyyy-MM-dd HH:mm:ss format. Must be the same day as searchDate, otherwise an error occurs. Defaults to yyyy-MM-dd 00:00:00. Optional, can be null.
     * @throws BaseException
     * @since 4.19.4
     */
    public List<String> getIncrCloudVideos(final String deviceSerial, final int cameraNo,
                                           final EZConstants.EZCloudVideoType videoType, final String searchDate,
                                           final String maxCreateTime) throws BaseException {
        return mEzvizAPI.getIncrCloudVideos(deviceSerial, cameraNo, videoType, searchDate, maxCreateTime);
    }

    /**
     * 根据文件id批量查询详情信息接口
     * Batch query detail information by file IDs.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     默认为1 / Default is 1
     * @param videos       视频数组（限制30个以内） / Video ID array (limited to 30)
     * @throws BaseException
     * @since 4.19.4
     */
    public List<EZCloudRecordFile> getCloudVideoDetails(final String deviceSerial, final int cameraNo,
                                                        final List<String> videos) throws BaseException {
        return mEzvizAPI.getCloudVideoDetails(deviceSerial, cameraNo, videos);
    }

    /**
     * 删除云存储录像片段
     * Delete cloud storage recording segments.
     *
     * @param deviceSerial 设备序列号 / Device serial number
     * @param cameraNo     默认为1 / Default is 1
     * @param videos       视频数组（限制30个以内） / Video ID array (limited to 30)
     * @throws BaseException
     * @since 4.19.4
     */
    public boolean deleteCloudVideoFragment(final String deviceSerial, final int cameraNo, final List<String> videos) throws BaseException {
        return mEzvizAPI.deleteCloudVideoFragment(deviceSerial, cameraNo, videos);
    }

}
