// EN: POS queries for staff information.
// VI: Queries POS cho thông tin nhân viên.

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

namespace MerchantService.API.Application.Queries.Pos;

#region Get POS Staff Query

/// <summary>
/// EN: Query to get current staff info for POS.
/// VI: Query để lấy thông tin nhân viên hiện tại cho POS.
/// </summary>
public record GetPosStaffQuery(Guid UserId) : IRequest<PosStaffDto?>;

/// <summary>
/// EN: Handler for GetPosStaffQuery.
/// VI: Handler cho GetPosStaffQuery.
/// </summary>
public class GetPosStaffQueryHandler : IRequestHandler<GetPosStaffQuery, PosStaffDto?>
{
    private readonly IMerchantStaffRepository _staffRepository;

    public GetPosStaffQueryHandler(
        IMerchantStaffRepository staffRepository)
    {
        _staffRepository = staffRepository;
    }

    public async Task<PosStaffDto?> Handle(GetPosStaffQuery request, CancellationToken cancellationToken)
    {
        // EN: Use user ID passed from the controller
        // VI: Dùng user ID được truyền từ controller
        var staff = await _staffRepository.GetByUserIdAsync(request.UserId, cancellationToken);
        if (staff == null) return null;

        return new PosStaffDto
        {
            StaffId = staff.Id,
            MerchantId = staff.MerchantId,
            Email = staff.Email ?? string.Empty,
            EmployeeCode = staff.EmployeeCode,
            Phone = staff.Phone,
            Role = staff.Role.Name,
            Status = staff.Status.Name,
            Permissions = (int)staff.Permissions,
            HasPinCode = !string.IsNullOrEmpty(staff.PinCodeHash),
            ShopAssignments = staff.ShopAssignments.Select(sm => new PosShopAssignmentDto
            {
                ShopId = sm.ShopId,
                ShopRole = sm.Role.Name,
                BranchId = sm.BranchId
            }).ToList(),
            RegisteredDevices = staff.DeviceTokens.Select(d => new PosDeviceDto
            {
                DeviceId = d.DeviceId,
                DeviceName = d.DeviceName ?? string.Empty,
                Platform = d.Platform,
                LastUsedAt = d.LastUsedAt
            }).ToList()
        };
    }
}

#endregion

#region POS DTOs

/// <summary>
/// EN: POS staff DTO.
/// VI: DTO nhân viên POS.
/// </summary>
public record PosStaffDto
{
    public Guid StaffId { get; init; }
    public Guid MerchantId { get; init; }
    public string Email { get; init; } = null!;
    public string? EmployeeCode { get; init; }
    public string? Phone { get; init; }
    public string Role { get; init; } = null!;
    public string Status { get; init; } = null!;
    public int Permissions { get; init; }
    public bool HasPinCode { get; init; }
    public List<PosShopAssignmentDto> ShopAssignments { get; init; } = [];
    public List<PosDeviceDto> RegisteredDevices { get; init; } = [];
}

public record PosShopAssignmentDto
{
    public Guid ShopId { get; init; }
    public string ShopRole { get; init; } = null!;
    public Guid? BranchId { get; init; }
}

public record PosDeviceDto
{
    public string DeviceId { get; init; } = null!;
    public string DeviceName { get; init; } = null!;
    public string Platform { get; init; } = null!;
    public DateTime? LastUsedAt { get; init; }
}

#endregion
