using BPA.SAAS.Manage.Application.Org.Dtos.Organize;
using BPA.SAAS.Manage.Application.Org.Interface;
using BPA.SAAS.Manage.Comm.Const;
using BPA.SAAS.Manage.Comm.Enum;
using BPA.SAAS.Manage.Comm.Util;
using BPA.SAAS.Manage.Core.Base;
using BPA.SAAS.Manage.Core.Org;
using Furion.DatabaseAccessor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace BPA.SAAS.Manage.Application.Org.Services
{
    public class OrganizeService : IOrganizeService, ITransient
    {
        private readonly ISqlSugarClient _db;
        public OrganizeService(ISqlSugarClient db)
        {
            _db = db;
        }
        /// <summary>
        ///  分页获取组织机构列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageUtil> QueryOrgPageList(OrgPageInput input)
        {
            RefAsync<int> total = 0;
            var name = !string.IsNullOrEmpty(input.Name?.Trim());
            var id = !string.IsNullOrEmpty(input.Id?.Trim());
            var pId = !string.IsNullOrEmpty(input.Pid?.Trim());
            var data = await _db.Queryable<BPA_Organize>()
                                     .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name.Trim()))
                                       .WhereIF(!string.IsNullOrWhiteSpace(input.Pid), u => u.Pids.Contains(input.Pid.Trim()) || u.Id == input.Pid.Trim())
                                      .Select<OrgOutput>()
                                      .OrderBy(a => a.CreateAt, OrderByType.Asc)
                                      .ToPageListAsync(input.Current, input.PageSize, total);
            PageUtil util = new PageUtil()
            {
                Total = total,
                Data = data

            };
            return util;
        }
        /// <summary>
        ///  获取组织机构列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<OrgOutput>> GetOrgList(OrgListInput input)
        {
            var pId = !string.IsNullOrEmpty(input.Pid?.Trim());
            var orgs = await _db.Queryable<BPA_Organize>()
                                       .WhereIF(pId, u => u.PID == input.Pid)
                                       .Where(u => u.Status != CommonStatus.DELETED).ToListAsync();
            return orgs.Adapt<List<OrgOutput>>();
        }
        /// <summary>
        /// 新增组织
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> AddOrg(OrgAddInput input)
        {
            if (!string.IsNullOrEmpty(input.Tel))
            {
                var tel = Regex.IsMatch(input.Tel, "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$");
                if (tel == false) throw Oops.Oh("手机号错误");
            }
            var sysOrg = input.Adapt<BPA_Organize>();
            if (string.IsNullOrWhiteSpace(sysOrg.PID))
            {
                sysOrg.PID = "0";
            }
            await FillPids(sysOrg);
            return await _db.Insertable(sysOrg).CallEntityMethod(m => m.Create()).ExecuteCommandAsync()>0;
        }
        /// <summary>
        /// 删除组织机构
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> DeleteOrg(string id)
        {
            var sysOrg = await _db.Queryable<BPA_Organize>().FirstAsync(u => u.Id == id);
            // 级联删除子节点
            var childIdList = await GetChildIdListWithSelfById(sysOrg.Id);
            var orgs = await _db.Queryable<BPA_Organize>().Where(u => childIdList.Contains(u.Id)).ToListAsync();
           return  await _db.Deleteable(orgs).ExecuteCommandAsync()>0;
        }

        /// <summary>
        /// 更新组织机构
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> UpdateOrg(UpdateOrgInput input)
        {
            if (input.Pid != Guid.Empty.ToString() && !string.IsNullOrEmpty(input.Pid) && input.Pid != "0")
            {
                var org = await _db.Queryable<BPA_Organize>().FirstAsync(u => u.Id == input.Pid);
                _ = org ?? throw Oops.Oh("父机构不存在");
            }

            if (!string.IsNullOrEmpty(input.Tel))
            {
                var tel = Regex.IsMatch(input.Tel, "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$");
                if (tel == false) throw Oops.Oh("手机号错误");
            }

            if (input.Id == input.Pid)
                throw Oops.Oh("当前机构Id不能与父机构Id相同");

            // 如果是编辑，父id不能为自己的子节点
            var childIdListById = await GetChildIdListWithSelfById(input.Id);
            if (childIdListById.Contains(input.Pid))
                throw Oops.Oh("当前机构Id不能与父机构Id相同");

            var sysOrg = await _db.Queryable<BPA_Organize>().FirstAsync(u => u.Id == input.Id);
            sysOrg.Name=input.Name;
            sysOrg.Tel = input.Tel;
            sysOrg.Remark = input.Remark;
            sysOrg.Sort= input.Sort;
            await FillPids(sysOrg);
            return await _db.Updateable(sysOrg).IgnoreColumns(ignoreAllNullColumns: true)
                   .ExecuteCommandAsync()>0;
           
        }
        /// <summary>
        /// 获取组织机构树
        /// </summary>
        /// <returns></returns>
        public async Task<dynamic> GetOrgTree()
        {
            var dataScopeList = new List<string>();
            var groupId = App.User?.FindFirst(ClaimConst.GroupId)?.Value;
            var orgs = await _db.Queryable<BPA_Organize>().WhereIF(dataScopeList.Count > 0, u => dataScopeList.Contains(u.Id))
                                                        .Where(u => u.Status == CommonStatus.ENABLE && u.GroupId== groupId).OrderBy(u => u.Sort)
                                                        .Select(u => new OrgTreeNode
                                                        {
                                                            key = u.Id,
                                                            parentId = u.PID,
                                                            title = u.Name,
                                                            value = u.Id.ToString(),
                                                            weight = u.Sort,
                                                            Type = u.Type,
                                                        }).ToListAsync();

            return new TreeBuildUtil<OrgTreeNode>().Build(orgs);

        }
        /// <summary>
        /// 填充父Ids字段
        /// </summary>
        /// <param name="sysOrg"></param>
        /// <returns></returns>
        private async Task FillPids(BPA_Organize sysOrg)
        {
            if (string.IsNullOrWhiteSpace(sysOrg.PID) || sysOrg.PID == "0")
            {
                sysOrg.Pids = "[0],";
                sysOrg.PID = "0";
            }
            else
            {
                var t = await _db.Queryable<BPA_Organize>().FirstAsync(u => u.Id == sysOrg.PID);
                sysOrg.Pids = t.Pids + "[" + t.Id + "],";
            }
        }
        /// <summary>
        /// 根据节点Id获取所有子节点Id集合，包含自己
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private async Task<List<string>> GetChildIdListWithSelfById(string id)
        {
            var childIdList = await _db.Queryable<BPA_Organize>()
                                              .Where(u => u.Pids.Contains(id.ToString()))
                                              .Select(u => u.Id).ToListAsync();
            childIdList.Add(id);
            return childIdList;
        }
        public async Task<Dictionary<string, object>> GetOrgList()
        {
            var data =await _db.Queryable<BPA_Organize>()
                 .ToDictionaryAsync(x => x.Id, x => x.Name);
            return data;
        }
    }
}
