package com.example.iot_controlhost.ui.viewmodel;

import android.app.Application;
import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiManager;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.widget.ImageView;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import androidx.lifecycle.MutableLiveData;

import com.blankj.utilcode.util.StringUtils;
import com.example.iot_controlhost.R;
import com.example.iot_controlhost.base.BasePresenter;
import com.example.iot_controlhost.model.DeviceErrorInfo;
import com.example.iot_controlhost.model.SingleLiveEvent;
import com.example.iot_controlhost.model.net.CommonResponse;
import com.example.iot_controlhost.model.net.RoomInfo;
import com.example.iot_controlhost.model.net.Weather;
import com.example.iot_controlhost.service.MQTTService;
import com.example.iot_controlhost.ui.dialog.ConfirmDialog;
import com.example.iot_controlhost.utils.DialogUtil;
import com.example.iot_controlhost.utils.FrpUpdateUtil;
import com.example.iot_controlhost.utils.MMKVUtil;
import com.example.iot_controlhost.utils.MyUtil;
import com.example.iot_controlhost.utils.global.HardwareSetting;
import com.example.iot_controlhost.utils.global.RoomSetting;
import com.example.iot_controlhost.utils.global.RxTag;
import com.example.iot_controlhost.utils.log.MyLog;
import com.example.iot_controlhost.utils.network.NetState;
import com.example.iot_controlhost.utils.network.Url;
import com.example.iot_controlhost.utils.network.XHttpManager;
import com.example.iot_controlhost.utils.network.XHttpShorthand;
import com.xhinliang.lunarcalendar.LunarCalendar;
import com.xuexiang.rxutil2.rxbus.RxBusUtils;

import org.xutils.http.RequestParams;
import org.xutils.x;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description 顶部信息栏
 * @Author DuanKanji
 * @CreateTime 2024年01月19日 14:41
 */
public class AppBarViewModel extends BasePresenter {
    public MutableLiveData<Boolean> isLight = new MutableLiveData<>();
    public MutableLiveData<String> weatherStr = new MutableLiveData<>();
    public MutableLiveData<String> dateStr = new MutableLiveData<>();
    public MutableLiveData<Drawable> logoType = new MutableLiveData<>(ResourcesCompat.getDrawable(getApplication().getResources(), R.mipmap.logo_gys, null));
    public MutableLiveData<Integer> ivServer = new MutableLiveData<>();
    public MutableLiveData<Integer> ivNetwork = new MutableLiveData<>();
    private Boolean pingBaiduAccess = true;
    private NetworkStateListener networkStateListener;
    private TelephonyManager mTelephonyManager;
    private ConnectivityManager connectivityManager;
    private ConnectivityManager.NetworkCallback networkCallback;

    public MutableLiveData<Integer> getIvServer() {
        return ivServer;
    }

    public MutableLiveData<Integer> getIvNetwork() {
        return ivNetwork;
    }

    public MutableLiveData<Integer> noticeLiveData = new SingleLiveEvent<>();
    public MutableLiveData<Weather> weatherLiveData = new MutableLiveData<>();

    public MutableLiveData<Integer> getNoticeLiveData() {
        return noticeLiveData;
    }

    public MutableLiveData<Weather> getWeatherLiveData() {
        return weatherLiveData;
    }

    public AppBarViewModel(@NonNull Application application) {
        super(application);
        refreshRoomInfo();
        //循环更新TopBar UI
        pollingTask.startPollingTaskOnIOThread(RxTag.BAR_UI, 5, () -> {
            Calendar calendar = Calendar.getInstance();
            LunarCalendar lunarCalender = LunarCalendar.obtainCalendar(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH));
            dateStr.postValue(lunarCalender.getLunarMonth() + "月" + lunarCalender.getLunarDay() + new SimpleDateFormat("\tMM/dd HH:mm").format(new Date()));
        });
        //循环更新天气 6小时一更新
        pollingTask.startPollingTaskOnIOThread(RxTag.BAR_UI_WEATHER, 60 * 60, this::refreshWeather);
        //监听更新TouBar UI
        RxBusUtils.get().onMainThread(RxTag.UPDATE_MAIN, Integer.class, i -> {
            switch (i) {
                case 4 ->//刷新网络状态
                        initNetIcon();
            }
        });
        // 轮询Ping Baidu以检测网络真实可用性  2024年8月22日 15:12:06需求取消
//        pollingTask.startPollingTaskOnIOThread(RxTag.PING_BAIDU, 3 * 60, () -> {
//            pingBaiduAccess = pingBaidu();
//            initNetIcon();
//        });
        networkStateListener = new NetworkStateListener();
        mTelephonyManager = (TelephonyManager) getApplication().getSystemService(Context.TELEPHONY_SERVICE);
        mTelephonyManager.listen(networkStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
        registerNetworkCallback();
        isLight.setValue(!RoomSetting.isDarkTheme());
        RxBusUtils.get().onMainThread(RxTag.MAIN_WARNING, DeviceErrorInfo.class, info -> {
            //弹窗
            Dialog dialog = errorInfoMap.get(info.getName());
            if (dialog != null) {
                dialog.dismiss();
            }
            if (!StringUtils.isEmpty(info.getErrorMessage())) {
                //显示新弹窗
                dialog = new ConfirmDialog(activityContext, info.getName(), info.getErrorMessage(), null);
                errorInfoMap.put(info.getName(), dialog);
            }
            //警示图标
            ImageView imageView = errorImageView.get(info.getName());
            if (imageView != null) {
                linearLayout.removeView(imageView);
            }
            if (!StringUtils.isEmpty(info.getErrorMessage())) {
                //显示
                imageView = getImageView(info);
                linearLayout.addView(imageView);
                errorImageView.put(info.getName(), imageView);
            }
        });
    }

    private boolean pingBaidu() {
        try {
            Process process = Runtime.getRuntime().exec("/system/bin/ping -c 1 www.baidu.com");
            int exitCode = process.waitFor();
            return exitCode == 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private ImageView getImageView(DeviceErrorInfo info) {
        ImageView iv = new ImageView(activityContext);
        // 设置 ImageView 的布局参数，比如宽度、高度等
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        // 设置 margin
        layoutParams.setMargins(5, 0, 5, 0);
        iv.setLayoutParams(layoutParams);
        iv.setImageResource(info.getResId());
        iv.setOnClickListener(v -> new ConfirmDialog(activityContext, info.getName(), info.getErrorMessage(), null).show());
        return iv;
    }

    private LinearLayout linearLayout;

    private Context activityContext;

    public void setMainActivityContext(Context mainActivityContext, LinearLayout linearLayout) {
        this.activityContext = mainActivityContext;
        this.linearLayout = linearLayout;
    }

    public Map<String, Dialog> errorInfoMap = new HashMap<>();
    public Map<String, ImageView> errorImageView = new HashMap<>();

    /**
     * 刷新房间信息
     */
    public void refreshRoomInfo() {
        RequestParams params = XHttpManager.getInstance().getRequestParams(Url.getInfo);
        params.addParameter("areaCode", RoomSetting.getAreaCode());
        x.http().get(params, new XHttpShorthand<RoomInfo>() {
            @Override
            public void success(RoomInfo model) {
                MyLog.app("房间信息获取成功");
                RoomInfo.DataDTO data = model.getData();
                MMKVUtil.put(RoomSetting.USER_NAME, data.getOwnerName());
                MMKVUtil.put(RoomSetting.TYPE, data.getTypeCode());
                //更新TouBar logo
                int id = R.mipmap.logo_blue;
                switch (RoomSetting.getType()) {
                    case 1 -> id = R.mipmap.logo_gys;//共育室
                    case 3 -> id = R.mipmap.logo_dcf;//大蚕房
                    case 4 -> id = R.mipmap.logo_cqs;//催青室
                }
                logoType.setValue(ResourcesCompat.getDrawable(getApplication().getResources(), id, null));
                //获取坐标
                if (!StringUtils.isEmpty(data.getLat()) && !StringUtils.isEmpty(data.getLon())) {
                    MMKVUtil.put(RoomSetting.ROOM_LATITUDE_LATITUDE, Double.parseDouble(data.getLat()));
                    MMKVUtil.put(RoomSetting.ROOM_COORDINATE_LONGITUDE, Double.parseDouble(data.getLon()));
                }
            }

            @Override
            public void error(Throwable e) {
                MyLog.appError("房间信息获取失败");
            }

        });
    }

    /**
     * 双击最大时间间隔
     * 单位：毫秒
     */
    private static final long DOUBLE_CLICK_TIME_DELTA = 1000;
    private long lastClickTime = 0;

    public void enterSetActivity() {
        //进入配置界面
        long clickTime = System.currentTimeMillis();
        if (clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA) {
            // 双击事件
            lastClickTime = 0;
            noticeLiveData.setValue(0);
        } else {
            lastClickTime = clickTime;
        }
    }

    public void showWeatherTips() {
        weatherLiveData.setValue(weather);
    }

    public void sosConform() {
        noticeLiveData.setValue(2);
    }

    /**
     * SOS功能
     */
    public void sos(Context mContext) {
        FrpUpdateUtil.check(mContext, true);
    }

    /**
     * 信号强度监听器
     */
    private class NetworkStateListener extends PhoneStateListener {
        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            super.onSignalStrengthsChanged(signalStrength);
            //获取网络信号强度
            int level = signalStrength.getLevel();
            if (level != NetState.Semaphore) {
                MyLog.network("网络信号级别更新为：" + level);
            }
            NetState.Semaphore = level;
            initNetIcon();
        }
    }

    private void initNetIcon() {
        int resId = R.mipmap.network_0;
        int ivNetServerId = MQTTService.getMQTTConnect() ? R.mipmap.server_1 : R.mipmap.server_0;
        int netType = NetState.getNetworkType(getApplication());
        switch (netType) {
            case 0 -> {
                resId = R.mipmap.wifi_0;
                ivNetServerId = R.mipmap.server_0;
            }
            case 1 -> resId = R.mipmap.rj45;
            case 2 -> {
                WifiManager wifiManager = (WifiManager) getApplication().getSystemService(Context.WIFI_SERVICE);
                NetState.Semaphore = WifiManager.calculateSignalLevel(wifiManager.getConnectionInfo().getRssi(), 5);
                switch (NetState.Semaphore) {
                    case 0 -> resId = R.mipmap.wifi_0;
//                        case 0 -> resId = R.drawable.wifi_1;
                    case 1 -> resId = R.mipmap.wifi_2;
                    case 2 -> resId = R.mipmap.wifi_3;
                    case 3 -> resId = R.mipmap.wifi_4;
                    case 4 -> resId = R.mipmap.wifi_5;
                }
            }
            case 3 -> {
                switch (NetState.Semaphore) {
                    case 0 -> resId = R.mipmap._4g_0;
                    case 1 -> resId = R.mipmap._4g_1;
                    case 2 -> resId = R.mipmap._4g_2;
                    case 3 -> resId = R.mipmap._4g_3;
                    case 4 -> resId = R.mipmap._4g_4;
                }
            }
        }
        ivServer.setValue(ivNetServerId);
        ivNetwork.setValue(pingBaiduAccess ? resId : R.mipmap.network_0);
        uploadHostInfoOnNetworkTypeChanged(netType);
    }

    private int lastNetState = -1;

    /**
     * 监听系统默认网络变化，确保WIFI、网线和移动网络之间切换时主动上传主机信息。
     */
    private void registerNetworkCallback() {
        connectivityManager = (ConnectivityManager) getApplication()
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager == null) {
            MyLog.networkError("网络类型监听注册失败：ConnectivityManager不可用");
            return;
        }
        networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(@NonNull Network network) {
                checkNetworkTypeChanged();
            }

            @Override
            public void onCapabilitiesChanged(@NonNull Network network,
                                              @NonNull NetworkCapabilities networkCapabilities) {
                checkNetworkTypeChanged();
            }

            @Override
            public void onLost(@NonNull Network network) {
                checkNetworkTypeChanged();
            }
        };
        connectivityManager.registerDefaultNetworkCallback(networkCallback);
        checkNetworkTypeChanged();
    }

    private void checkNetworkTypeChanged() {
        uploadHostInfoOnNetworkTypeChanged(NetState.getNetworkType(getApplication()));
    }

    private synchronized void uploadHostInfoOnNetworkTypeChanged(int netType) {
        if (lastNetState == netType) {
            return;
        }
        int previousNetState = lastNetState;
        lastNetState = netType;
        MyLog.network("网络类型发生变化：" + previousNetState + " → " + netType + "，主动上传主机信息");
        UploadHostInfo();
    }

    Weather weather;

    /**
     * 获取天气信息
     */
    private void refreshWeather() {
        RequestParams params = XHttpManager.getInstance().getRequestParams(Url.weather);
        params.addParameter("areacode", RoomSetting.getAreaCode());
        x.http().get(params, new XHttpShorthand<Weather>() {
            @Override
            public void success(Weather model) {
                MyLog.app("天气信息获取成功");
                weather = model;
                weatherStr.postValue(model.getData().getCasts().get(0).getDayweather() + " " + model.getData().getCasts().get(0).getDaytemp() + "℃");
            }

            @Override
            public void error(Throwable e) {
                MyLog.appError("天气信息获取失败");
            }

            @Override
            public void onFinish() {
                super.onFinish();
            }
        });
    }


    /**
     * 上传主机信息
     */
    private void UploadHostInfo() {
        RequestParams params = XHttpManager.getInstance().getRequestParams(Url.uploadHostInfo);
        params.addParameter("HostCode", HardwareSetting.getHostId());
        params.addParameter("VersionNumber", MyUtil.getVersionId(getApplication()));
        params.addParameter("VersionName", MyUtil.getVersionName(getApplication()));
        params.addParameter("PlatformVersion", HardwareSetting.getDeviceModel());
        int type = 0;
        //0：未定义，1：物联网卡4G，2：物联网卡5G，3：WIFI，4：RJ45
        switch (NetState.getNetworkType(getApplication())) {
            case 0 -> type = 0;
            case 1 -> type = 4;
            case 2 -> type = 3;
            case 3 -> type = 1;
        }
        params.addParameter("Network", type);
        params.addParameter("IotCardCode", HardwareSetting.getIccid());
        params.addParameter("MAC", HardwareSetting.getImei());
        x.http().post(params, new XHttpShorthand<CommonResponse>() {
            @Override
            public void success(CommonResponse model) {
                MyLog.app("主机信息上传成功");
            }

            @Override
            public void error(Throwable e) {
                MyLog.appError("主机信息上传失败");
            }
        });
    }

    @Override
    protected void onCleared() {
        if (mTelephonyManager != null && networkStateListener != null) {
            mTelephonyManager.listen(networkStateListener, PhoneStateListener.LISTEN_NONE);
        }
        if (connectivityManager != null && networkCallback != null) {
            connectivityManager.unregisterNetworkCallback(networkCallback);
        }
        super.onCleared();
    }
}
