using Amazon.Runtime.Internal.Transform;
using Hotline.Application.FlowEngine;
using Hotline.Application.Snapshot.Contracts;
using Hotline.Application.Snapshot;
using Hotline.Application.Snapshot.Contracts;
using Hotline.Caching.Interfaces;
using Hotline.Caching.Services;
using Hotline.Configurations;
using Hotline.FlowEngine.Definitions;
using Hotline.FlowEngine.Workflows;
using Hotline.Orders;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Repository.SqlSugar.Snapshot;
using Hotline.Settings;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.Snapshot;
using Hotline.Share.Enums.FlowEngine;
using Hotline.Share.Enums.Order;
using Hotline.Share.Enums.Snapshot;
using Hotline.Share.Tools;
using Hotline.Snapshot;
using Hotline.Snapshot.IRepository;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.ComponentModel;
using System.Text;
using Hotline.Application.OrderApp;
using XF.Domain.Authentications;
using XF.Domain.Exceptions;
using XF.Domain.Repository;
using XF.Utility.EnumExtensions;

namespace Hotline.Api.Controllers.Snapshot;

/// <summary>
/// 随手拍工单
/// </summary>
[Description("随手拍工单")]
public class SnapshotOrderController : BaseController
{
    private readonly IOrderSnapshotRepository _orderSnapshotRepository;
    private readonly IOrderSnapshotApplication _orderSnapshotApplication;
    private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
    private readonly ISystemAreaDomainService _systemAreaDomainService;
    private readonly IIndustryRepository _industryRepository;
    private readonly ISessionContext _sessionContext;
    private readonly IWorkflowDomainService _workflowDomainService;
    private readonly IOrderRepository _orderRepository;
    private readonly IWorkflowApplication _workflowApplication;
    private readonly IRepository<WorkflowDefinition> _workflowDefinitionRepository;
    private readonly IOrderApplication _orderApplication;
    private readonly IOptionsSnapshot<AppConfiguration> _appOptions;

    public SnapshotOrderController(IOrderSnapshotRepository orderSnapshotRepository, IOrderSnapshotApplication orderSnapshotApplication, ISystemAreaDomainService systemAreaDomainService, ISystemDicDataCacheManager systemDicDataCacheManager, IIndustryRepository industryRepository, ISessionContext sessionContext, IWorkflowDomainService workflowDomainService, IOrderRepository orderRepository, IWorkflowApplication workflowApplication, IRepository<WorkflowDefinition> workflowDefinitionRepository, IOrderApplication orderApplication, IOptionsSnapshot<AppConfiguration> appOptions)
    {
        _orderSnapshotRepository = orderSnapshotRepository;
        _orderSnapshotApplication = orderSnapshotApplication;
        _systemAreaDomainService = systemAreaDomainService;
        _systemDicDataCacheManager = systemDicDataCacheManager;
        _industryRepository = industryRepository;
        _sessionContext = sessionContext;
        _workflowDomainService = workflowDomainService;
        _orderRepository = orderRepository;
        _workflowApplication = workflowApplication;
        _workflowDefinitionRepository = workflowDefinitionRepository;
        _orderApplication = orderApplication;
        _appOptions = appOptions;
    }

    /// <summary>
    /// 随手拍所有工单集合
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("order")]
    public async Task<PagedDto<OrderSnapshotItemsOutDto>> GetOrderSnapshotItems([FromQuery] OrderSnapshotItemsInDto dto)
        => (await _orderSnapshotApplication.GetOrderSnapshotItems(dto).ToPagedListAsync(dto)).ToPaged();

    /// <summary>
    /// 设为重点
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPut("isemphasis")]
    public async Task UpdateIsEmphasisAsync([FromBody] UpdateIsEmphasisInDto dto)
        => await _orderSnapshotApplication.UpdateIsEmphasisAsync(dto);

    /// <summary>
    /// 电气焊作业申报工单集合
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("order/electrogas")]
    public async Task<PagedDto<OrderSnapshotElectrogasItemsOutDto>> GetOrderSnapshotElectrogasItems([FromQuery] OrderSnapshotItemsInDto dto)
        => (await _orderSnapshotApplication.GetOrderSnapshotElectrogasItems(dto).ToPagedListAsync(dto)).ToPaged();

    /// <summary>
    /// 随手拍所有工单页面基础信息
    /// </summary>
    [HttpGet("order/basedata")]
    public async Task<Dictionary<string, object>> GetOrderSnapshotItemsDatabaseAsync()
    {
        IList<Kv> steps = new List<Kv>();
        await _workflowDefinitionRepository.Queryable()
            .Where(m => m.Status == EDefinitionStatus.Enable && m.Code == "gdbl")
            .OrderByDescending(m => m.Version)
            .Select(m => new { m.Id, m.Steps })
            .FirstAsync().Then(async workflowSteps =>
            {
                steps = workflowSteps.Steps.Adapt<IList<NameCodeDto>>()
               .ToList().Select(m => new Kv
               {
                   Key = m.Code,
                   Value = m.Name,
               }).ToList();
            });
        return new Dictionary<string, object>
        {
            { "orderStatus", EnumExts.GetDescriptions<EOrderStatus>()},
            { "area", await _systemAreaDomainService.GetAreaKeyValue(parentId: _appOptions.Value.AreaCode)},
            { "steps", steps},
            { "orderTags", _systemDicDataCacheManager.OrderTag},
            { "industry", await _industryRepository.Queryable().Select(d => new { d.Id, d.Name, }).ToListAsync()},
            { "acceptType", _systemDicDataCacheManager.AcceptType.Adapt<List<Kv>>() }
        };
    }

    /// <summary>
    /// 获取网格员回复集合
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("guider/reply")]
    public async Task<PagedDto<GuiderReplyItemsOutDto>> GetGuiderReplyItems([FromQuery] GuiderReplyItemsInDto dto)
        => (await _orderSnapshotApplication.GetGuiderReplyItems(dto).ToPagedListAsync(dto)).ToPaged();

    /// <summary>
    /// 获取工单标注集合
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("label")]
    public async Task<PagedDto<SignOrderSnapshotItemsOutDto>> GetSignOrderSnapshotItems([FromQuery] SignOrderSnapshotItemsInDto dto)
        => (await _orderSnapshotApplication.GetSignOrderSnapshotItems(dto).ToPagedListAsync(dto)).ToPaged();

    /// <summary>
    /// 获取工单已经标签集合
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("labeled")]
    public async Task<PagedDto<LabeledOrderSnapshotItemsOutDto>> GetLabeledOrderSnapshotItems([FromQuery] LabeledOrderSnapshotItemsInDto dto)
        => (await _orderSnapshotApplication.GetLabeledOrderSnapshotItems(dto).ToPagedListAsync(dto)).ToPaged();

    /// <summary>
    /// 标签详情
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet("label/{id}")]
    public async Task<LabelOrderSnapshotDetailOutDto> GetLabelOrderSnapshotDetailAsync(string id)
    {
        var order = await _orderRepository.Queryable()
            .LeftJoin<OrderSnapshot>((order, snapshot) => order.Id == snapshot.Id)
            .Where((order, snapshot) => order.Id == id)
            .Select((order, snapshot) => new LabelOrderSnapshotDetailOutDto { Id = order.Id, Title = order.Title, Lables = snapshot.Labels })
            .FirstAsync();
        var snapshot = await _orderSnapshotRepository.GetAsync(id, HttpContext.RequestAborted);
        order.Lables = snapshot.Labels;
        order.LabelsBaseData = _systemDicDataCacheManager.SnapshotOrderLabel;
        return order;
    }

    /// <summary>
    /// 修改工单标签
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPut("label")]
    public async Task UpdateLabelOrderSnapshotAsync([FromBody] UpdateLabelOrderSnapshotInDto dto)
        => await _orderSnapshotApplication.UpdateLabelAsync(dto.Id, dto.SnapshotLabels);

    /// <summary>
    /// 获取工单标签日志集合
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("label/log")]
    public async Task<PagedDto<LabelOrderSnapshotLogItemsOutDto>> GetLabelOrderSnapshotLogItems([FromQuery] LabelOrderSnapshotLogItemsInDto dto)
        => (await _orderSnapshotApplication.GetLabelOrderSnapshotLogItems(dto).ToPagedListAsync(dto)).ToPaged();

    /// <summary>
    /// 随手拍公开集合
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("publish")]
    public async Task<PagedDto<GetOrderSnapshotPublishItemsOutDto>> GetOrderSnapshotPublishItems([FromQuery] GetOrderSnapshotPublishItemsInDto dto)
        => (await _orderSnapshotApplication.GetOrderSnapshotPublishItems(dto).ToPagedListAsync(dto)).ToPaged();

    /// <summary>
    /// 随手拍公开详情
    /// </summary>
    /// <param name="id">工单Id</param>
    /// <returns></returns>
    [HttpGet("publish/{id}")]
    public async Task<GetOrderSnapshotPublishDetailOutDto> GetOrderSnapshotPublishDetailAsync(string id)
        => await _orderSnapshotApplication.GetOrderSnapshotPublishDetailAsync(id);

    /// <summary>
    /// 添加公开审核
    /// </summary>
    /// <returns></returns>
    [HttpPost("publish")]
    public async Task AddOrderSnapshotPublishItemsAsync([FromBody] AddSnapshotOrderPublishInDto dto)
         => await _orderSnapshotApplication.AddOrderPublishAsync(dto, HttpContext.RequestAborted);

    /// <summary>
    /// 随手拍公开审批集合
    /// </summary>
    /// <returns></returns>
    [HttpGet("publish/audit")]
    public async Task<PagedDto<GetOrderSnapshotPublishAuditItemsOutDto>> GetOrderSnapshotPublishAuditItems([FromQuery] GetOrderSnapshotPublishAuditItemsInDto dto)
        => (await _orderSnapshotApplication.GetOrderSnapshotPublishAuditItems(dto).ToPagedListAsync(dto)).ToPaged();

    /// <summary>
    /// 审核随手拍公开申请通过/不通过
    /// </summary>
    /// <returns></returns>
    [HttpPut("publish/status")]
    public async Task UpdateOrderSnapshotPublishStatusAsync([FromBody] UpdateOrderSnapshotPublishStatusInDto dto)
        => await _orderSnapshotApplication.UpdateOrderSnapshotPublishStatusAsync(dto);

    /// <summary>
    /// 随手拍公开审批详情
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet("publish/audit/{id}")]
    public async Task<GetOrderSnapshotPublishAuditDetailOutDto> GetOrderSnapshotPublishAuditDetailAsync(string id)
        => await _orderSnapshotApplication.GetOrderSnapshotPublishAuditDetailAsync(id);

    /// <summary>
    /// 批量设置随手拍公开申请不通过
    /// </summary>
    /// <returns></returns>
    [HttpPut("publishs/status/refuse")]
    public async Task UpdateOrderSnapshotPublishsStatusRefuseAsync(IList<string> ids)
        => await _orderSnapshotApplication.UpdateOrderSnapshotPublishsStatusRefuseAsync(ids);

    /// <summary>
    /// 随手拍公开集合基础数据
    /// </summary>
    /// <returns></returns>
    [HttpGet("publish/basedata")]
    public async Task<Dictionary<string, object>> GetOrderSnapshotPublishItemsBasedataAsync()
    {
        var industry = await _industryRepository.Queryable()
       .Select(d => new { d.Id, d.Name, })
       .ToListAsync();

        return new Dictionary<string, object>
        {
            { "publishStatus", EnumExts.GetDescriptions<EOrderSnapshotPublishStatus>()},
            { "acceptCode", _systemDicDataCacheManager.AcceptType.Adapt<List<Kv>>() },
            { "orderStatus", EnumExts.GetDescriptions<EOrderStatus>()},
            { "area", await _systemAreaDomainService.GetAreaKeyValue(parentId: _appOptions.Value.AreaCode)},
            { "industry", industry}
        };
    }

    /// <summary>
    /// 网格员超时未回复, 处理工单
    /// </summary>
    /// <param name="id">工单Id</param>
    /// <returns></returns>
    [HttpPut("guider/timeout/{id}")]
    public async Task HandleFromWanggeyuanToMaskAsync(string id)
    {
        await _orderApplication.HandleFromWanggeyuanToMaskAsync(id, string.Empty, HttpContext.RequestAborted);
    }

    /// <summary>
    /// 市民追加奖励集合
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("citizen/reward")]
    public async Task<PagedDto<CitizenRewardOutDto>> GetCitizenRewardItemsAsync([FromQuery] CitizenRewardInDto dto)
        => (await _orderSnapshotApplication.GetCitizenRewardItems(dto).ToPagedListAsync(dto)).ToPaged();
}
