using System.ComponentModel.DataAnnotations;
using Asp.Versioning;
using Baya.Application.Features.Identity.Commands.UploadCustomerAvatar;
using Baya.Application.Features.Identity.Commands.UpsertCustomerProfile;
using Baya.Application.Features.Identity.Queries.GetMyCustomerProfile;
using Baya.Application.Models.Common;
using Baya.Application.Models.Identity;
using Baya.WebFramework.Attributes;
using Baya.WebFramework.BaseController;
using Mediator;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Baya.Web.Api.Controllers.V1;

[ApiVersion("1")]
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[Authorize]
[Display(Description = "The signed-in customer's payer profile")]
public sealed class CustomerProfilesController(ISender sender) : BaseController
{
    [HttpPost("[action]")]
    [ProducesOkApiResponseType<CustomerProfileDto>]
    public async Task<IActionResult> Upsert(UpsertCustomerProfileCommand command, CancellationToken cancellationToken)
        => OperationResult(await sender.Send(command, cancellationToken));

    [HttpGet("[action]")]
    [ProducesOkApiResponseType<CustomerProfileDto>]
    public async Task<IActionResult> Me(CancellationToken cancellationToken)
        => OperationResult(await sender.Send(new GetMyCustomerProfileQuery(), cancellationToken));

    // Multipart image upload → stored via IObjectStorage; the returned URL is persisted on the profile.
    [HttpPost("[action]")]
    [ProducesOkApiResponseType<AvatarUploadResult>]
    public async Task<IActionResult> Avatar(IFormFile file, CancellationToken cancellationToken)
    {
        if (file is null || file.Length == 0)
            return OperationResult(Baya.Application.Models.Common.OperationResult<AvatarUploadResult>.FailureResult("No file uploaded."));

        using var buffer = new MemoryStream();
        await file.CopyToAsync(buffer, cancellationToken);
        var command = new UploadCustomerAvatarCommand(buffer.ToArray(), file.ContentType, file.Length);
        return OperationResult(await sender.Send(command, cancellationToken));
    }
}
