using Hotline.Api.Filter;
using Hotline.Caching.Interfaces;
using Hotline.Application.ExportExcel;
using Hotline.Application.Users;
using Hotline.Configurations;
using Hotline.Permissions;
using Hotline.Settings;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Dtos.Org;
using Hotline.Share.Enums.Order;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Threading.Channels;
using XF.Domain.Authentications;
using XF.Domain.Exceptions;
using XF.Utility.EnumExtensions;

namespace Hotline.Api.Controllers
{
    /// <summary>
    /// 组织架构相关接口
    /// </summary>
    public class OrgController : BaseController
    {
        private readonly ISystemOrganizeRepository _systemOrganizeRepository;
        private readonly ISystemDomainService _systemDomainService;
        private readonly ISystemAreaDomainService _areaDomainService;
        private readonly IMapper _mapper;
        private readonly ISessionContext _sessionContext;
		private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
        private readonly IOrgApplication _orgApplication;
        private readonly IExportApplication _exportApplication;

        public OrgController(
            ISystemOrganizeRepository systemOrganizeRepository,
            ISystemDomainService systemDomainService,
            ISystemAreaDomainService areaDomainService,
            IMapper mapper,
            ISessionContext sessionContext,
            IOptionsSnapshot<AppConfiguration> appOptions,
            IOrgApplication orgApplication,
            IExportApplication exportApplication)
        {
            _systemOrganizeRepository = systemOrganizeRepository;
            _systemDomainService = systemDomainService;
            _areaDomainService = areaDomainService;
            _mapper = mapper;
            _sessionContext = sessionContext;
            _appOptions = appOptions;
            _orgApplication = orgApplication;
            _exportApplication = exportApplication;
        }

        /// <summary>
        /// 组织机构获取树形列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("getorgjson")]
        [AllowAnonymous]
        public async Task<IReadOnlyList<SystemOrganize>> GetOrgJson()
        {
            return await _systemOrganizeRepository.GetOrgJson();
        }

        [HttpGet("getorgjsonforuser")]
        [AllowAnonymous]
        public async Task<IReadOnlyList<SystemOrganize>> GetOrgJsonItems()
        {
            return await _orgApplication.GetOrgJsonItems();
        }

        [HttpPost("getorgjsonforuser/export")]
		[LogFilterAlpha("导出日志")]
		[AllowAnonymous]
        public async Task<FileStreamResult> GetOrgJsonItemsExport([FromBody] ExportExcelDto<string> dto)
        {
            var items = await _systemOrganizeRepository.GetOrgAll(_sessionContext.OrgIsCenter,_sessionContext.RequiredOrgId);
            return _exportApplication.GetExcelFile(dto, items.ToList(), "组织架构");
        }


        ///// <summary>
        ///// 新增组织架构
        ///// </summary>
        ///// <param name="dto"></param>
        ///// <returns></returns>
        //[HttpPost("add-org")]
        //[Obsolete]
        //public async Task AddOrg([FromBody] AddOrgDto dto)
        //{
        //    var org = _mapper.Map<SystemOrganize>(dto);
        //    //验证名称是否重复
        //    if (await _systemDomainService.IsNameRepeat(dto.Name, HttpContext.RequestAborted) > 0)
        //        throw UserFriendlyException.SameMessage("组织名称重复");
        //    if (await _systemDomainService.IsShrotNameRepeat(dto.ShortName, HttpContext.RequestAborted) > 0)
        //        throw UserFriendlyException.SameMessage("组织简称重复");

        //    //处理编码
        //    org.Id = await _systemDomainService.GenerateNewOrgCodeAsync(dto.ParentId, HttpContext.RequestAborted);

        //    org.InitOrgLevel();
        //    await _systemOrganizeRepository.AddAsync(org, HttpContext.RequestAborted);
        //}

        /// <summary>
        /// 新增组织架构
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task Add([FromBody] AddOrgDto dto)
        {
            var exists = await _systemOrganizeRepository.AnyAsync(
                d => d.Name == dto.Name || d.ShortName == dto.ShortName, HttpContext.RequestAborted);
            if (exists)
                throw UserFriendlyException.SameMessage("名称或简称已存在");

            await _systemDomainService.AddOrgAsync(dto, HttpContext.RequestAborted);
        }

        ///// <summary>
        ///// 修改组织架构
        ///// </summary>
        ///// <param name="dto"></param>
        ///// <returns></returns>
        //[HttpPost("update-org")]
        //[Obsolete]
        //public async Task UpdateOrg([FromBody] UpdateOrgDto dto)
        //{
        //    var org = await _systemOrganizeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
        //    if (org is null)
        //        throw UserFriendlyException.SameMessage("无效组织架构");
        //    if (org.Id == dto.ParentId)
        //        throw UserFriendlyException.SameMessage("父级不能为自己");
        //    //验证名称是否重复
        //    if (await _systemDomainService.IsNameRepeat(dto.Name, HttpContext.RequestAborted) > 1)
        //        throw UserFriendlyException.SameMessage("组织名称重复");
        //    if (await _systemDomainService.IsShrotNameRepeat(dto.ShortName, HttpContext.RequestAborted) > 1)
        //        throw UserFriendlyException.SameMessage("组织简称重复");

        //    _mapper.Map(dto, org);
        //    await _systemOrganizeRepository.UpdateAsync(org, HttpContext.RequestAborted);
        //}

        /// <summary>
        /// 修改组织架构(不支持修改上级)
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task Update([FromBody] UpdateOrgDto dto)
        {
            var org = await _systemOrganizeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
            if (org is null)
                throw UserFriendlyException.SameMessage("无效组织架构");
            if (org.Id == dto.ParentId)
                throw UserFriendlyException.SameMessage("父级不能为自己");

            var exists = await _systemOrganizeRepository.AnyAsync(
                d => d.Id != dto.Id &&
                     (d.Name == dto.Name || d.ShortName == dto.ShortName), HttpContext.RequestAborted);
            if (exists)
                throw UserFriendlyException.SameMessage("名称或简称已存在");

            _mapper.Map(dto, org);
            await _systemOrganizeRepository.UpdateAsync(org, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 删除组织数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("delete-org/{id}")]
        [LogFilter("删除组织")]
        public async Task DeleteOrg(string id)
        {
            var org = await _systemOrganizeRepository.GetAsync(id, HttpContext.RequestAborted);
            if (org is null)
                throw UserFriendlyException.SameMessage("无效组织架构");
           var chail= await _systemOrganizeRepository.AnyAsync(p => p.ParentId == org.Id);
            if(chail==true)
                throw UserFriendlyException.SameMessage("存在下级部门，请先删除下级部门数据！");

            await _systemOrganizeRepository.RemoveAsync(org, true, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 获取组织
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("getorg/{id}")]
        public async Task<SystemOrganize> GetOrg(string id)
        {
            var org = await _systemOrganizeRepository.GetAsync(id, HttpContext.RequestAborted);
            if (org is null)
                throw UserFriendlyException.SameMessage("无效组织架构");
            return org;
        }

		/// <summary>
		/// 获取一级部门
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		[HttpGet("get_one_org")]
		public async Task<List<SystemOrganize>> GetOneOrg()
		{
			var oneOrgs = await _systemOrganizeRepository.Queryable().Where(x=>x.Level == 1).ToListAsync();
			return oneOrgs;
		}

		/// <summary>
		/// 获取可用组织架构树形
		/// </summary>
		/// <returns></returns>
		[HttpGet("getcanuseorg")]
        public async Task<IReadOnlyList<SystemOrganize>> GetCanUseOrg()
        {
            return await _systemOrganizeRepository.GetCanUseOrg();
        }


        /// <summary>
        /// 获取可用组织架构树形（用户管理）
        /// </summary>
        /// <returns></returns>
        [HttpGet("getcanuseorgforuser")]
        public async Task<IReadOnlyList<SystemOrganize>> GetCanUseOrgForUser()
        {
            if (_sessionContext.OrgIsCenter)
            {
                return await _systemOrganizeRepository.GetCanUseOrg();
            }
            else
            {
                return await _systemOrganizeRepository.GetCanUseOrgByOrgCode(_sessionContext.RequiredOrgId);
            }
        }

        [HttpGet("cascade")]
        public async Task<IReadOnlyList<SystemOrganize>> GetOrgsCascade([FromQuery]string? id)
        {
            return await _systemOrganizeRepository.Queryable()
                .OrderBy(d => d.Id)
                .ToTreeAsync(it => it.Children, it => it.ParentId, id);
        }


        /// <summary>
        /// 新增页面基础数据
        /// </summary>
        /// <returns></returns>
        [HttpGet("base-data-add")]
        [Obsolete]
        public async Task<object> BaseDataAdd()
        {
            var rep = new
            {
                OrgType = EnumExts.GetDescriptions<EOrgType>()
            };
            return rep;
        }

        /// <summary>
        /// 部门页面基础数据
        /// </summary>
        /// <returns></returns>
        [HttpGet("base-data")]
        public async Task<dynamic> BaseData() =>
            new
            {
                OrgTypeOptions = EnumExts.GetDescriptions<EOrgType>(),
                Areas = await _areaDomainService.GetAreaTree(_appOptions.Value.IsZiGong ? 6 : 0)
            };
    }
}