using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
using UnityEngine.AzureSky;
using UnityEngine.UI;

public class GameSettingPanel : UIView<GameSettingData,GameSettingDataReactive>
{
    #region Variables
    //时间天气面板
    public CanvasGroup TimePanel;
    //显示面板
    public CanvasGroup DisplayPanel;
    //时间天气面板开关
    public Toggle TimeToggle;
    //显示面板开关
    public Toggle DisplayToggle;
    //省份选择
    public Dropdown ProvinceDropdown;
    //城市选择
    public Dropdown CityDropdown;
    //实时天气开关
    public Toggle RTWeatherToggle;
    //实时天气刷新按钮
    public Button RTWeatherButton;
    //天气
    public Dropdown WeatherDropdown;
    //温度
    public Slider TempSlider;
    public InputField TempInput;
    //风力
    public Slider ForceSlider;
    public InputField ForceInput;
    //风向
    public Dropdown DirectionDropdown;
    //昼夜交替
    public Toggle TimeOfDayToggle;
    //持续时间
    public Slider DurationSlider;
    public InputField DurationInput;
    public float DurationTime = 6f;
    //时间
    public Slider TimeSlider;
    public InputField HourInput;
    public InputField MinuteInput;
    //贴图质量
    public Dropdown TextureDropdown;
    //各向异性
    public Dropdown AnisotropicDropdown;
    //阴影开关
    public Toggle ShadowToggle;
    //画面质量
    public Dropdown QualityDropdown;
    //亮度
    public Slider BrightnessSlider;
    ////反射
    //public Dropdown ReflectionDropdown;
    //分辨率
    public Dropdown ResolutionDropdown;
    //全屏
    public Toggle FullScreenToggle;
    public Button CloseButton;

    public CountryCodeData CodeData = new CountryCodeData();
    public List<string> ProvinceOptions = new List<string>();
    public List<string> CityOptions = new List<string>();
    //public GameSettingDataReactive DataSource = new GameSettingDataReactive();
    public ResolutionDatas ResData = new ResolutionDatas();
    #endregion
    public override void Awake()
    {
        base.Awake();
        Observable.EveryUpdate()
            .Subscribe(_ =>
            {
                TimeSlider.value = AzureSkyController.Instance.timeOfDay.hour;
            });
        #region 获取省份列表
        HttpManager.Instance.Get<CountryCodeData>(HttpManager.Instance.GetCityCode, data =>
        {
            CodeData = data;
            foreach (var tempdata in data.CountryCode)
            {
                ProvinceOptions.Add(tempdata.province);
            }
            ProvinceDropdown.AddOptions(ProvinceOptions);
            GetCity(true);

        });
        #endregion
        #region 获取分辨率数据
#if UNITY_STANDALONE
        var url = HttpManager.Instance.GetResolution;
        HttpManager.Instance.Get<ResolutionDatas>(url, data =>
        {
            ResData = data;
            foreach (var temdata in ResData.ResList)
            {
                var option = new Dropdown.OptionData
                {
                    text = temdata.Width + "*" + temdata.Height
                };
                ResolutionDropdown.options.Add(option);
            }

            //分辨率
            DataSource.Resolution.Subscribe(value => ResolutionDropdown.value = value).AddTo(gameObject);
            DataSource.Resolution.Subscribe(value =>
            {
                Screen.SetResolution(ResData.ResList[value].Width, ResData.ResList[value].Height, DataSource.FullScreen.Value);

            }).AddTo(gameObject);
            ResolutionDropdown.OnValueChangedAsObservable().Subscribe(value => DataSource.Resolution.Value = value);

            //全屏
            DataSource.FullScreen.Subscribe(value => FullScreenToggle.isOn = value).AddTo(gameObject);
            DataSource.FullScreen.Subscribe(value =>
            {
                Screen.SetResolution(ResData.ResList[ResolutionDropdown.value].Width, ResData.ResList[ResolutionDropdown.value].Height, value);
            }).AddTo(gameObject);
            FullScreenToggle.OnValueChangedAsObservable().Subscribe(value => DataSource.FullScreen.Value = value);

        });
#endif
        #endregion
#if UNITY_WEBGL
        ResolutionDropdown.interactable = false;
        FullScreenToggle.interactable = false;
        
#endif
#region 数据绑定
        //省份
        DataSource.Province.Subscribe(value => ProvinceDropdown.value = value).AddTo(gameObject);
        ProvinceDropdown.OnValueChangedAsObservable().Subscribe(value => DataSource.Province.Value = value);
        //城市
        DataSource.City.Subscribe(value => CityDropdown.value = value).AddTo(gameObject);
        CityDropdown.OnValueChangedAsObservable().Subscribe(value => DataSource.City.Value = value);
        //实时天气
        DataSource.RealTimeWeather.Subscribe(value => RTWeatherToggle.isOn = value).AddTo(gameObject);
        RTWeatherToggle.OnValueChangedAsObservable().Subscribe(value => DataSource.RealTimeWeather.Value = value);
        //天气
        DataSource.Weather.Subscribe(value => WeatherDropdown.value = value).AddTo(gameObject);
        DataSource.Weather.SubscribeToText(UIManager.Instance.GetView<ToolBarPanel>().WeatherText, x => WeatherDropdown.captionText.text).AddTo(gameObject);
        DataSource.Weather
            .Where(_ => RTWeatherToggle.isOn == false)
            .Subscribe(value =>
            {
                AzureSkyController.Instance.isBlendingWeathers = false;
                AzureSkyController.Instance.SetNewWeatherProfile(value);
            }).AddTo(gameObject);

        WeatherDropdown.OnValueChangedAsObservable()
            .Where(_ => RTWeatherToggle.isOn == false)
            .Subscribe(s => DataSource.Weather.Value = s);
        //温度
        DataSource.Temperature.Subscribe(value => TempSlider.value = value).AddTo(gameObject);
        DataSource.Temperature.SubscribeToText(UIManager.Instance.GetView<ToolBarPanel>().TemperatureText, x => (int)TempSlider.value + "℃").AddTo(gameObject);
        DataSource.Temperature.SubscribeToText(TempInput, x => ((int)TempSlider.value).ToString()).AddTo(gameObject);
        TempSlider.OnValueChangedAsObservable().Subscribe(s => DataSource.Temperature.Value = (int)s);
        TempInput.OnEndEditAsObservable().Subscribe(s => DataSource.Temperature.Value = int.Parse(s));
        //风力
        DataSource.WindForce.Subscribe(value => AssetManager.Instance.windZone.windMain = value);
        DataSource.WindForce.Subscribe(value => ForceSlider.value = value).AddTo(gameObject);
        DataSource.WindForce.SubscribeToText(UIManager.Instance.GetView<ToolBarPanel>().WindText, x => (int)ForceSlider.value + "级").AddTo(gameObject);
        DataSource.WindForce.SubscribeToText(ForceInput, x => ((int)ForceSlider.value).ToString()).AddTo(gameObject);
        ForceSlider.OnValueChangedAsObservable().Subscribe(s => DataSource.WindForce.Value = (int)s);
        ForceInput.OnEndEditAsObservable().Subscribe(s => DataSource.WindForce.Value = int.Parse(s));
        //风向
        DataSource.WindDirection.Subscribe(value => DirectionDropdown.value = value).AddTo(gameObject);
        DataSource.WindDirection.SubscribeToText(UIManager.Instance.GetView<ToolBarPanel>().DirectionText, x => DirectionDropdown.captionText.text).AddTo(gameObject);
        DataSource.WindDirection.Subscribe(value => AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, value * 45 - AssetManager.Instance.InitialAngle, 0)).AddTo(gameObject);
        DirectionDropdown.OnValueChangedAsObservable().Subscribe(s => DataSource.WindDirection.Value = s);
        //昼夜交替
        DataSource.TimeOfDay.Subscribe(value => TimeOfDayToggle.isOn = value).AddTo(gameObject);
        DataSource.TimeOfDay.Subscribe(isOn =>
        {
            if (isOn)
            {
                DurationTime = DurationSlider.value * 60f;
            }

            else
            {
                DurationTime = 0f;
                TimeSlider.value = 11.0f;
            }
            AzureSkyController.Instance.timeOfDay.dayCycle = DurationTime;
            var value = AzureSkyController.Instance.timeOfDay.GetDayLength();
            AzureSkyController.Instance.GetTimeProgression(value);

        }).AddTo(gameObject);
        TimeOfDayToggle.OnValueChangedAsObservable().Subscribe(s => DataSource.TimeOfDay.Value = s);
        //持续时间
        DataSource.Duration.Subscribe(value => DurationSlider.value = value).AddTo(gameObject);
        DataSource.Duration.SubscribeToText(DurationInput, x => DurationSlider.value.ToString()).AddTo(gameObject);
        DataSource.Duration.Subscribe(value =>
        {
            DurationTime = value * 60f;
            if (TimeOfDayToggle.isOn)
            {
                AzureSkyController.Instance.timeOfDay.dayCycle = DurationTime;
                var value2 = AzureSkyController.Instance.timeOfDay.GetDayLength();
                AzureSkyController.Instance.GetTimeProgression(value2);
            }
        }).AddTo(gameObject);
        DurationSlider.OnValueChangedAsObservable().Subscribe(s =>
        {
            DataSource.Duration.Value = s;

        });
        DurationInput.OnEndEditAsObservable().Subscribe(s => DataSource.Duration.Value = float.Parse(s));
        //时间滑块
        DataSource.Time.Subscribe(value => TimeSlider.value = value).AddTo(gameObject);
        DataSource.Time.Subscribe(value =>
        {
            string[] times = value.ToString("F2").Split('.');
            int hour = int.Parse(times[0]);
            float _minute = int.Parse(times[1]) * 0.6f;
            int minute = (int)_minute;
            HourInput.text = hour.ToString("D2");
            MinuteInput.text = minute.ToString("D2");

        }).AddTo(gameObject);
        DataSource.Time.Subscribe(value => AzureSkyController.Instance.timeOfDay.hour = value).AddTo(gameObject);
        TimeSlider.OnValueChangedAsObservable().Subscribe(s => DataSource.Time.Value = s);
        HourInput.OnEndEditAsObservable().Subscribe(s => DataSource.Time.Value = float.Parse(s + "." + int.Parse(MinuteInput.text) / 6));
        MinuteInput.OnEndEditAsObservable().Subscribe(s => DataSource.Time.Value = float.Parse(HourInput.text + "." + int.Parse(s) / 6));
        //贴图质量
        DataSource.TextureQuality.Subscribe(value => TextureDropdown.value = value).AddTo(gameObject);
        DataSource.TextureQuality.Subscribe(value => QualitySettings.masterTextureLimit = value).AddTo(gameObject);
        TextureDropdown.OnValueChangedAsObservable().Subscribe(v => DataSource.TextureQuality.Value = v);
        //各向异性
        DataSource.Anisotropic.Subscribe(value => AnisotropicDropdown.value = value).AddTo(gameObject);
        DataSource.Anisotropic.Subscribe(value =>
        {
            switch (value)
            {
                case 0:
                    QualitySettings.anisotropicFiltering = AnisotropicFiltering.Disable;
                    break;
                case 1:
                    QualitySettings.anisotropicFiltering = AnisotropicFiltering.ForceEnable;
                    break;
            }

        }).AddTo(gameObject);
        AnisotropicDropdown.OnValueChangedAsObservable().Subscribe(v => DataSource.Anisotropic.Value = v);
        //画面质量
        DataSource.Quality.Subscribe(value => QualityDropdown.value = value).AddTo(gameObject);
        DataSource.Quality
           .Subscribe(value =>
           {
               //QualitySettings.renderPipeline = AssetManager.Instance.RenderPipelines[value];
               QualitySettings.SetQualityLevel(value);

           });
        QualityDropdown.OnValueChangedAsObservable().Subscribe(value => DataSource.Quality.Value = value);
        //阴影开关
        DataSource.ShadowSwitch.Subscribe(value => ShadowToggle.isOn = value).AddTo(gameObject);
        DataSource.ShadowSwitch.Subscribe(value =>
        {
            if (value)
            {
                AzureSkyController.Instance.lightTransform.GetComponent<Light>().shadows = LightShadows.Soft;
            }

            else
            {
                AzureSkyController.Instance.lightTransform.GetComponent<Light>().shadows = LightShadows.None;
            }

        }).AddTo(gameObject);
        ShadowToggle.OnValueChangedAsObservable().Subscribe(value => DataSource.ShadowSwitch.Value = value);
        //亮度
        DataSource.Brightness.Subscribe(value => BrightnessSlider.value = value).AddTo(gameObject);
        DataSource.Brightness.Subscribe(value => AzureSkyController.Instance.LightAddition = value).AddTo(gameObject);
        BrightnessSlider.OnValueChangedAsObservable().Subscribe(value => DataSource.Brightness.Value = value);
        //反射
        //DataSource.Reflection.Subscribe(value => ReflectionDropdown.value = value).AddTo(gameObject);
        //DataSource.Reflection.Subscribe(value =>
        //{
        //    switch (value)
        //    {
        //        case 0:
        //            AssetManager.Instance.ReflectionProbes.SetActive(false);
        //            break;
        //        case 1:
        //            AssetManager.Instance.ReflectionProbes.SetActive(true);
        //            break;
        //    }
        //}).AddTo(gameObject);
        //ReflectionDropdown.OnValueChangedAsObservable().Subscribe(value => DataSource.Reflection.Value = value);
#endregion
#region Button Click
        ProvinceDropdown.OnValueChangedAsObservable()
            .Where(_ => CodeData.CountryCode != null)
            .Subscribe(value =>
            {
                GetCity(false);
            });
        CityDropdown.OnValueChangedAsObservable()
            .Where(_ => CodeData.CountryCode != null)
            .Subscribe(value =>
            {
                AssetManager.Instance.CityCode = GetCityCode(ProvinceDropdown.captionText.text, CityDropdown.captionText.text);
                GetWeather();
            });
        RTWeatherToggle.onValueChanged.AddListener((bool value) => CustomWeather(!value));

        RTWeatherButton.OnClickAsObservable()
            .Where(_ => RTWeatherToggle.isOn)
            .Subscribe(_ => GetWeather());
        //重置
        transform.Find("Bottom/Restoring").GetComponent<Button>().OnClickAsObservable()
            .Subscribe(_ =>
            {
                var data = new GameSettingData
                {
                    Province = DataSource.Province.Value,
                    City = DataSource.City.Value
                };
                DataSource.SetData(data);
                GetWeather();
            });
        //关闭
        CloseButton.OnClickAsObservable()
            .Subscribe(_ => 
            {
                GetComponent<RectTransform>().DOAnchorPos(new Vector2(0, 2000), 0.1f);
#if !UNITY_WEBGL
                SaveData();
#endif
            } );
#endregion
#region 面板切换
        TimeToggle.OnValueChangedAsObservable()
            .Subscribe(value =>
            {
                if (value)
                {
                    TimePanel.alpha = 1;
                    TimePanel.interactable = true;
                    TimePanel.blocksRaycasts = true;
                }
                else
                {
                    TimePanel.alpha = 0;
                    TimePanel.interactable = false;
                    TimePanel.blocksRaycasts = false;
                }
            });
        DisplayToggle.OnValueChangedAsObservable()
            .Subscribe(value =>
            {
                if (value)
                {
                    DisplayPanel.alpha = 1;
                    DisplayPanel.interactable = true;
                    DisplayPanel.blocksRaycasts = true;
                }
                else
                {
                    DisplayPanel.alpha = 0;
                    DisplayPanel.interactable = false;
                    DisplayPanel.blocksRaycasts = false;
                }
            });
#endregion
    }

#region Privte Function
    //获取城市
    private void GetCity(bool isGetData)
    {
        CityDropdown.options.Clear();
        CityOptions.Clear();
        foreach (ProvinceData data in CodeData.CountryCode)
        {
            if (ProvinceDropdown.captionText.text == data.province)
            {
                foreach (var city in data.City)
                {
                    CityOptions.Add(city.CityName);
                }
            }
        }
        CityDropdown.AddOptions(CityOptions);
        CityDropdown.value = 0;
        AssetManager.Instance.CityCode = GetCityCode(ProvinceDropdown.captionText.text, CityDropdown.captionText.text);
        if (isGetData)
            GetData();

    }
    //获取城市代码
    string GetCityCode(string ProvinceName, string CityName)
    {
        string code = "";

        for (int i = 0; i < CodeData.CountryCode.Count; i++)
        {
            for (int j = 0; j < CodeData.CountryCode[i].City.Count; j++)
            {
                if (ProvinceName == CodeData.CountryCode[i].province)
                {
                    if (CityName == CodeData.CountryCode[i].City[j].CityName)
                    {
                        code = CodeData.CountryCode[i].City[j].CityCode;
                        break;
                    }
                }

            }
        }
        return code;
    }
    private void GetWeather()
    {
        var url = $"{AssetManager.Instance.WeatherCallPath + AssetManager.Instance.CityCode}&key={AssetManager.Instance.Key}";
        HttpManager.Instance.Get<WeatherData>(url, tempdata =>
        {
            Debug.Log(tempdata.lives[0].city);
            var weather = tempdata.lives[0].weather;
            Debug.Log(weather);
            UIManager.Instance.GetView<ToolBarPanel>().CityText.text = CityDropdown.captionText.text; //tempdata.lives[0].city;
            if (RTWeatherToggle.isOn)
            {
                UIManager.Instance.GetView<ToolBarPanel>().WeatherText.text = tempdata.lives[0].weather;
                UIManager.Instance.GetView<ToolBarPanel>().TemperatureText.text = tempdata.lives[0].temperature + "℃";
                UIManager.Instance.GetView<ToolBarPanel>().DirectionText.text = tempdata.lives[0].winddirection + "风";
                UIManager.Instance.GetView<ToolBarPanel>().WindText.text = tempdata.lives[0].windpower + "级";
                AzureSkyController.Instance.isBlendingWeathers = false;
                if (weather.Contains("多云"))
                {
                    AzureSkyController.Instance.SetNewWeatherProfile(1);
                }
                else if (weather == "阴" || weather.Contains("霾") || weather.Contains("雾"))
                {
                    AzureSkyController.Instance.SetNewWeatherProfile(2);
                }
                else if (weather.Contains("雨"))
                {
                    AzureSkyController.Instance.SetNewWeatherProfile(3);
                }
                else if (weather.Contains("雪"))
                {
                    AzureSkyController.Instance.SetNewWeatherProfile(4);
                }
                else
                {
                    AzureSkyController.Instance.SetNewWeatherProfile(0);

                }

                switch (tempdata.lives[0].winddirection)
                {
                    case "北":
                        AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, 0 * 45 - AssetManager.Instance.InitialAngle, 0);
                        break;
                    case "东北":
                        AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, 1 * 45 - AssetManager.Instance.InitialAngle, 0);
                        break;
                    case "东":
                        AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, 2 * 45 - AssetManager.Instance.InitialAngle, 0);
                        break;
                    case "东南":
                        AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, 3 * 45 - AssetManager.Instance.InitialAngle, 0);
                        break;
                    case "南":
                        AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, 4 * 45 - AssetManager.Instance.InitialAngle, 0);
                        break;
                    case "西南":
                        AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, 5 * 45 - AssetManager.Instance.InitialAngle, 0);
                        break;
                    case "西":
                        AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, 6 * 45 - AssetManager.Instance.InitialAngle, 0);
                        break;
                    case "西北":
                        AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, 7 * 45 - AssetManager.Instance.InitialAngle, 0);
                        break;
                    case "无风向":
                        AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, 0 * 45 - AssetManager.Instance.InitialAngle, 0);
                        break;
                    case "旋转不定":
                        AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, 0 * 45 - AssetManager.Instance.InitialAngle, 0);
                        break;
                }


                if (tempdata.lives[0].windpower == "≤3")
                {
                    AssetManager.Instance.windZone.windMain = 1;
                }
                else
                {
                    var value = Convert.ToSingle(tempdata.lives[0].windpower);
                    AssetManager.Instance.windZone.windMain = value;
                }

            }


        });
    }
    private void CustomWeather(bool isOn)
    {
        WeatherDropdown.interactable = isOn;
        TempSlider.interactable = isOn;
        TempInput.interactable = isOn;
        ForceSlider.interactable = isOn;
        ForceInput.interactable = isOn;
        DirectionDropdown.interactable = isOn;

        if (isOn)
        {
            UIManager.Instance.GetView<ToolBarPanel>().WeatherText.text = WeatherDropdown.captionText.text;
            AzureSkyController.Instance.isBlendingWeathers = false;
            AzureSkyController.Instance.SetNewWeatherProfile(WeatherDropdown.value);

            UIManager.Instance.GetView<ToolBarPanel>().TemperatureText.text = (int)TempSlider.value + "℃";
            UIManager.Instance.GetView<ToolBarPanel>().WindText.text = (int)ForceSlider.value + "级";

            UIManager.Instance.GetView<ToolBarPanel>().DirectionText.text = DirectionDropdown.captionText.text;
            AssetManager.Instance.windZone.transform.localEulerAngles = new Vector3(0, DirectionDropdown.value * 45 - AssetManager.Instance.InitialAngle, 0);
        }
        else
        {
            GetWeather();
        }


    }
    //加载数据
    private void GetData()
    {
        var url = HttpManager.Instance.GetGameSetting;
        HttpManager.Instance.Get<GameSettingData>(url, data =>
        {
            DataSource.SetData(data);
        });
    }
    //保存数据
    private void SaveData()
    {
        var url = string.Format(HttpManager.Instance.GetGameSetting);
        HttpManager.Instance.PostData(url, DataSource.GetData());
    }
#endregion

}