using CloudBuilder.Core.DatabaseAccessor;
using CloudBuilder.Core.DatabaseAccessor.Entity;
using CloudBuilder.Core.Service;
using CloudBuilder.Security.Data;
using CloudBuilder.Security.Entity;
using CloudBuilder.Security.Policy;
using CloudBuilder.Security.SearchCriteria;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace CloudBuilder.Security.Service
{
    public class LocaleService : ILocaleService
    {
        private readonly IApplicationService service;

        private IRepository<LocaleEntity> repository;
        public LocaleService(IApplicationService service)
        {
            this.service = service;
            repository = service.GetRepository<IRepository<LocaleEntity>>();
        }

        [AllowAnonymous]
        [HttpGet]
        public LocaleEntity[] FindAll()
        {
            return repository.DetachedEntities.ToArray();
        }

        [AllowAnonymous]
        public LocaleResultData FindBySearchCriteria(LocaleSearchCriteria criteria)
        {
            LocaleResultData data = new LocaleResultData();
            LocaleEntity[] list = null;

            int count = 0;

            string sqlWhere = null;

            if (criteria.Filter != null && criteria.Filter.Length > 0)
            {
                sqlWhere = SearchFilter.ComposeWhereClause(criteria.Filter);
            }

            LocaleEntity entity = LocaleEntity.GetInstance();
            string sql = entity.GetSelectTopFrom(criteria.limit, criteria.page, criteria.orderby.StringToDbField(), criteria.orderbytag, sqlWhere);

            string err = null;
            try
            {
                list = repository.FromSql(sql).ToArray();
            }
            catch (System.Exception ex)
            {
                err = ex.Message;
            }


            if (list != null && list.Length > 0)
            {
                sql = entity.GetSelectCountFrom(sqlWhere);
                count = (int)repository.ExecuteScalar(sql);

                data.Datas = list.Select(x => new LocaleDisplayData(x)).ToArray();
            }
            else
            {
                data.Datas = null;
            }

            data.Limit = criteria.limit;
            data.Page = criteria.page;

            data.Total = count;
            //data.Sql = sql;
            data.ErrorMessage = err;
            return data;
        }

        [AllowAnonymous]
        public LocaleEntity FindByKey(LocaleEntityKey key)
        {
            return repository.DetachedEntities.Where(x => 1 == 1
            && x.GroupName == key.GroupName
            && x.Lang == key.Lang
            && x.Name == key.Name
           ).FirstOrDefault()!;
        }

        [PermissionOperate(name: SecurityPermissionPolicy.Locale, operate: Operate.Insert)]
        [UnitOfWork]
        public LocaleEntity Insert(LocaleEntity data)
        {
            throw new NotImplementedException();
        }

        [PermissionOperate(name: SecurityPermissionPolicy.Locale, operate: Operate.Update)]
        [UnitOfWork]
        public LocaleEntity Update(LocaleEntity data)
        {
            throw new NotImplementedException();
        }

        [PermissionOperate(name: SecurityPermissionPolicy.Locale, operate: Operate.Update)]
        [UnitOfWork]
        public void UpdateLocaleData(LocaleData data)
        {
            List<LocaleEntity> list = new List<LocaleEntity>();
            LocaleEntity locale;
            if (data.Deletes != null)
            {
                foreach (var item in data.Deletes)
                {
                    locale = new LocaleEntity() { GroupName = item.OrgGroupName, Name = item.OrgName, Lang = item.OrgLang };
                    list.Add(locale);
                }
                repository.DeleteNow(list);
            }
            if (data.Inserts != null)
            {
                repository.InsertNow(data.Inserts);
            }
            if (data.Updates != null)
            {
                list = new List<LocaleEntity>();
                foreach (var item in data.Updates)
                {
                    locale = new LocaleEntity() { GroupName = item.OrgGroupName, Name = item.OrgName, Lang = item.OrgLang };
                    list.Add(locale);
                }
                repository.DeleteNow(list);

                list = new List<LocaleEntity>();
                foreach (var item in data.Updates)
                {
                    locale = new LocaleEntity();
                    ObjectCopyHelper.Copy(item, locale);
                    list.Add(locale);
                }
                repository.InsertNow(list);
            }
        }


        [PermissionOperate(name: SecurityPermissionPolicy.Locale, operate: Operate.Delete)]
        public void Delete(LocaleEntityKey key)
        {
            LocaleEntity ent = repository.DetachedEntities.Where(x => 1 == 1
              && x.GroupName == key.GroupName
              && x.Lang == key.Lang
              && x.Name == key.Name
             ).FirstOrDefault()!;
            if (ent != null) { repository.DeleteNow(ent); }
        }


    }
}
