using Femto.Api.Controllers.Posts.Dto;
using Femto.Common;
using Femto.Modules.Blog.Application;
using Femto.Modules.Blog.Application.Commands.CreatePost;
using Femto.Modules.Blog.Application.Queries.GetPosts;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Femto.Api.Controllers.Posts;

[ApiController]
[Route("posts")]
public class PostsController(IBlogModule blogModule, ICurrentUserContext currentUserContext) : ControllerBase
{
    [HttpGet]
    public async Task<ActionResult<GetAllPublicPostsResponse>> LoadPosts(
        [FromQuery] GetPublicPostsSearchParams searchParams,
        CancellationToken cancellationToken
    )
    {
        var res = await blogModule.PostQuery(
            new GetPostsQuery(currentUserContext.CurrentUser?.Id)
            {
                From = searchParams.From,
                Amount = searchParams.Amount ?? 20,
                AuthorId = searchParams.AuthorId,
                Author = searchParams.Author,
            },
            cancellationToken
        );

        return new GetAllPublicPostsResponse(
            res.Posts.Select(p => new PostDto(
                new PostAuthorDto(p.Author.AuthorId, p.Author.Username),
                p.PostId,
                p.Text,
                p.Media.Select(m => new PostMediaDto(m.Url, m.Width, m.Height)),
                p.CreatedAt
            )),
            res.Next
        );
    }

    [HttpPost]
    [Authorize]
    public async Task<ActionResult<CreatePostResponse>> CreatePost(
        [FromBody] CreatePostRequest req,
        CancellationToken cancellationToken
    )
    {
        var guid = await blogModule.PostCommand(
            new CreatePostCommand(
                req.AuthorId,
                req.Content,
                req.Media.Select(
                    (media, idx) =>
                        new CreatePostMedia(
                            media.MediaId,
                            media.Url,
                            media.Type,
                            idx,
                            media.Width,
                            media.Height
                        )
                ),
                req.IsPublic
            ),
            cancellationToken
        );

        return new CreatePostResponse(guid);
    }
}
