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

namespace SIGCM.Infrastructure.Repositories;

public class CouponRepository : ICouponRepository
{
    private readonly IDbConnectionFactory _connectionFactory;

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

    public async Task<IEnumerable<Coupon>> GetAllAsync()
    {
        using var conn = _connectionFactory.CreateConnection();
        return await conn.QueryAsync<Coupon>("SELECT * FROM Coupons ORDER BY CreatedAt DESC");
    }

    public async Task<int> CreateAsync(Coupon coupon)
    {
        using var conn = _connectionFactory.CreateConnection();
        var sql = @"
            INSERT INTO Coupons (Code, DiscountType, DiscountValue, ExpiryDate, MaxUsages, MaxUsagesPerUser, IsActive, CreatedAt)
            VALUES (@Code, @DiscountType, @DiscountValue, @ExpiryDate, @MaxUsages, @MaxUsagesPerUser, @IsActive, GETUTCDATE());
            SELECT CAST(SCOPE_IDENTITY() as int);";
        return await conn.QuerySingleAsync<int>(sql, coupon);
    }

    public async Task DeleteAsync(int id)
    {
        using var conn = _connectionFactory.CreateConnection();
        await conn.ExecuteAsync("DELETE FROM Coupons WHERE Id = @Id", new { Id = id });
    }

    public async Task<Coupon?> GetByCodeAsync(string code)
    {
        using var conn = _connectionFactory.CreateConnection();
        return await conn.QuerySingleOrDefaultAsync<Coupon>(
            "SELECT * FROM Coupons WHERE Code = @Code AND IsActive = 1", 
            new { Code = code });
    }

    public async Task IncrementUsageAsync(int id)
    {
        using var conn = _connectionFactory.CreateConnection();
        await conn.ExecuteAsync(
            "UPDATE Coupons SET UsageCount = UsageCount + 1 WHERE Id = @Id", 
            new { Id = id });
    }

    public async Task<int> CountUserUsageAsync(int userId, string couponCode)
    {
        using var conn = _connectionFactory.CreateConnection();
        // Check listings for this user with this coupon code
        // Note: CouponCode column was added to Listings
        var sql = "SELECT COUNT(1) FROM Listings WHERE UserId = @UserId AND CouponCode = @CouponCode";
        return await conn.ExecuteScalarAsync<int>(sql, new { UserId = userId, CouponCode = couponCode });
    }
}
