using System.Data;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;

namespace WerksverkaufScanner.Services;

public class PreisAenderungSqlService
{
    private readonly string _connectionString;

    public PreisAenderungSqlService(IConfiguration cfg)
    {
        _connectionString = cfg.GetConnectionString("Default")
            ?? throw new InvalidOperationException("Connection string 'Default' fehlt.");
    }

    public async Task<int> SaveAsync(
        string filialId,
        int artikelId,
        int artikelVariantenId,
        int variante,
        int preisInCents,
        string benutzer)
    {
        // Preis aus Cent zu Euro (decimal)
        var neuerPreis = preisInCents / 100m;

        await using var con = new SqlConnection(_connectionString);
        await con.OpenAsync();

        await using var tx = await con.BeginTransactionAsync();

        try
        {
            // 1️⃣ Alten Preis auslesen
            decimal alterPreis = 0;
            const string selectSql = @"
SELECT ISNULL(VerkaufsPreis, 0)
FROM [Kassensystem].[KS].[ArtikelVariantenFI]
WHERE FilialId = @FilialId AND ArtikelVariantenId = @ArtikelVariantenId;";

            await using (var selectCmd = new SqlCommand(selectSql, con, (SqlTransaction)tx))
            {
                selectCmd.Parameters.Add("@FilialId", SqlDbType.NVarChar, 20).Value = filialId;
                selectCmd.Parameters.Add("@ArtikelVariantenId", SqlDbType.Int).Value = artikelVariantenId;

                var result = await selectCmd.ExecuteScalarAsync();
                if (result != null && result != DBNull.Value)
                    alterPreis = Convert.ToDecimal(result);
            }

            // 2️⃣ Update im ArtikelVariantenFI
            const string updateSql = @"
                UPDATE [Kassensystem].[KS].[ArtikelVariantenFI]
                SET VerkaufsPreis = @NeuerPreis,
                    LetzteÄnderung = SYSUTCDATETIME(),
                    VonUser = @User
                WHERE FilialId = @FilialId AND ArtikelVariantenId = @ArtikelVariantenId;";

            await using (var updateCmd = new SqlCommand(updateSql, con, (SqlTransaction)tx))
            {
                updateCmd.Parameters.Add("@NeuerPreis", SqlDbType.Decimal).Value = neuerPreis;
                updateCmd.Parameters.Add("@User", SqlDbType.NVarChar, 100).Value = benutzer;
                updateCmd.Parameters.Add("@FilialId", SqlDbType.NVarChar, 20).Value = filialId;
                updateCmd.Parameters.Add("@ArtikelVariantenId", SqlDbType.Int).Value = artikelVariantenId;

                await updateCmd.ExecuteNonQueryAsync();
            }

            // 3️⃣ Insert in PreisHistorie
            const string insertSql = @"
                INSERT INTO [Kassensystem].[KS].[PreisHistorie]
                    (FilialId, ArtikelVariantenId, AlterPreis, NeuerPreis, Zeitpunkt, Anwender)
                    VALUES
                    (@FilialId, @ArtikelVariantenId, @AlterPreis, @NeuerPreis, SYSUTCDATETIME(), @User);";

            await using (var insertCmd = new SqlCommand(insertSql, con, (SqlTransaction)tx))
            {
                insertCmd.Parameters.Add("@FilialId", SqlDbType.NVarChar, 20).Value = filialId;
                insertCmd.Parameters.Add("@ArtikelVariantenId", SqlDbType.Int).Value = artikelVariantenId;
                insertCmd.Parameters.Add("@AlterPreis", SqlDbType.Decimal).Value = alterPreis;
                insertCmd.Parameters.Add("@NeuerPreis", SqlDbType.Decimal).Value = neuerPreis;
                insertCmd.Parameters.Add("@User", SqlDbType.NVarChar, 100).Value = benutzer;

                await insertCmd.ExecuteNonQueryAsync();
            }

            await tx.CommitAsync();
            return 1; // Erfolg
        }
        catch
        {
            await tx.RollbackAsync();
            throw;
        }
    }
}
