using Dapper;
using SIGCM.Domain.Entities;
using SIGCM.Domain.Interfaces;
using SIGCM.Infrastructure.Data;

namespace SIGCM.Infrastructure.Repositories;

public class ListingNoteRepository : IListingNoteRepository
{
    private readonly IDbConnectionFactory _connectionFactory;

    public ListingNoteRepository(IDbConnectionFactory connectionFactory)
    {
        _connectionFactory = connectionFactory;
    }

    public async Task<int> CreateAsync(ListingNote note)
    {
        using var conn = _connectionFactory.CreateConnection();
        var sql = @"
            INSERT INTO ListingNotes (ListingId, SenderId, IsFromModerator, Message, CreatedAt, IsRead)
            VALUES (@ListingId, @SenderId, @IsFromModerator, @Message, GETUTCDATE(), 0);
            SELECT CAST(SCOPE_IDENTITY() as int);";
        return await conn.QuerySingleAsync<int>(sql, note);
    }

    public async Task<IEnumerable<ListingNote>> GetByListingIdAsync(int listingId)
    {
        using var conn = _connectionFactory.CreateConnection();
        var sql = "SELECT * FROM ListingNotes WHERE ListingId = @ListingId ORDER BY CreatedAt ASC";
        return await conn.QueryAsync<ListingNote>(sql, new { ListingId = listingId });
    }

    public async Task<IEnumerable<ListingNote>> GetByUserIdAsync(int userId)
    {
        using var conn = _connectionFactory.CreateConnection();
        var sql = @"
            SELECT ln.* 
            FROM ListingNotes ln
            INNER JOIN Listings l ON ln.ListingId = l.Id
            WHERE l.UserId = @UserId
            ORDER BY ln.CreatedAt DESC";
        return await conn.QueryAsync<ListingNote>(sql, new { UserId = userId });
    }

    public async Task MarkAsReadAsync(int noteId)
    {
        using var conn = _connectionFactory.CreateConnection();
        await conn.ExecuteAsync("UPDATE ListingNotes SET IsRead = 1 WHERE Id = @Id", new { Id = noteId });
    }

    public async Task<int> GetUnreadCountAsync(int userId, bool isForModerator)
    {
        using var conn = _connectionFactory.CreateConnection();
        var sql = "";
        if (isForModerator)
        {
            // Para moderadores: Mensajes que NO son de moderador y NO están leídos
            sql = @"SELECT COUNT(*) FROM ListingNotes WHERE IsFromModerator = 0 AND IsRead = 0";
        }
        else
        {
            // Para usuarios: Mensajes que SON de moderador, para sus avisos, y NO están leídos
            sql = @"
                SELECT COUNT(*) 
                FROM ListingNotes ln
                INNER JOIN Listings l ON ln.ListingId = l.Id
                WHERE l.UserId = @UserId AND ln.IsFromModerator = 1 AND ln.IsRead = 0";
        }
        return await conn.ExecuteScalarAsync<int>(sql, new { UserId = userId });
    }
}
