using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Enums;
using APT.BaseData.Domain.IServices;
using APT.BaseData.Domain.Msg;
using APT.Infrastructure.Core;
using APT.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using APT.Infrastructure.Api;
namespace APT.BaseData.Services.DomainServices
{
    public partial class PFCodeRuleService : CommonService, IPFCodeRuleService
    {
        public PFCodeRuleService(IRepository repository)
            : base(repository)
        {
        }
        private static object xflag = new object();
        public string Gen(SystemCodeFilter fiter)
        {

            var returnList = "123";
            if (fiter.Count < 1)
                return returnList;
            returnList = DoGetRuleCode(fiter.CodeType, fiter.OrgId ?? Guid.Empty,
                fiter.Count, true);
            return returnList;
        }
        public string NewGenSerial(SystemCodeFilter fiter)
        {
            var date = DateTime.Now.ToString("yyyyMMdd");
            lock (xflag)
            {
                var baseConfig = this.GetEntityByRedis<T_FM_ORGANIZATION>(fiter.GetOrgId(), fiter.GetOrgId());
                if (baseConfig == null)
                    this.ThrowError("010002");
                var codeRule = this.GetEntityByRedis<T_PF_CODE_RULE>(fiter.CodeType.ToString(), fiter.GetOrgId());
                if (codeRule == null)
                    this.ThrowError("020026", fiter.CodeType.ToString());
                var serialList = new List<string>();
                var orgCode = codeRule.IS_ORG_CODE ? baseConfig.CODE : "";
                var tenantCode = codeRule.IS_TENANT_CODE ? baseConfig.TENANT_CODE : "";
                if (!(codeRule.IS_IGNORE_DATE ?? false))
                {
                    if (codeRule.CURRENT_DATA != date)
                    {
                        codeRule.NUM = 0;
                        codeRule.CURRENT_DATA = date;
                    }
                    for (int n = 1; n <= fiter.Count; n++)
                    {
                        serialList.Add($"{codeRule.CODE_PREFIX}{tenantCode}{orgCode}{date}{(codeRule.NUM + n).PadLeft(codeRule.SERIAL_NUM_LEN, '0')}");
                    }
                    codeRule.NUM += fiter.Count;
                }
                else
                {
                    for (int n = 1; n <= fiter.Count; n++)
                    {
                        serialList.Add($"{codeRule.CODE_PREFIX}{tenantCode}{orgCode}{(codeRule.NUM + n).PadLeft(codeRule.SERIAL_NUM_LEN, '0')}");
                    }
                    codeRule.NUM += fiter.Count;
                }
                this.UpdateEntity<T_PF_CODE_RULE>(codeRule);
                return string.Join(',', serialList);
            }
        }
        public string NewGenSerialByDb(SystemCodeFilter fiter, string dbConn)
        {
            BaseFilter baseFilter = new BaseFilter();
            baseFilter.IsMultipleDb = true;
            baseFilter.OrgId = fiter.OrgId;
            //baseFilter.IgnoreOrgRule = true;
            var date = DateTime.Now.ToString("yyyyMMdd");
            lock (xflag)
            {
                var baseConfig = this.GetEntity<T_FM_ORGANIZATION>(x => x.ORG_ID == fiter.OrgId, baseFilter);
                if (baseConfig == null)
                    this.ThrowError("010002");
                var codeRule = this.GetEntity<T_PF_CODE_RULE>(x => x.CODE_TYPE == fiter.CodeType, baseFilter);
                if (codeRule == null)
                    this.ThrowError("020026", fiter.CodeType.ToString());
                var serialList = new List<string>();
                var orgCode = codeRule.IS_ORG_CODE ? baseConfig.CODE : "";
                var tenantCode = codeRule.IS_TENANT_CODE ? baseConfig.TENANT_CODE : "";
                if (!(codeRule.IS_IGNORE_DATE ?? false))
                {
                    if (codeRule.CURRENT_DATA != date)
                    {
                        codeRule.NUM = 0;
                        codeRule.CURRENT_DATA = date;
                    }
                    for (int n = 1; n <= fiter.Count; n++)
                    {
                        serialList.Add($"{codeRule.CODE_PREFIX}{tenantCode}{orgCode}{date}{(codeRule.NUM + n).PadLeft(codeRule.SERIAL_NUM_LEN, '0')}");
                    }
                    codeRule.NUM += fiter.Count;
                }
                else
                {
                    for (int n = 1; n <= fiter.Count; n++)
                    {
                        serialList.Add($"{codeRule.CODE_PREFIX}{tenantCode}{orgCode}{(codeRule.NUM + n).PadLeft(codeRule.SERIAL_NUM_LEN, '0')}");
                    }
                    codeRule.NUM += fiter.Count;
                }
                this.UpdateEntityByConn<T_PF_CODE_RULE>(codeRule, dbConn);
                return string.Join(',', serialList);
            }
        }
        public string NewGenSerialByTenant(SystemCodeFilter fiter, string TenantCode)
        {
            BaseFilter baseFilter = new BaseFilter();
            baseFilter.IsSpecifyDb = true;
            baseFilter.SpecifyTenant = TenantCode;
            baseFilter.OrgId = fiter.OrgId;
            //baseFilter.IgnoreOrgRule = true;
            var date = DateTime.Now.ToString("yyyyMMdd");
            lock (xflag)
            {
                var baseConfig = this.GetEntity<T_FM_ORGANIZATION>(x => x.ORG_ID == fiter.OrgId, baseFilter);
                if (baseConfig == null)
                    this.ThrowError("010002");
                var codeRule = this.GetEntity<T_PF_CODE_RULE>(x => x.CODE_TYPE == fiter.CodeType, baseFilter);
                if (codeRule == null)
                    this.ThrowError("020026", fiter.CodeType.ToString());
                var serialList = new List<string>();
                var orgCode = codeRule.IS_ORG_CODE ? baseConfig.CODE : "";
                var tenantCode = codeRule.IS_TENANT_CODE ? baseConfig.TENANT_CODE : "";
                if (!(codeRule.IS_IGNORE_DATE ?? false))
                {
                    if (codeRule.CURRENT_DATA != date)
                    {
                        codeRule.NUM = 0;
                        codeRule.CURRENT_DATA = date;
                    }
                    for (int n = 1; n <= fiter.Count; n++)
                    {
                        serialList.Add($"{codeRule.CODE_PREFIX}{tenantCode}{orgCode}{date}{(codeRule.NUM + n).PadLeft(codeRule.SERIAL_NUM_LEN, '0')}");
                    }
                    codeRule.NUM += fiter.Count;
                }
                else
                {
                    for (int n = 1; n <= fiter.Count; n++)
                    {
                        serialList.Add($"{codeRule.CODE_PREFIX}{tenantCode}{orgCode}{(codeRule.NUM + n).PadLeft(codeRule.SERIAL_NUM_LEN, '0')}");
                    }
                    codeRule.NUM += fiter.Count;
                }
                this.UpdateEntityByTenant<T_PF_CODE_RULE>(codeRule, tenantCode);
                return string.Join(',', serialList);
            }
        }
        public string GenNoUpdate(SystemCodeFilter fiter)
        {
            var returnList = "";
            if (fiter.Count < 1)
                return returnList;
            returnList = DoGetRuleCode(fiter.CodeType, fiter.OrgId ?? Guid.Empty,
                fiter.Count, false);
            return returnList;
        }

        /// <summary>
        /// 获取 编号 （默认 1个  消息类型）
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="codeType"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public string GetCodeTypeRuleCode(Guid? orgId, int codeType = 5, int count = 1)
        {
            if (orgId == null)
            {
                orgId = APT.Infrastructure.Api.AppContext.CurrentSession.OrgId;
            }
            return DoGetRuleCode(codeType, orgId.Value, count, true);
        }


        private string DoGetRuleCode(int codeType, Guid orgId, int count, bool isUpdate)
        {
            CodeRuleParam param = new CodeRuleParam();
            param.CodeType = codeType;
            param.Count = count;
            param.OrgId = orgId;
            return this.GetRuleCodes(param);
        }

    }
}
