using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using WebApp.Data;
using WebApp.Entities;
using System.Linq;

namespace WebApp.Endpoints
{
    public static class MessagesEndpoints
    {
        public static RouteGroupBuilder MapMessagesEndpoints(this WebApplication app)
        {
            Console.WriteLine("Registering MessagesEndpoints...");

            var group = app.MapGroup("api/messages");

            // Test endpoint to verify registration
            group.MapGet("/test", () => Results.Ok("Messages endpoint is working"));

            // POST /api/messages/sendFromOrgToVolunteers
            group.MapPost("/sendFromOrgToVolunteers",
                async (SendMessageRequest request, ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) =>
                {
                    Console.WriteLine("Hit sendFromOrgToVolunteers endpoint.");

                    // Get token and organization
                    var token = await guhf.GetTokenFromHTTPContext(httpContext);
                    var org = await guhf.GetOrganisationFromToken(token);
                    if (org == null)
                        return Results.Unauthorized();

                    // Verify event belongs to org
                    var ev = await dbContext.Events.FindAsync(request.EventId);
                    if (ev == null || ev.OrganisationId != org.OrganisationId)
                        return Results.BadRequest("Event not found or unauthorized.");

                    // Get all volunteers (non-org users)
                    var volunteers = await dbContext.WebUsers
                        .Where(u => !u.IsOrganisation)
                        .ToListAsync();

                    // Create message entities
                    var messages = volunteers.Select(v => new Message
                    {
                        EventType = request.EventId,
                        VolunteerId = v.UserId,
                        OrganizationId = org.OrganisationId,
                        IsMsgFromVolunteer = false,
                        IsoDate = DateTime.UtcNow,
                        Content = request.Content
                    }).ToList();

                    dbContext.Messages.AddRange(messages);
                    await dbContext.SaveChangesAsync();

                    return Results.Ok();
                });

            // GET /api/messages/my - get messages for current user
            group.MapGet("/my",
                async (ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) =>
                {
                    var token = await guhf.GetTokenFromHTTPContext(httpContext);
                    var user = await guhf.GetUserFromToken(token);

                    if (user == null)
                        return Results.Unauthorized();

                    var messages = await dbContext.Messages
                        .Where(m =>
                            (user.IsOrganisation && m.OrganizationId == user.UserId) ||
                            (!user.IsOrganisation && m.VolunteerId == user.UserId))
                        .OrderByDescending(m => m.IsoDate)
                        .ToListAsync();

                    return Results.Ok(messages);
                });
            // DELETE /api/messages/{id}
            group.MapDelete("/{id:int}", async (int id, ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) =>
            {
                var token = await guhf.GetTokenFromHTTPContext(httpContext);
                var user = await guhf.GetUserFromToken(token);

                if (user == null)
                    return Results.Unauthorized();

                var message = await dbContext.Messages.FindAsync(id);
                if (message == null)
                    return Results.NotFound();

                // Only allow deleting if user is either the organization or volunteer in the message
                if (user.IsOrganisation && message.OrganizationId != user.UserId)
                    return Results.Forbid();

                if (!user.IsOrganisation && message.VolunteerId != user.UserId)
                    return Results.Forbid();

                dbContext.Messages.Remove(message);
                await dbContext.SaveChangesAsync();

                return Results.NoContent();
            });

            return group;
        }
    }

    public class SendMessageRequest
    {
        public int EventId { get; set; }
        public string Content { get; set; }
    }
}
