using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using ZhonTai.Admin.Core.Dto;
using ZhonTai.Admin.Services;
using NPP.SmartSchedue.Api.Contracts.Services.Work;
using NPP.SmartSchedue.Api.Contracts.Services.Work.Input;
using NPP.SmartSchedue.Api.Contracts.Services.Work.Output;
using NPP.SmartSchedue.Api.Repositories.Work;
using NPP.SmartSchedue.Api.Contracts.Domain.Work;
using ZhonTai.DynamicApi;
using ZhonTai.DynamicApi.Attributes;

namespace NPP.SmartSchedue.Api.Services.Work;

/// <summary>
/// 工序组服务
/// </summary>
[DynamicApi(Area = "app")]
public class ProcessGroupService : BaseService, IProcessGroupService, IDynamicApi
{
    private readonly ProcessGroupRepository _processGroupRepository;
    private readonly ProcessGroupRelationRepository _processGroupRelationRepository;
    private readonly ProcessRepository _processRepository;

    public ProcessGroupService(
        ProcessGroupRepository processGroupRepository,
        ProcessGroupRelationRepository processGroupRelationRepository,
        ProcessRepository processRepository)
    {
        _processGroupRepository = processGroupRepository;
        _processGroupRelationRepository = processGroupRelationRepository;
        _processRepository = processRepository;
    }

    /// <summary>
    /// 查询
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<ProcessGroupGetOutput> GetAsync(long id)
    {
        var output = await _processGroupRepository.Select
            .WhereDynamic(id)
            .ToOneAsync<ProcessGroupGetOutput>();

        return output;
    }

    /// <summary>
    /// 查询分页
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<PageOutput<ProcessGroupGetPageOutput>> GetPageAsync(PageInput<ProcessGroupGetPageInput> input)
    {
        var list = await _processGroupRepository.Select
            .WhereIf(!string.IsNullOrEmpty(input.Filter?.GroupName), a => a.GroupName.Contains(input.Filter.GroupName))
            .WhereIf(!string.IsNullOrEmpty(input.Filter?.ProjectCategory), a => a.ProjectCategory.Contains(input.Filter.ProjectCategory))
            .WhereIf(input.Filter?.IsEnabled.HasValue == true, a => a.IsEnabled == input.Filter.IsEnabled.Value)
            .Count(out var total)
            .OrderByDescending(a => a.Id)
            .Page(input.CurrentPage, input.PageSize)
            .ToListAsync<ProcessGroupGetPageOutput>();

        var data = new PageOutput<ProcessGroupGetPageOutput>()
        {
            List = list,
            Total = total
        };

        foreach (var item  in data.List)
        {
            item.ProcessCount = await _processGroupRelationRepository.Select.Where(a => a.ProcessGroupId == item.Id)
                .CountAsync();
        }

        return data;
    }

    /// <summary>
    /// 获取所有工序组列表
    /// </summary>
    /// <returns>工序组列表</returns>
    public async Task<List<ProcessGroupGetPageOutput>> GetAllAsync()
    {
        var list = await _processGroupRepository.Select
            .Where(a => a.IsEnabled == true)
            .OrderBy(a => a.GroupName)
            .ToListAsync<ProcessGroupGetPageOutput>();

        // 为每个工序组添加工序数量
        foreach (var item in list)
        {
            item.ProcessCount = await _processGroupRelationRepository.Select
                .Where(a => a.ProcessGroupId == item.Id && a.IsEnabled)
                .CountAsync();
        }

        return list;
    }

    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<long> AddAsync(ProcessGroupAddInput input)
    {
        var entity = Mapper.Map<ProcessGroupEntity>(input);
        var result = await _processGroupRepository.InsertAsync(entity);
        return result.Id;
    }

    /// <summary>
    /// 修改
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task UpdateAsync(ProcessGroupUpdateInput input)
    {
        var entity = await _processGroupRepository.GetAsync(input.Id);
        Mapper.Map(input, entity);
        await _processGroupRepository.UpdateAsync(entity);
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task DeleteAsync(long id)
    {
        await _processGroupRepository.DeleteAsync(id);
    }

    /// <summary>
    /// 软删除
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task SoftDeleteAsync(long id)
    {
        await _processGroupRepository.SoftDeleteAsync(id);
    }

    /// <summary>
    /// 批量软删除
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    public async Task BatchSoftDeleteAsync(long[] ids)
    {
        await _processGroupRepository.SoftDeleteAsync(ids);
    }

    /// <summary>
    /// 获取工序组的所有工序
    /// </summary>
    /// <param name="groupId">工序组ID</param>
    /// <returns>工序列表</returns>
    public async Task<List<ProcessInfo>> GetGroupProcessesAsync(long groupId)
    {
        var relations = await _processGroupRelationRepository.Select
            .Where(a => a.ProcessGroupId == groupId && a.IsEnabled)
            .OrderBy(a => a.RelationOrder)
            .ToListAsync();

        var processIds = relations.Select(r => r.ProcessId).ToArray();
        var processes = await _processRepository.Select
            .Where(a => processIds.Contains(a.Id))
            .ToListAsync();

        var result = new List<ProcessInfo>();
        foreach (var relation in relations)
        {
            var process = processes.FirstOrDefault(p => p.Id == relation.ProcessId);
            if (process != null)
            {
                result.Add(new ProcessInfo
                {
                    ProcessGroupId = relation.ProcessGroupId,
                    ProcessId = relation.ProcessId,
                    ProcessCode = process.ProcessCode,
                    ProcessName = process.ProcessName,
                    ProcessCategory = process.ProcessCategory,
                    EquipmentType = process.EquipmentType,
                    TheoreticalDuration = process.TheoreticalDuration,
                    RelationOrder = relation.RelationOrder,
                    RelationType = relation.RelationType,
                    PredecessorProcessId = relation.PredecessorProcessId,
                    SuccessorProcessId = relation.SuccessorProcessId,
                });
            }
        }

        return result;
    }

    /// <summary>
    /// 为工序组添加工序
    /// </summary>
    /// <param name="input">添加工序参数</param>
    /// <returns>添加结果</returns>
    public async Task<bool> AddProcessToGroupAsync(ProcessGroupRelationInput input)
    {
        try
        {
            var relation = Mapper.Map<ProcessGroupRelationEntity>(input);
            await _processGroupRelationRepository.InsertAsync(relation);
            return true;
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    /// 从工序组移除工序
    /// </summary>
    /// <param name="groupId">工序组ID</param>
    /// <param name="processId">工序ID</param>
    /// <returns>移除结果</returns>
    public async Task<bool> RemoveProcessFromGroupAsync(long groupId, long processId)
    {
        try
        {
            await _processGroupRelationRepository.DeleteAsync(a => a.ProcessGroupId == groupId && a.ProcessId == processId);
            return true;
        }
        catch
        {
            return false;
        }
    }
} 