using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using RB_MES_API.Context;
using RB_MES_API.HostService;
using RB_MES_API.Models;
using System.Data;

namespace RB_MES_API.Controllers
{
    /// <summary>
    /// 
    /// </summary>
    public class EnpowerTask : IHostedService, IDisposable
    {
        private readonly RBContext _context;
        private readonly IServiceScopeFactory _serviceScopeFactory;     //创建一个完全独立的新作用域，以调用本地轮询服务
        private readonly ILogger _logger;
        private readonly IDistributedCache _distributedCache;
        private readonly IKDSqlHelper _sqlHelper;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceScopeFactory"></param>
        /// <param name="logger"></param>
        public EnpowerTask(IServiceScopeFactory serviceScopeFactory,ILogger<EnpowerTask> logger
            , RBContext context, IDistributedCache distributed,IKDSqlHelper sqlHelper )//静态方法
        {
            _serviceScopeFactory = serviceScopeFactory;
            _logger = logger;
            _context = context;
            _distributedCache = distributed;
            _sqlHelper = sqlHelper;
        }

        /// <inheritdoc/>

        public void Dispose()
        {
            this.Dispose();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        async Task<bool> GetAutoService()
        {
            bool autoService = false;
            await Task.Run(() => {
                if (LocalStaticRequest.AutoPushTask)
                {
                    autoService = true;
                    Thread thread =new Thread (waitstarservice);
                    thread.IsBackground = true;
                    thread.Start ();
                }
                return Task.CompletedTask;
            });
            
            return autoService;
        }
        async Task IHostedService.StartAsync(CancellationToken cancellationToken)
        {
            if (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    //如果缓存中不存在，就从数据库里取出来再放进缓存
                    List<SystemProfile> sys = CacheHelper.GetCache<List<SystemProfile>>("LocalStaticRequest");
                    if (sys == null)
                    {
                        //先初始化全局变量
                        sys = await _context.r_SystemProfiles!.AsNoTracking().ToListAsync();
                    }
                    CacheHelper.Set_AbsluteExpire("LocalStaticRequest", sys);

                    var pushservice = sys.Find(s => s.FCategoryID == 1 && s.FKey == "AutoPushTask");
                    var sendinterval = sys.Find(s => s.FCategoryID == 1 && s.FKey == "SendInterval");
                    var tokenurl= sys.Find(s => s.FCategoryID == 4 && s.FKey == "TokenUrl");
                    bool isauto = pushservice != null ? pushservice.FValue == "1" ? true : false : false;
                    int sendTime = sendinterval == null ? 0 : 60 * 1000 * int.Parse(sendinterval.FValue);//以分钟作为单位...
                    var apigroupid = sys.Find(s => s.FCategoryID == 1 && s.FKey == "APIGrouID");
                    string url = tokenurl.FValue;
                    //如果最后一个字符不是"/"就添加上去
                    url += url.Substring(url.Length - 1, 1) == "/" ? "" : "/";
                    LocalStaticRequest.APIGrouID = apigroupid == null ? 0 : apigroupid.FID;
                    LocalStaticRequest.SendTime = sendTime;
                    LocalStaticRequest.LocasServerStatus = false;
                    LocalStaticRequest.AutoPushTask = isauto;
                    LocalStaticRequest.tokenurl = url;

                    //将计量单位加入缓存
                    Thread uthread = new Thread(AddUnitCache);
                    uthread.IsBackground = true;
                    uthread.Start();
                    //建议测试阶段手工启动，生产环境下还是自动启动
                    bool B = await GetAutoService();
                    if (!B)
                    {
                        Thread thread = new Thread(waitstarserviceAuto);
                        thread.IsBackground = true;
                        thread.Start();
                    }
                }
                catch (Exception)
                {
                    //如果金蝶Cloud登录失败，就会发生异常，可能导致程序崩溃...
                    throw;
                }
                
            }
        }

        private void AddUnitCache()
        {
            DataTable table = CacheHelper.GetCache<DataTable>("BD_UNIT");
            if(table == null)
            {
                string sql = "SELECT * FROM kdCloud_BD_UNIT WHERE FDocumentStatus=@C AND FForbidStatus=@A";
                SqlParameter[] sqlParameters = new SqlParameter[]
                {
                new SqlParameter("@C","C"),
                new SqlParameter("@A","A")
                };
                string reason = string.Empty;
                DataSet dataSet = _sqlHelper.GetDataSet(CommandType.Text, sql, sqlParameters, ref reason);
                if (dataSet != null)
                {
                    if(dataSet.Tables.Count > 0)
                    {
                        table = dataSet.Tables[0];
                        if(table.Rows.Count > 0) { CacheHelper.Set_AbsluteExpire("BD_UNIT", table); }                       
                    }
                }
            }
            
        }
        private void waitstarservice()
        {
            using var scope = _serviceScopeFactory.CreateScope();
            IPushMesInterface myScopedService = scope.ServiceProvider.GetRequiredService<IPushMesInterface>();
            myScopedService.DoAutoWork();
        }
        /// <summary>
        /// 一直等着，直到出现启动服务的变量
        /// </summary>
        private void waitstarserviceAuto()
        {
            while (true)
            {
                if (LocalStaticRequest.AutoPushTask)
                {
                    Thread thread = new Thread(waitstarservice);
                    thread.IsBackground = true;
                    thread.Start();
                    break;
                }
            }
        }

        Task IHostedService.StopAsync(CancellationToken cancellationToken)
        {
            Dispose();
            _logger.LogInformation(DateTime.Now.ToLongTimeString(), "推送服务停止...");
            return Task.CompletedTask;
        }
    }
}
