using Dapper;
using EVCB_OCPP.Domain;
using EVCB_OCPP.Packet.Messages.SubTypes;
using EVCB_OCPP.WEBAPI.Helpers;
using EVCB_OCPP.WEBAPI.Models;
using EVCB_OCPP.WEBAPI.Models.WebAPI.Dto;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;

namespace EVCB_OCPP.WEBAPI.Services;

public class MeterValueDbService
{
    public MeterValueDbService(
        SqlConnectionFactory<MeterValueDBContext> meterValueDbConnectionFactory,
        ILogger<MeterValueDbService> logger)
    {
        this.meterValueDbConnectionFactory = meterValueDbConnectionFactory;
        this.logger = logger;
    }

    private readonly SqlConnectionFactory<MeterValueDBContext> meterValueDbConnectionFactory;
    private readonly ILogger<MeterValueDbService> logger;

    internal async Task<List<ConnectorMeterValueModel>> GetChargeBoxTransactionMeterValues(DateTime minStartTime, string chargeBoxId, IEnumerable<int> transactionIds, IEnumerable<int> measurandCodes)
    {
        var toReturn = new List<ConnectorMeterValueModel>();
        string date = minStartTime.ToString("yyMMdd");
        string cmd = $"""
                    WITH CTE AS (
                        SELECT
                            s.*,
                            ROW_NUMBER() OVER (PARTITION BY s.MeasurandId ORDER BY s.CreatedOn DESC) AS RowNum
                        FROM [dbo].[ConnectorMeterValueRecord{date}] s
                        WHERE s.ChargeBoxId = @ChargeBoxId
                            AND s.TransactionId IN @TransactionIds
                            AND s.MeasurandId IN @MeasurandIds
                    )
                    SELECT *
                    FROM CTE
                    WHERE RowNum = 1;
                    """;

        var parameters = new DynamicParameters();
        parameters.Add("@ChargeBoxId", chargeBoxId, DbType.String, ParameterDirection.Input, 50);
        parameters.Add("@TransactionIds", transactionIds);
        parameters.Add("@MeasurandIds", measurandCodes);

        using SqlConnection conn = await meterValueDbConnectionFactory.CreateAsync();
        var result = await conn.QueryAsync<ConnectorMeterValueModel>(cmd, parameters, commandTimeout: EVCBConfiguration.DB_DefaultConnectionTimeout);
        toReturn = result.ToList();

        return toReturn;
    }
}
