using Hotline.Share.Dtos;
using Mapster;
using SqlSugar;
using XF.Domain.Dependency;
using XF.Domain.Exceptions;
using XF.Domain.Repository;

namespace Hotline.Settings
{
    public class SystemAreaDomainService : ISystemAreaDomainService, IScopeDependency
    {
        private readonly IRepository<SystemArea> _systemAreaRepository;

        public SystemAreaDomainService(IRepository<SystemArea> systemAreaRepository)
        {
            _systemAreaRepository = systemAreaRepository;
        }

        public async Task AddArea(SystemArea model, CancellationToken cancellationToken)
        {
            await _systemAreaRepository.AddAsync(model, cancellationToken);
        }

        public async Task ModifyArea(SystemArea model, CancellationToken cancellationToken)
        {
            await _systemAreaRepository.UpdateAsync(model, cancellationToken);
        }

        public async Task<List<SystemArea>> GetAreaTree(int idLength = 0, string parentId = "510000")
        {
            return await _systemAreaRepository.Queryable()
                 .WhereIF(idLength != 0, x => SqlFunc.Length(x.Id) == idLength)
                 .OrderBy(x => x.Id).ToTreeAsync(x => x.Children, q => q.ParentId, parentId);
        }

        public async Task<SystemArea?> GetArea(string id, CancellationToken cancellationToken)
        {
            return await _systemAreaRepository.GetAsync(id, cancellationToken);
        }

        public async Task DelArea(string id, CancellationToken cancellationToken)
        {
            await _systemAreaRepository.RemoveAsync(id, true, cancellationToken);
        }

        /// <summary>
        /// 生成新的区域编码
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="UserFriendlyException"></exception>
        public async Task<string> GenerateNewAreaCodeAsync(string parentId, CancellationToken cancellationToken)
        {
            var parentArea = await _systemAreaRepository.GetAsync(parentId, cancellationToken);
            if (parentArea == null)
                throw new UserFriendlyException("无效数据");

            var maxCode = await _systemAreaRepository.Queryable()
                .Where(d => d.ParentId == parentId)
                .MaxAsync(d => d.Id, cancellationToken);

            if (string.IsNullOrEmpty(maxCode))
                return $"{parentArea.Id}01";

            if (!int.TryParse(maxCode.GetLastAreaCode(), out var max))
                throw new UserFriendlyException("无效区域编码");

            return $"{parentArea.Id}{max + 1}";

        }

        public async Task<List<Kv>> GetAreaKeyValue(int idLength = 0, string parentId = "510000")
        {
            return (await GetAreaTree(idLength, parentId)).Adapt<List<Kv>>();
        }
    }
}
