// EN: Query to get registered POS devices for current merchant.
// VI: Query để lấy danh sách thiết bị POS đã đăng ký của merchant hiện tại.

using MediatR;
using MerchantService.Domain.AggregatesModel.MerchantAggregate;
using MerchantService.Domain.AggregatesModel.MerchantStaffAggregate;
using MerchantService.Domain.Exceptions;

namespace MerchantService.API.Application.Queries.Devices;

/// <summary>
/// EN: Query to get registered devices for current merchant.
/// VI: Query để lấy thiết bị đã đăng ký của merchant hiện tại.
/// </summary>
public record GetDevicesQuery(Guid UserId) : IRequest<IReadOnlyList<DeviceDto>>;

/// <summary>
/// EN: Device DTO.
/// VI: DTO thiết bị.
/// </summary>
public record DeviceDto
{
    public Guid Id { get; init; }
    public Guid StaffId { get; init; }
    public string? StaffCode { get; init; }
    public string DeviceToken { get; init; } = null!;
    public string? DeviceName { get; init; }
    public string Platform { get; init; } = null!;
    public bool IsActive { get; init; }
    public DateTime? LastUsedAt { get; init; }
    public DateTime CreatedAt { get; init; }
}

/// <summary>
/// EN: Handler for getting registered devices.
/// VI: Handler để lấy danh sách thiết bị đã đăng ký.
/// </summary>
public class GetDevicesQueryHandler : IRequestHandler<GetDevicesQuery, IReadOnlyList<DeviceDto>>
{
    private readonly IMerchantRepository _merchantRepository;
    private readonly IMerchantStaffRepository _staffRepository;

    public GetDevicesQueryHandler(
        IMerchantRepository merchantRepository,
        IMerchantStaffRepository staffRepository)
    {
        _merchantRepository = merchantRepository;
        _staffRepository = staffRepository;
    }

    public async Task<IReadOnlyList<DeviceDto>> Handle(GetDevicesQuery request, CancellationToken cancellationToken)
    {
        // EN: Use user ID passed from the controller
        // VI: Dùng user ID được truyền từ controller
        var merchant = await _merchantRepository.GetByUserIdAsync(request.UserId, cancellationToken);
        if (merchant == null)
        {
            return [];
        }

        // EN: Get all staff for this merchant, then collect their devices.
        // VI: Lấy tất cả nhân viên của merchant, sau đó thu thập thiết bị.
        var staffList = await _staffRepository.GetByMerchantIdAsync(merchant.Id, cancellationToken);

        var devices = new List<DeviceDto>();
        foreach (var staff in staffList)
        {
            foreach (var device in staff.DeviceTokens)
            {
                devices.Add(new DeviceDto
                {
                    Id = device.Id,
                    StaffId = staff.Id,
                    StaffCode = staff.EmployeeCode,
                    DeviceToken = device.DeviceId,
                    DeviceName = device.DeviceName,
                    Platform = device.Platform,
                    IsActive = device.LastUsedAt.HasValue && device.LastUsedAt.Value > DateTime.UtcNow.AddDays(-30),
                    LastUsedAt = device.LastUsedAt,
                    CreatedAt = device.CreatedAt
                });
            }
        }

        return devices.OrderByDescending(d => d.CreatedAt).ToList();
    }
}
