using System.Collections.Generic;
using System.Linq;
using NBC;
using UnityEngine;

namespace NBF.Setting
{
    /// <summary>
    /// 分辨率设置
    /// </summary>
    [Sort(2)]
    public class ResolutionSetting : MultiOption<Resolution>
    {
        private int _defaultResolution;
        public override string Name => "Resolution";
        public override string Group => SettingsDef.Group.Graphic;
        protected override int DefaultValue => _defaultResolution;
        public override string Tab => SettingsDef.Tab.Graphic;
        // public override bool IsDropdown => true;


        static readonly (int w, int h)[] Classic16_9 =
        {
            (1280, 720),
            (1600, 900),
            (1920, 1080),
            (2560, 1440),
            (3840, 2160),
        };

        static readonly (int w, int h)[] Classic16_10 =
        {
            (1280, 800),
            (1680, 1050),
            (1920, 1200),
            (2560, 1600),
        };

        static readonly (int w, int h)[] Classic21_9 =
        {
            (2560, 1080),
            (3440, 1440),
            (3840, 1600),
        };

        static readonly (int w, int h)[] Classic32_9 =
        {
            (3840, 1080),
            (5120, 1440),
        };

        protected override void OnInitialize()
        {
            var supported = Screen.resolutions
                .Select(r => (r.width, r.height))
                .Distinct()
                .ToHashSet();

            var mainWindowDisplayInfo = Screen.mainWindowDisplayInfo; // 主窗口所在显示器的信息

            float aspect = (float)Screen.currentResolution.width / Screen.currentResolution.height;

            bool Near(float a, float b, float eps = 0.03f) => Mathf.Abs(a - b) <= eps;

            IEnumerable<(int w, int h)> preferred =
                Near(aspect, 16f / 9f) ? Classic16_9 :
                Near(aspect, 16f / 10f) ? Classic16_10 :
                Near(aspect, 21f / 9f) ? Classic21_9 :
                Near(aspect, 32f / 9f) ? Classic32_9 :
                Classic16_9; // 兜底


            var list = preferred.Where(supported.Contains).ToList();

            // 兜底：保证原生分辨率一定在列表里（尤其是超宽屏）
            var native = (Screen.currentResolution.width, Screen.currentResolution.height);
            if (!list.Contains(native) && supported.Contains(native))
                list.Add(native);

            // 排序（从小到大或从大到小都行）
            list = list.OrderBy(x => x.w * x.h).ToList();


            foreach (var resolution in list)
            {
                var w = resolution.w;
                var h = resolution.h;
                if (w > mainWindowDisplayInfo.width || h > mainWindowDisplayInfo.height) continue;
                AddOption($"{w}x{h}", new Resolution()
                {
                    width = w,
                    height = h,
                });
                Log.Info($"Resolution {w}x{h}");
            }
            

            TryGetIndex(t =>
                    t.width == Screen.currentResolution.width && t.height == Screen.currentResolution.height,
                out _defaultResolution);

            if (_defaultResolution < 0)
            {
                _defaultResolution = 0;
            }

            var n = Value;
            var nm = SaveValue;
            if (!PlayerPrefs.HasKey(SaveKey))
            {
                
            }
        }
        

        protected override void OnApply()
        {
            var resolution = GetSelectedOption();
            Log.Info($"Screen.fullScreenMode {Screen.fullScreenMode}");
            var mode = FullScreenMode.ExclusiveFullScreen;
            var screenMode = Root.GetSettingOption<FullScreenModeSetting>();
            if (screenMode != null)
            {
                mode = screenMode.GetSelectedOption();
            }

            if (mode == FullScreenMode.ExclusiveFullScreen)
            {
                Screen.SetResolution(Screen.currentResolution.width, Screen.currentResolution.height, mode);
            }
            else
            {
                Screen.SetResolution(resolution.width, resolution.height, mode);
            }
        }
    }
}