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

namespace SIGCM.Infrastructure.Repositories;

public class PricingRepository
{
  private readonly IDbConnectionFactory _db;

  public PricingRepository(IDbConnectionFactory db)
  {
    _db = db;
  }

  public async Task<CategoryPricing?> GetByCategoryIdAsync(int categoryId)
  {
    using var conn = _db.CreateConnection();
    return await conn.QuerySingleOrDefaultAsync<CategoryPricing>(
        "SELECT * FROM CategoryPricing WHERE CategoryId = @Id", new { Id = categoryId });
  }

  public async Task UpsertPricingAsync(CategoryPricing pricing)
  {
    using var conn = _db.CreateConnection();
    // Lógica de "Si existe actualiza, sino inserta"
    var exists = await conn.ExecuteScalarAsync<int>(
        "SELECT COUNT(1) FROM CategoryPricing WHERE CategoryId = @CategoryId", new { pricing.CategoryId });

    if (exists > 0)
    {
      var updateSql = @"
                UPDATE CategoryPricing 
                SET BasePrice = @BasePrice, BaseWordCount = @BaseWordCount, 
                    ExtraWordPrice = @ExtraWordPrice, SpecialChars = @SpecialChars,
                    SpecialCharPrice = @SpecialCharPrice, BoldSurcharge = @BoldSurcharge,
                    FrameSurcharge = @FrameSurcharge
                WHERE CategoryId = @CategoryId";
      await conn.ExecuteAsync(updateSql, pricing);
    }
    else
    {
      var insertSql = @"
                INSERT INTO CategoryPricing 
                (CategoryId, BasePrice, BaseWordCount, ExtraWordPrice, SpecialChars, SpecialCharPrice, BoldSurcharge, FrameSurcharge)
                VALUES 
                (@CategoryId, @BasePrice, @BaseWordCount, @ExtraWordPrice, @SpecialChars, @SpecialCharPrice, @BoldSurcharge, @FrameSurcharge)";
      await conn.ExecuteAsync(insertSql, pricing);
    }
  }

  public async Task<IEnumerable<Promotion>> GetActivePromotionsAsync()
  {
    using var conn = _db.CreateConnection();
    return await conn.QueryAsync<Promotion>(
        "SELECT * FROM Promotions WHERE IsActive = 1");
  }

  // --- SECCIÓN PROMOCIONES ---

  public async Task<IEnumerable<Promotion>> GetAllPromotionsAsync()
  {
    using var conn = _db.CreateConnection();
    return await conn.QueryAsync<Promotion>("SELECT * FROM Promotions ORDER BY Id DESC");
  }

  public async Task<int> CreatePromotionAsync(Promotion promo)
  {
    using var conn = _db.CreateConnection();
    var sql = @"
            INSERT INTO Promotions (Name, CategoryId, MinDays, DaysOfWeek, DiscountPercentage, DiscountFixedAmount, IsActive)
            VALUES (@Name, @CategoryId, @MinDays, @DaysOfWeek, @DiscountPercentage, @DiscountFixedAmount, @IsActive);
            SELECT CAST(SCOPE_IDENTITY() as int);";
    return await conn.QuerySingleAsync<int>(sql, promo);
  }

  public async Task UpdatePromotionAsync(Promotion promo)
  {
    using var conn = _db.CreateConnection();
    var sql = @"
            UPDATE Promotions 
            SET Name = @Name, CategoryId = @CategoryId, MinDays = @MinDays, 
                DaysOfWeek = @DaysOfWeek, DiscountPercentage = @DiscountPercentage, 
                DiscountFixedAmount = @DiscountFixedAmount, IsActive = @IsActive
            WHERE Id = @Id";
    await conn.ExecuteAsync(sql, promo);
  }

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