using Hotline.Api.Filter;
using Hotline.Application.IndustryClassification;
using Hotline.FlowEngine.Workflows;
using Hotline.IndustryClassification;
using Hotline.Orders;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Settings;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.IndustryClassification;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Requests;
using Hotline.Tools;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using XF.Domain.Authentications;
using XF.Domain.Exceptions;
using XF.Domain.Repository;

namespace Hotline.Api.Controllers
{
    /// <summary>
    /// 行业管理
    /// </summary>
    public class IndustrialManagementController : BaseController
    {
        private readonly IMapper _mapper;
        private readonly ISystemOrganizeRepository _organizeRepository;
        private readonly IIndustryClassificationRepositpry _industrialManagementRepository;
        private readonly IRepository<SystemOrganize> _systemOrganizeRepository;
        private readonly IRepository<Order> _orderRepository;
        private readonly ISessionContext _sessionContext;
        private readonly IRepository<WorkflowStep> _workflowStepRepository;
        private readonly IIndustryClassificationApplication _industryClassificationApplication;

        public IndustrialManagementController(IMapper mapper,
            ISystemOrganizeRepository organizeRepository,
            IIndustryClassificationRepositpry industrialManagementRepository,
            IRepository<SystemOrganize> systemOrganizeRepository,
            IRepository<Order> orderRepository,
            ISessionContext sessionContext,
            IRepository<WorkflowStep> workflowStepRepository,
            IIndustryClassificationApplication industryClassificationApplication)
        {
            _mapper = mapper;
            _organizeRepository = organizeRepository;
            _industrialManagementRepository = industrialManagementRepository;
            _systemOrganizeRepository = systemOrganizeRepository;
            _orderRepository = orderRepository;
            _sessionContext = sessionContext;
            _workflowStepRepository = workflowStepRepository;
            _industryClassificationApplication = industryClassificationApplication;
        }

        /// <summary>
        /// 获取部门
        /// </summary>
        /// <returns></returns>
        [HttpGet("getorglist/{id}")]
        public async Task<List<IndustrialOrgs>> GetOrgList(string id)
        {
            var list = await _systemOrganizeRepository.Queryable()
                     .Select(p => new IndustrialOrgs
                     {
                         OrgId = p.Id,
                         OrgName = p.Name,
                         ParentId = p.ParentId,
                         ParentName = p.ParentId,
                         IsDisable = SqlFunc.Subqueryable<IndustryAssociations>().Where(d => d.OrganizeId == p.Id).WhereIF(!string.IsNullOrEmpty(id), d => d.IndustrialManagementId != id).Any()
                     })
                     .ToTreeAsync(d => d.Children, it => it.ParentId, null);

            return list;
        }

        /// <summary>
        /// 新增行业
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("industryadd")]
        [LogFilter("新增行业")]
        public async Task Add([FromBody] IndustryAddDto dto)
        {
            if (dto == null)
                throw UserFriendlyException.SameMessage("数据错误");
            if (string.IsNullOrEmpty(dto.IndustryName))
                throw UserFriendlyException.SameMessage("行业名称不能为空");
            if (dto.OrgsIds == null || dto.OrgsIds.Count == 0)
                throw UserFriendlyException.SameMessage("关联部门不能为空");

            var isHas = await _industrialManagementRepository.AnyAsync(p => p.IndustrialName == dto.IndustryName, HttpContext.RequestAborted);
            if (isHas)
                throw UserFriendlyException.SameMessage("存在此行业名称");

            var hasDat = await _industrialManagementRepository.Queryable()
                    .Includes(d => d.Orgs)
                    .AnyAsync(d => d.Orgs.Any(p => dto.OrgsIds.Contains(p.Id)));
            if (hasDat)
                throw UserFriendlyException.SameMessage("部门已关联行业！");

            IndustrialManagement industrialManagement = new()
            {
                IndustrialName = dto.IndustryName,
                LastModificationTime = DateTime.Now
            };
            await _industrialManagementRepository.AddAsync(industrialManagement, HttpContext.RequestAborted);
            industrialManagement.Orgs = dto.OrgsIds.Select(d => new SystemOrganize { Id = d }).ToList();
            await _industrialManagementRepository.SetIndustrialManagementAsync(industrialManagement, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 修改行业
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("industryupdate")]
        [LogFilter("修改行业")]
        public async Task Update([FromBody] IndustryUpdateDto dto)
        {
            if (dto == null)
                throw UserFriendlyException.SameMessage("数据错误");
            if (string.IsNullOrEmpty(dto.IndustryName))
                throw UserFriendlyException.SameMessage("行业名称不能为空");
            if (dto.OrgsIds == null || dto.OrgsIds.Count == 0)
                throw UserFriendlyException.SameMessage("关联部门不能为空");

            var isHas = await _industrialManagementRepository.AnyAsync(p => p.IndustrialName == dto.IndustryName && p.Id != dto.Id,
                HttpContext.RequestAborted);
            if (isHas)
                throw UserFriendlyException.SameMessage("存在此行业名称");

            var hasDat = await _industrialManagementRepository.Queryable()
                .Includes(d => d.Orgs)
                .AnyAsync(d => d.Id != dto.Id && d.Orgs.Any(p => dto.OrgsIds.Contains(p.Id)));
            if (hasDat)
                throw UserFriendlyException.SameMessage("部门已关联行业！");

            var data = await _industrialManagementRepository.GetAsync(p => p.Id == dto.Id, HttpContext.RequestAborted);
            if (data == null)
                throw UserFriendlyException.SameMessage("数据查询失败");
            data.IndustrialName = dto.IndustryName;
            await _industrialManagementRepository.UpdateAsync(data, HttpContext.RequestAborted);
            data.Orgs = dto.OrgsIds.Select(d => new SystemOrganize { Id = d }).ToList();
            await _industrialManagementRepository.SetIndustrialManagementAsync(data, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 查询详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<IndustrialManagement> GetDataInfo(string id)
        {
            return await _industrialManagementRepository.Queryable()
                        .Includes(d => d.Orgs)
                        .FirstAsync(d => d.Id == id);
        }

        /// <summary>
        /// 删除行业
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        [LogFilter("删除行业")]
        public async Task Remove(string id)
        {
            await _industrialManagementRepository.DelIndustrialManagementAsync(id, cancellationToken: HttpContext.RequestAborted);
        }

        /// <summary>
        /// 根据行业查询部门
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("getindustryassociationsbyid")]
        public async Task<IndustrialManagement> GetIndustryAssociationsById([FromQuery] string id)
        {
            var data = await _industrialManagementRepository.Queryable()
                .Includes(d => d.Orgs)
                .Where(d => d.Id == id)
                .FirstAsync();

            return data;
        }

        /// <summary>
        /// 查询行业列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("getindustrialmanagementlist")]
        public async Task<PagedDto<IndustrialManagementDto>> GetIndustrialManagementList([FromQuery] PagedKeywordRequest dto)
        {
            var (total, items) = await _industryClassificationApplication.GetIndustrialManagementList(dto)
                .ToPagedListAsync(dto, HttpContext.RequestAborted);
            return new PagedDto<IndustrialManagementDto>(total, items);
        }

        /// <summary>
        /// 查询行业列表--导出
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getindustrialmanagementlist_export")]
		[LogFilterAlpha("导出日志")]
		public async Task<FileStreamResult> GetIndustrialManagementListExport([FromBody] ExportExcelDto<PagedKeywordRequest> dto)
        {
            var query = _industryClassificationApplication.GetIndustrialManagementList(dto.QueryDto);

            List<IndustrialManagementDto> data;
            if (dto.IsExportAll)
            {
                data = await query.ToListAsync(HttpContext.RequestAborted);
            }
            else
            {
                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
                data = items;
            }

            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<IndustrialManagementDto>(dto.ColumnInfos);

            var dtos = data
                .Select(stu => _mapper.Map(stu, typeof(IndustrialManagementDto), dynamicClass))
                .Cast<object>()
                .ToList();

            var stream = ExcelHelper.CreateStream(dtos);
            return ExcelStreamResult(stream, "行业列表数据");
        }

        /// <summary>
        /// 行业诉求工单
        /// </summary>
        [HttpGet("industrial-orders")]
        public async Task<PagedDto<IndustrialManagementOrderDto>> GetIndustrialManagementOrderList([FromQuery] IndustrialManagementRequestDto dto)
        {
            var (total, items) = await _industryClassificationApplication.GetIndustrialManagementOrderList(dto)
                .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
            return new PagedDto<IndustrialManagementOrderDto>(total, items);
        }

        /// <summary>
        /// 行业诉求工单--导出
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("industrial-orders-export")]
		[LogFilterAlpha("导出日志")]
		public async Task<FileStreamResult> GetIndustrialManagementOrderListExport([FromBody] ExportExcelDto<IndustrialManagementRequestDto> dto)
        {
            var query = _industryClassificationApplication.GetIndustrialManagementOrderList(dto.QueryDto);

            List<IndustrialManagementOrderDto> data;
            if (dto.IsExportAll)
            {
                data = await query.ToListAsync(HttpContext.RequestAborted);
            }
            else
            {
                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
                data = items;
            }

            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<IndustrialManagementOrderDto>(dto.ColumnInfos);

            var dtos = data
                .Select(stu => _mapper.Map(stu, typeof(IndustrialManagementOrderDto), dynamicClass))
                .Cast<object>()
                .ToList();

            var stream = ExcelHelper.CreateStream(dtos);
            return ExcelStreamResult(stream, "行业诉求工单数据");
        }

    }
}