using MediatR;
using IamService.Domain.AggregatesModel.OrganizationAggregate;
using IamService.Domain.Exceptions;

namespace IamService.API.Application.Commands.Organizations;

/// <summary>
/// EN: Handler for ArchiveOrganizationCommand.
/// VI: Handler cho ArchiveOrganizationCommand.
/// </summary>
public class ArchiveOrganizationCommandHandler : IRequestHandler<ArchiveOrganizationCommand, bool>
{
    private readonly IOrganizationRepository _organizationRepository;
    private readonly ILogger<ArchiveOrganizationCommandHandler> _logger;

    public ArchiveOrganizationCommandHandler(
        IOrganizationRepository organizationRepository,
        ILogger<ArchiveOrganizationCommandHandler> logger)
    {
        _organizationRepository = organizationRepository;
        _logger = logger;
    }

    public async Task<bool> Handle(ArchiveOrganizationCommand request, CancellationToken cancellationToken)
    {
        _logger.LogInformation("Archiving organization: {Id}", request.Id);

        var organization = await _organizationRepository.GetByIdAsync(request.Id, cancellationToken);

        if (organization == null)
        {
            throw new DomainException($"Organization with ID '{request.Id}' not found.");
        }

        // EN: Check if organization has children
        // VI: Kiểm tra tổ chức có con không
        var children = await _organizationRepository.GetChildrenAsync(request.Id, cancellationToken);
        if (children.Any())
        {
            throw new DomainException("Cannot archive organization with child organizations. Archive children first.");
        }

        organization.Archive();

        _organizationRepository.Update(organization);

        await _organizationRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation("Organization {Id} archived successfully", request.Id);

        return true;
    }
}
