using DbFirst.Application.Repositories;
using DbFirst.Domain.Entities;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using System.Data;

namespace DbFirst.Infrastructure.Repositories;

public class MassDataRepository : IMassDataRepository
{
    private readonly MassDataDbContext _db;

    public MassDataRepository(MassDataDbContext db)
    {
        _db = db;
    }

    public async Task<int> GetCountAsync(CancellationToken cancellationToken = default)
    {
        return await _db.Massdata.AsNoTracking().CountAsync(cancellationToken);
    }

    public async Task<Massdata?> GetByCustomerNameAsync(string customerName, CancellationToken cancellationToken = default)
    {
        return await _db.Massdata.AsNoTracking()
            .FirstOrDefaultAsync(x => x.CustomerName == customerName, cancellationToken);
    }

    public async Task<List<Massdata>> GetAllAsync(int? skip = null, int? take = null, CancellationToken cancellationToken = default)
    {
        var query = _db.Massdata.AsNoTracking().OrderBy(x => x.Id).AsQueryable();

        if (skip.HasValue)
        {
            query = query.Skip(skip.Value);
        }

        if (take.HasValue)
        {
            query = query.Take(take.Value);
        }

        return await query.ToListAsync(cancellationToken);
    }

    public async Task<Massdata> UpsertByCustomerNameAsync(string customerName, decimal amount, bool statusFlag, string category, CancellationToken cancellationToken = default)
    {
        var customerParam = new SqlParameter("@CustomerName", SqlDbType.VarChar, 200) { Value = customerName };
        var amountParam = new SqlParameter("@Amount", SqlDbType.Decimal) { Value = amount, Precision = 12, Scale = 2 };
        var statusParam = new SqlParameter("@StatusFlag", SqlDbType.Bit) { Value = statusFlag };
        var categoryParam = new SqlParameter("@Category", SqlDbType.VarChar, 100) { Value = category };

        await _db.Database.ExecuteSqlRawAsync(
            "EXEC dbo.PRMassdata_UpsertByCustomerName @CustomerName, @Amount, @StatusFlag, @Category",
            parameters: new[] { customerParam, amountParam, statusParam, categoryParam },
            cancellationToken: cancellationToken);

        var updated = await GetByCustomerNameAsync(customerName, cancellationToken);
        if (updated == null)
        {
            throw new InvalidOperationException("Upsert completed but record could not be loaded.");
        }

        return updated;
    }
}
