using StackExchange.Redis;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XYY.Core.Standard.Data.Redis;

namespace XYY.Service.Standard.Finance.Charging.Attached
{
    public enum ContainsZipStatus
    {
        NoData = 0,
        NotExists = 1,
        Exists = 2
    }

    public class ITAttachedZipSet : IDisposable
    {
        HashSet<string> zipSet = null;
        IDatabase db;
        bool keyExistsChecked = false;
        object syncRoot = new object();

        const string ITAttachedZipKey = "ITAttachedZip";
        const string ITAttachedZip20230324Key = "ITAttachedZip20230324";

        public ITAttachedZipSet(RedisHelper helper)
        {
            this.db = helper.GetDatabase();
        }



        public void Dispose()
        {
            if (zipSet != null)
            {
                zipSet.Clear();
                zipSet = null;
            }
        }



        internal ContainsZipStatus ContainsZip(string zipCode)
        {
            if (zipSet == null)
            {
                if (!keyExistsChecked)
                {
                    lock (syncRoot)
                    {
                        string redisKey= ITAttachedZipKey;
                        if (DateTime.Now >= Convert.ToDateTime("2023-03-24")) { redisKey = ITAttachedZip20230324Key; }
                        if (!keyExistsChecked)
                        {
                            var keyExists = db.KeyExists(redisKey);
                            keyExistsChecked = true;

                            if (keyExists)
                            {
                                zipSet = new HashSet<string>();

                                var members = db.SetMembers(redisKey);
                                var list = members.Select(m => m == RedisValue.Null ? null : m.ToString());
                                if (list?.Any() == true)
                                {
                                    zipSet = list.ToHashSet();
                                }

                            }
                            else return ContainsZipStatus.NoData;
                        }
                        if (zipSet == null)
                            return ContainsZipStatus.NoData;
                    }
                }
                else return ContainsZipStatus.NoData;
            }

            var exists = zipSet.Any(i => string.Equals(i, zipCode, StringComparison.OrdinalIgnoreCase));
            if (exists) return ContainsZipStatus.Exists;
            else return ContainsZipStatus.NotExists;


        }
    }
}
