using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.IO;
using BettingPredictor;
using HorseRacingPredictor.Manager;

namespace HorseRacingPredictor.Horses
{
    internal class Database : HorseRacingPredictor.Manager.Database
    {
        // Implementazione della proprietà astratta _connectionString per il database cavalli
        protected override string _connectionString => "Server=DESKTOP-9O9JHFS;Database=TestBS_Horses;User Id=sa;Password=Asti2019;";

        private readonly FileReader fileReaderHorses;

        public Database()
        {
            fileReaderHorses = new FileReader();
        }

        public DataTable GetAllHorseRaceData()
        {
            DataTable horseRaceData = new DataTable();
            ExecuteQuery("GetAllHorseRaceData", connection =>
            {
                using (SqlCommand command = new SqlCommand("SELECT * FROM HorseRaceData", connection))
                {
                    using (SqlDataAdapter adapter = new SqlDataAdapter(command))
                    {
                        adapter.Fill(horseRaceData);
                    }
                }
            });
            return horseRaceData;
        }

        public void ProcessAndInsertHorseRaceData(string filePath)
        {
            try
            {
                // Leggi i dati dal file CSV usando il nuovo metodo che restituisce HorseRaceData
                List<HorseRaceData> horseDataList = fileReaderHorses.ReadHorseDataFromFile(filePath);

                // Utilizza i metodi del FileReader per estrarre informazioni sulla corsa
                DateTime raceDate = fileReaderHorses.ExtractRaceDate(filePath);
                string meeting = fileReaderHorses.ExtractMeetingName(filePath);
                int race = fileReaderHorses.ExtractRaceNumber(filePath);

                // Inserisci i dati nel database
                InsertHorseDataInRacesTable(horseDataList, meeting, race, raceDate, filePath);

                Console.WriteLine($"Elaborazione e inserimento dati corsa cavalli completata: {filePath}");
            }
            catch (Exception ex)
            {
                LogError($"l'elaborazione del file {filePath}", ex);
            }
        }

        private void InsertHorseDataInRacesTable(List<HorseRaceData> horseDataList, string meeting, int race, DateTime raceDate, string filePath)
        {
            string operation = "l'inserimento dei dati dei cavalli nella tabella Races";

            ExecuteQuery(operation, connection =>
            {
                foreach (var horseData in horseDataList)
                {
                    UpsertRacesTableData(connection, horseData, meeting, race, raceDate, filePath);
                }
            });
        }

        private void UpsertRacesTableData(SqlConnection connection, HorseRaceData horseData, string meeting, int race, DateTime raceDate, string filePath)
        {
            try
            {
                // Numero del cavallo
                int num = 0;
                int.TryParse(horseData.Num, out num);

                // Data e ora attuale per i campi Created e Updated
                DateTime currentDateTime = DateTime.Now;

                string query = @"
                                    IF EXISTS (SELECT 1 FROM Races WHERE Data = @Data AND Meeting = @Meeting AND Race = @Race AND Num = @Num)
                                    BEGIN
                                        UPDATE Races SET 
                                            FileName = @FileName,
                                            HorseName = @HorseName,
                                            Age = @Age,
                                            Gender = @Gender,
                                            HandicapRating = @HandicapRating,
                                            CareerRuns = @CareerRuns,
                                            CareerWins = @CareerWins,
                                            CareerStrikeRate = @CareerStrikeRate,
                                            CareerROI = @CareerROI,
                                            CareerPlacings = @CareerPlacings,
                                            CareerPlaceStrikeRate = @CareerPlaceStrikeRate,
                                            DryTrackRuns = @DryTrackRuns,
                                            DryTrackWins = @DryTrackWins,
                                            DryTrackStrikeRate = @DryTrackStrikeRate,
                                            DryTrackROI = @DryTrackROI,
                                            WetTrackRuns = @WetTrackRuns,
                                            WetTrackWins = @WetTrackWins,
                                            WetTrackStrikeRate = @WetTrackStrikeRate,
                                            WetTrackROI = @WetTrackROI,
                                            AveragePrizeMoney = @AveragePrizeMoney,
                                            CareerPrizeMoney = @CareerPrizeMoney,
                                            BestFixedOdds = @BestFixedOdds,
                                            BetEasyOdds = @BetEasyOdds,
                                            Weight = @Weight,
                                            WeightCarried = @WeightCarried,
                                            Barrier = @Barrier,
                                            PrizeMoney = @PrizeMoney,
                                            ThisTrackRuns = @ThisTrackRuns,
                                            ThisTrackWins = @ThisTrackWins,
                                            ThisTrackStrikeRate = @ThisTrackStrikeRate,
                                            ThisTrackROI = @ThisTrackROI,
                                            ThisTrackPlaces = @ThisTrackPlaces,
                                            ThisTrackPlaceStrikeRate = @ThisTrackPlaceStrikeRate,
                                            ThisDistanceRuns = @ThisDistanceRuns,
                                            ThisDistanceWins = @ThisDistanceWins,
                                            ThisDistanceStrikeRate = @ThisDistanceStrikeRate,
                                            ThisDistanceROI = @ThisDistanceROI,
                                            ThisDistancePlaces = @ThisDistancePlaces,
                                            ThisDistancePlaceStrikeRate = @ThisDistancePlaceStrikeRate,
                                            ThisTrackDistanceRuns = @ThisTrackDistanceRuns,
                                            ThisTrackDistanceWins = @ThisTrackDistanceWins,
                                            ThisTrackDistanceStrikeRate = @ThisTrackDistanceStrikeRate,
                                            ThisTrackDistanceROI = @ThisTrackDistanceROI,
                                            ThisTrackDistancePlaces = @ThisTrackDistancePlaces,
                                            ThisTrackDistancePlaceStrikeRate = @ThisTrackDistancePlaceStrikeRate,
                                            ThisConditionRuns = @ThisConditionRuns,
                                            ThisConditionWins = @ThisConditionWins,
                                            ThisConditionStrikeRate = @ThisConditionStrikeRate,
                                            ThisConditionROI = @ThisConditionROI,
                                            ThisConditionPlaces = @ThisConditionPlaces,
                                            ThisConditionPlaceStrikeRate = @ThisConditionPlaceStrikeRate,
                                            Jockey = @Jockey,
                                            Apprentice = @Apprentice,
                                            JockeyWeightClaim = @JockeyWeightClaim,
                                            JockeyLast100HorseEarnings = @JockeyLast100HorseEarnings,
                                            JockeyLast100AvgHorseEarnings = @JockeyLast100AvgHorseEarnings,
                                            JockeyLast100Starts = @JockeyLast100Starts,
                                            JockeyLast100Wins = @JockeyLast100Wins,
                                            JockeyLast100StrikeRate = @JockeyLast100StrikeRate,
                                            JockeyLast100ROI = @JockeyLast100ROI,
                                            JockeyLast100Places = @JockeyLast100Places,
                                            JockeyLast100PlaceStrikeRate = @JockeyLast100PlaceStrikeRate,
                                            Jockey12MonthHorseEarnings = @Jockey12MonthHorseEarnings,
                                            Jockey12MonthAvgHorseEarnings = @Jockey12MonthAvgHorseEarnings,
                                            Jockey12MonthsStarts = @Jockey12MonthsStarts,
                                            Jockey12MonthsWins = @Jockey12MonthsWins,
                                            Jockey12MonthsStrikeRate = @Jockey12MonthsStrikeRate,
                                            Jockey12MonthsROI = @Jockey12MonthsROI,
                                            Jockey12MonthsPlaces = @Jockey12MonthsPlaces,
                                            Jockey12MonthsPlaceStrikeRate = @Jockey12MonthsPlaceStrikeRate,
                                            JockeyThisSeasonHorseEarnings = @JockeyThisSeasonHorseEarnings,
                                            JockeyThisSeasonAvgHorseEarnings = @JockeyThisSeasonAvgHorseEarnings,
                                            JockeyThisSeasonStarts = @JockeyThisSeasonStarts,
                                            JockeyThisSeasonWins = @JockeyThisSeasonWins,
                                            JockeyThisSeasonStrikeRate = @JockeyThisSeasonStrikeRate,
                                            JockeyThisSeasonROI = @JockeyThisSeasonROI,
                                            JockeyThisSeasonPlaces = @JockeyThisSeasonPlaces,
                                            JockeyThisSeasonPlaceStrikeRate = @JockeyThisSeasonPlaceStrikeRate,
                                            JockeyLastSeasonHorseEarnings = @JockeyLastSeasonHorseEarnings,
                                            JockeyLastSeasonAvgHorseEarnings = @JockeyLastSeasonAvgHorseEarnings,
                                            JockeyLastSeasonStarts = @JockeyLastSeasonStarts,
                                            JockeyLastSeasonWins = @JockeyLastSeasonWins,
                                            JockeyLastSeasonStrikeRate = @JockeyLastSeasonStrikeRate,
                                            JockeyLastSeasonROI = @JockeyLastSeasonROI,
                                            JockeyLastSeasonPlaces = @JockeyLastSeasonPlaces,
                                            JockeyLastSeasonPlaceStrikeRate = @JockeyLastSeasonPlaceStrikeRate,
                                            Trainer = @Trainer,
                                            TrainerLast100HorseEarnings = @TrainerLast100HorseEarnings,
                                            TrainerLast100AvgHorseEarnings = @TrainerLast100AvgHorseEarnings,
                                            TrainerLast100Starts = @TrainerLast100Starts,
                                            TrainerLast100Wins = @TrainerLast100Wins,
                                            TrainerLast100StrikeRate = @TrainerLast100StrikeRate,
                                            TrainerLast100ROI = @TrainerLast100ROI,
                                            TrainerLast100Places = @TrainerLast100Places,
                                            TrainerLast100PlaceStrikeRate = @TrainerLast100PlaceStrikeRate,
                                            Trainer12MonthHorseEarnings = @Trainer12MonthHorseEarnings,
                                            Trainer12MonthAvgHorseEarnings = @Trainer12MonthAvgHorseEarnings,
                                            Trainer12MonthsStarts = @Trainer12MonthsStarts,
                                            Trainer12MonthsWins = @Trainer12MonthsWins,
                                            Trainer12MonthsStrikeRate = @Trainer12MonthsStrikeRate,
                                            Trainer12MonthsROI = @Trainer12MonthsROI,
                                            Trainer12MonthsPlaces = @Trainer12MonthsPlaces,
                                            Trainer12MonthsPlaceStrikeRate = @Trainer12MonthsPlaceStrikeRate,
                                            TrainerThisSeasonHorseEarnings = @TrainerThisSeasonHorseEarnings,
                                            TrainerThisSeasonAvgHorseEarnings = @TrainerThisSeasonAvgHorseEarnings,
                                            TrainerThisSeasonStarts = @TrainerThisSeasonStarts,
                                            TrainerThisSeasonWins = @TrainerThisSeasonWins,
                                            TrainerThisSeasonStrikeRate = @TrainerThisSeasonStrikeRate,
                                            TrainerThisSeasonROI = @TrainerThisSeasonROI,
                                            TrainerThisSeasonPlaces = @TrainerThisSeasonPlaces,
                                            TrainerThisSeasonPlaceStrikeRate = @TrainerThisSeasonPlaceStrikeRate,
                                            TrainerLastSeasonHorseEarnings = @TrainerLastSeasonHorseEarnings,
                                            TrainerLastSeasonAvgHorseEarnings = @TrainerLastSeasonAvgHorseEarnings,
                                            TrainerLastSeasonStarts = @TrainerLastSeasonStarts,
                                            TrainerLastSeasonWins = @TrainerLastSeasonWins,
                                            TrainerLastSeasonStrikeRate = @TrainerLastSeasonStrikeRate,
                                            TrainerLastSeasonROI = @TrainerLastSeasonROI,
                                            TrainerLastSeasonPlaces = @TrainerLastSeasonPlaces,
                                            TrainerLastSeasonPlaceStrikeRate = @TrainerLastSeasonPlaceStrikeRate,
                                            LastStartFinishPosition = @LastStartFinishPosition,
                                            LastStartMargin = @LastStartMargin,
                                            LastStartDistance = @LastStartDistance,
                                            LastStartDistanceChange = @LastStartDistanceChange,
                                            LastStartPrizeMoney = @LastStartPrizeMoney,
                                            FormGuideUrl = @FormGuideUrl,
                                            HorseProfileUrl = @HorseProfileUrl,
                                            JockeyProfileUrl = @JockeyProfileUrl,
                                            TrainerProfileUrl = @TrainerProfileUrl,
                                            FinishResult = @FinishResult,
                                            Updated = @Updated
                                        WHERE Data = @Data AND Meeting = @Meeting AND Race = @Race AND Num = @Num
                                    END
                                    ELSE
                                    BEGIN
                                        INSERT INTO Races (
                                            Data, Meeting, Race, Num, FileName, HorseName, Age, Gender, HandicapRating,
                                            CareerRuns, CareerWins, CareerStrikeRate, CareerROI, CareerPlacings, CareerPlaceStrikeRate,
                                            DryTrackRuns, DryTrackWins, DryTrackStrikeRate, DryTrackROI, WetTrackRuns, WetTrackWins,
                                            WetTrackStrikeRate, WetTrackROI, AveragePrizeMoney, CareerPrizeMoney, BestFixedOdds, BetEasyOdds,
                                            Weight, WeightCarried, Barrier, PrizeMoney, ThisTrackRuns, ThisTrackWins, ThisTrackStrikeRate,
                                            ThisTrackROI, ThisTrackPlaces, ThisTrackPlaceStrikeRate, ThisDistanceRuns, ThisDistanceWins,
                                            ThisDistanceStrikeRate, ThisDistanceROI, ThisDistancePlaces, ThisDistancePlaceStrikeRate,
                                            ThisTrackDistanceRuns, ThisTrackDistanceWins, ThisTrackDistanceStrikeRate, ThisTrackDistanceROI,
                                            ThisTrackDistancePlaces, ThisTrackDistancePlaceStrikeRate, ThisConditionRuns, ThisConditionWins,
                                            ThisConditionStrikeRate, ThisConditionROI, ThisConditionPlaces, ThisConditionPlaceStrikeRate,
                                            Jockey, Apprentice, JockeyWeightClaim, JockeyLast100HorseEarnings, JockeyLast100AvgHorseEarnings,
                                            JockeyLast100Starts, JockeyLast100Wins, JockeyLast100StrikeRate, JockeyLast100ROI, JockeyLast100Places,
                                            JockeyLast100PlaceStrikeRate, Jockey12MonthHorseEarnings, Jockey12MonthAvgHorseEarnings,
                                            Jockey12MonthsStarts, Jockey12MonthsWins, Jockey12MonthsStrikeRate, Jockey12MonthsROI,
                                            Jockey12MonthsPlaces, Jockey12MonthsPlaceStrikeRate, JockeyThisSeasonHorseEarnings,
                                            JockeyThisSeasonAvgHorseEarnings, JockeyThisSeasonStarts, JockeyThisSeasonWins,
                                            JockeyThisSeasonStrikeRate, JockeyThisSeasonROI, JockeyThisSeasonPlaces, JockeyThisSeasonPlaceStrikeRate,
                                            JockeyLastSeasonHorseEarnings, JockeyLastSeasonAvgHorseEarnings, JockeyLastSeasonStarts,
                                            JockeyLastSeasonWins, JockeyLastSeasonStrikeRate, JockeyLastSeasonROI, JockeyLastSeasonPlaces,
                                            JockeyLastSeasonPlaceStrikeRate, Trainer, TrainerLast100HorseEarnings, TrainerLast100AvgHorseEarnings,
                                            TrainerLast100Starts, TrainerLast100Wins, TrainerLast100StrikeRate, TrainerLast100ROI,
                                            TrainerLast100Places, TrainerLast100PlaceStrikeRate, Trainer12MonthHorseEarnings,
                                            Trainer12MonthAvgHorseEarnings, Trainer12MonthsStarts, Trainer12MonthsWins, Trainer12MonthsStrikeRate,
                                            Trainer12MonthsROI, Trainer12MonthsPlaces, Trainer12MonthsPlaceStrikeRate, TrainerThisSeasonHorseEarnings,
                                            TrainerThisSeasonAvgHorseEarnings, TrainerThisSeasonStarts, TrainerThisSeasonWins,
                                            TrainerThisSeasonStrikeRate, TrainerThisSeasonROI, TrainerThisSeasonPlaces, TrainerThisSeasonPlaceStrikeRate,
                                            TrainerLastSeasonHorseEarnings, TrainerLastSeasonAvgHorseEarnings, TrainerLastSeasonStarts,
                                            TrainerLastSeasonWins, TrainerLastSeasonStrikeRate, TrainerLastSeasonROI, TrainerLastSeasonPlaces,
                                            TrainerLastSeasonPlaceStrikeRate, LastStartFinishPosition, LastStartMargin, LastStartDistance, 
                                            LastStartDistanceChange, LastStartPrizeMoney, FormGuideUrl, HorseProfileUrl, JockeyProfileUrl, 
                                            TrainerProfileUrl, FinishResult, Created, Updated
                                        ) VALUES (
                                            @Data, @Meeting, @Race, @Num, @FileName, @HorseName, @Age, @Gender, @HandicapRating,
                                            @CareerRuns, @CareerWins, @CareerStrikeRate, @CareerROI, @CareerPlacings, @CareerPlaceStrikeRate,
                                            @DryTrackRuns, @DryTrackWins, @DryTrackStrikeRate, @DryTrackROI, @WetTrackRuns, @WetTrackWins,
                                            @WetTrackStrikeRate, @WetTrackROI, @AveragePrizeMoney, @CareerPrizeMoney, @BestFixedOdds, @BetEasyOdds,
                                            @Weight, @WeightCarried, @Barrier, @PrizeMoney, @ThisTrackRuns, @ThisTrackWins, @ThisTrackStrikeRate,
                                            @ThisTrackROI, @ThisTrackPlaces, @ThisTrackPlaceStrikeRate, @ThisDistanceRuns, @ThisDistanceWins,
                                            @ThisDistanceStrikeRate, @ThisDistanceROI, @ThisDistancePlaces, @ThisDistancePlaceStrikeRate,
                                            @ThisTrackDistanceRuns, @ThisTrackDistanceWins, @ThisTrackDistanceStrikeRate, @ThisTrackDistanceROI,
                                            @ThisTrackDistancePlaces, @ThisTrackDistancePlaceStrikeRate, @ThisConditionRuns, @ThisConditionWins,
                                            @ThisConditionStrikeRate, @ThisConditionROI, @ThisConditionPlaces, @ThisConditionPlaceStrikeRate,
                                            @Jockey, @Apprentice, @JockeyWeightClaim, @JockeyLast100HorseEarnings, @JockeyLast100AvgHorseEarnings,
                                            @JockeyLast100Starts, @JockeyLast100Wins, @JockeyLast100StrikeRate, @JockeyLast100ROI, @JockeyLast100Places,
                                            @JockeyLast100PlaceStrikeRate, @Jockey12MonthHorseEarnings, @Jockey12MonthAvgHorseEarnings,
                                            @Jockey12MonthsStarts, @Jockey12MonthsWins, @Jockey12MonthsStrikeRate, @Jockey12MonthsROI,
                                            @Jockey12MonthsPlaces, @Jockey12MonthsPlaceStrikeRate, @JockeyThisSeasonHorseEarnings,
                                            @JockeyThisSeasonAvgHorseEarnings, @JockeyThisSeasonStarts, @JockeyThisSeasonWins,
                                            @JockeyThisSeasonStrikeRate, @JockeyThisSeasonROI, @JockeyThisSeasonPlaces, @JockeyThisSeasonPlaceStrikeRate,
                                            @JockeyLastSeasonHorseEarnings, @JockeyLastSeasonAvgHorseEarnings, @JockeyLastSeasonStarts,
                                            @JockeyLastSeasonWins, @JockeyLastSeasonStrikeRate, @JockeyLastSeasonROI, @JockeyLastSeasonPlaces,
                                            @JockeyLastSeasonPlaceStrikeRate, @Trainer, @TrainerLast100HorseEarnings, @TrainerLast100AvgHorseEarnings,
                                            @TrainerLast100Starts, @TrainerLast100Wins, @TrainerLast100StrikeRate, @TrainerLast100ROI,
                                            @TrainerLast100Places, @TrainerLast100PlaceStrikeRate, @Trainer12MonthHorseEarnings,
                                            @Trainer12MonthAvgHorseEarnings, @Trainer12MonthsStarts, @Trainer12MonthsWins, @Trainer12MonthsStrikeRate,
                                            @Trainer12MonthsROI, @Trainer12MonthsPlaces, @Trainer12MonthsPlaceStrikeRate, @TrainerThisSeasonHorseEarnings,
                                            @TrainerThisSeasonAvgHorseEarnings, @TrainerThisSeasonStarts, @TrainerThisSeasonWins,
                                            @TrainerThisSeasonStrikeRate, @TrainerThisSeasonROI, @TrainerThisSeasonPlaces, @TrainerThisSeasonPlaceStrikeRate,
                                            @TrainerLastSeasonHorseEarnings, @TrainerLastSeasonAvgHorseEarnings, @TrainerLastSeasonStarts,
                                            @TrainerLastSeasonWins, @TrainerLastSeasonStrikeRate, @TrainerLastSeasonROI, @TrainerLastSeasonPlaces,
                                            @TrainerLastSeasonPlaceStrikeRate, @LastStartFinishPosition, @LastStartMargin, @LastStartDistance, 
                                            @LastStartDistanceChange, @LastStartPrizeMoney, @FormGuideUrl, @HorseProfileUrl, @JockeyProfileUrl, 
                                            @TrainerProfileUrl, @FinishResult, @Created, @Updated
                                        )
                                    END";

                using (var command = new SqlCommand(query, connection))
                {
                    // Chiavi primarie
                    command.Parameters.AddWithValue("@Data", raceDate);
                    command.Parameters.AddWithValue("@Meeting", meeting ?? string.Empty);
                    command.Parameters.AddWithValue("@Race", race);
                    command.Parameters.AddWithValue("@Num", num);

                    // Dati accessori
                    command.Parameters.AddWithValue("@FileName", filePath ?? string.Empty);

                    // Dati cavallo
                    command.Parameters.AddWithValue("@HorseName", horseData.HorseName ?? string.Empty);
                    command.Parameters.AddWithValue("@Age", horseData.Age);
                    command.Parameters.AddWithValue("@Gender", horseData.Gender ?? string.Empty);
                    command.Parameters.AddWithValue("@HandicapRating", horseData.HandicapRating);
                    command.Parameters.AddWithValue("@CareerRuns", horseData.CareerRuns);
                    command.Parameters.AddWithValue("@CareerWins", horseData.CareerWins);
                    command.Parameters.AddWithValue("@CareerStrikeRate", horseData.CareerStrikeRate);
                    command.Parameters.AddWithValue("@CareerROI", horseData.CareerROI);
                    command.Parameters.AddWithValue("@CareerPlacings", horseData.CareerPlacings);
                    command.Parameters.AddWithValue("@CareerPlaceStrikeRate", horseData.CareerPlaceStrikeRate);
                    command.Parameters.AddWithValue("@DryTrackRuns", horseData.DryTrackRuns);
                    command.Parameters.AddWithValue("@DryTrackWins", horseData.DryTrackWins);
                    command.Parameters.AddWithValue("@DryTrackStrikeRate", horseData.DryTrackStrikeRate);
                    command.Parameters.AddWithValue("@DryTrackROI", horseData.DryTrackROI);
                    command.Parameters.AddWithValue("@WetTrackRuns", horseData.WetTrackRuns);
                    command.Parameters.AddWithValue("@WetTrackWins", horseData.WetTrackWins);
                    command.Parameters.AddWithValue("@WetTrackStrikeRate", horseData.WetTrackStrikeRate);
                    command.Parameters.AddWithValue("@WetTrackROI", horseData.WetTrackROI);
                    command.Parameters.AddWithValue("@AveragePrizeMoney", horseData.AveragePrizeMoney);
                    command.Parameters.AddWithValue("@CareerPrizeMoney", horseData.CareerPrizeMoney);
                    command.Parameters.AddWithValue("@BestFixedOdds", horseData.BestFixedOdds);
                    command.Parameters.AddWithValue("@BetEasyOdds", horseData.BetEasyOdds);
                    command.Parameters.AddWithValue("@Weight", horseData.Weight);
                    command.Parameters.AddWithValue("@WeightCarried", horseData.WeightCarried);
                    command.Parameters.AddWithValue("@Barrier", horseData.Barrier);
                    command.Parameters.AddWithValue("@PrizeMoney", horseData.PrizeMoney);

                    // Statistiche pista
                    command.Parameters.AddWithValue("@ThisTrackRuns", horseData.ThisTrackRuns);
                    command.Parameters.AddWithValue("@ThisTrackWins", horseData.ThisTrackWins);
                    command.Parameters.AddWithValue("@ThisTrackStrikeRate", horseData.ThisTrackStrikeRate);
                    command.Parameters.AddWithValue("@ThisTrackROI", horseData.ThisTrackROI);
                    command.Parameters.AddWithValue("@ThisTrackPlaces", horseData.ThisTrackPlaces);
                    command.Parameters.AddWithValue("@ThisTrackPlaceStrikeRate", horseData.ThisTrackPlaceStrikeRate);
                    command.Parameters.AddWithValue("@ThisDistanceRuns", horseData.ThisDistanceRuns);
                    command.Parameters.AddWithValue("@ThisDistanceWins", horseData.ThisDistanceWins);
                    command.Parameters.AddWithValue("@ThisDistanceStrikeRate", horseData.ThisDistanceStrikeRate);
                    command.Parameters.AddWithValue("@ThisDistanceROI", horseData.ThisDistanceROI);
                    command.Parameters.AddWithValue("@ThisDistancePlaces", horseData.ThisDistancePlaces);
                    command.Parameters.AddWithValue("@ThisDistancePlaceStrikeRate", horseData.ThisDistancePlaceStrikeRate);
                    command.Parameters.AddWithValue("@ThisTrackDistanceRuns", horseData.ThisTrackDistanceRuns);
                    command.Parameters.AddWithValue("@ThisTrackDistanceWins", horseData.ThisTrackDistanceWins);
                    command.Parameters.AddWithValue("@ThisTrackDistanceStrikeRate", horseData.ThisTrackDistanceStrikeRate);
                    command.Parameters.AddWithValue("@ThisTrackDistanceROI", horseData.ThisTrackDistanceROI);
                    command.Parameters.AddWithValue("@ThisTrackDistancePlaces", horseData.ThisTrackDistancePlaces);
                    command.Parameters.AddWithValue("@ThisTrackDistancePlaceStrikeRate", horseData.ThisTrackDistancePlaceStrikeRate);
                    command.Parameters.AddWithValue("@ThisConditionRuns", horseData.ThisConditionRuns);
                    command.Parameters.AddWithValue("@ThisConditionWins", horseData.ThisConditionWins);
                    command.Parameters.AddWithValue("@ThisConditionStrikeRate", horseData.ThisConditionStrikeRate);
                    command.Parameters.AddWithValue("@ThisConditionROI", horseData.ThisConditionROI);
                    command.Parameters.AddWithValue("@ThisConditionPlaces", horseData.ThisConditionPlaces);
                    command.Parameters.AddWithValue("@ThisConditionPlaceStrikeRate", horseData.ThisConditionPlaceStrikeRate);

                    // Jockey
                    command.Parameters.AddWithValue("@Jockey", horseData.Jockey ?? string.Empty);
                    command.Parameters.AddWithValue("@Apprentice", horseData.Apprentice ?? string.Empty);
                    command.Parameters.AddWithValue("@JockeyWeightClaim", horseData.JockeyWeightClaim);
                    command.Parameters.AddWithValue("@JockeyLast100HorseEarnings", horseData.JockeyLast100HorseEarnings);
                    command.Parameters.AddWithValue("@JockeyLast100AvgHorseEarnings", horseData.JockeyLast100AvgHorseEarnings);
                    command.Parameters.AddWithValue("@JockeyLast100Starts", horseData.JockeyLast100Starts);
                    command.Parameters.AddWithValue("@JockeyLast100Wins", horseData.JockeyLast100Wins);
                    command.Parameters.AddWithValue("@JockeyLast100StrikeRate", horseData.JockeyLast100StrikeRate);
                    command.Parameters.AddWithValue("@JockeyLast100ROI", horseData.JockeyLast100ROI);
                    command.Parameters.AddWithValue("@JockeyLast100Places", horseData.JockeyLast100Places);
                    command.Parameters.AddWithValue("@JockeyLast100PlaceStrikeRate", horseData.JockeyLast100PlaceStrikeRate);
                    command.Parameters.AddWithValue("@Jockey12MonthHorseEarnings", horseData.Jockey12MonthHorseEarnings);
                    command.Parameters.AddWithValue("@Jockey12MonthAvgHorseEarnings", horseData.Jockey12MonthAvgHorseEarnings);
                    command.Parameters.AddWithValue("@Jockey12MonthsStarts", horseData.Jockey12MonthsStarts);
                    command.Parameters.AddWithValue("@Jockey12MonthsWins", horseData.Jockey12MonthsWins);
                    command.Parameters.AddWithValue("@Jockey12MonthsStrikeRate", horseData.Jockey12MonthsStrikeRate);
                    command.Parameters.AddWithValue("@Jockey12MonthsROI", horseData.Jockey12MonthsROI);
                    command.Parameters.AddWithValue("@Jockey12MonthsPlaces", horseData.Jockey12MonthsPlaces);
                    command.Parameters.AddWithValue("@Jockey12MonthsPlaceStrikeRate", horseData.Jockey12MonthsPlaceStrikeRate);
                    command.Parameters.AddWithValue("@JockeyThisSeasonHorseEarnings", horseData.JockeyThisSeasonHorseEarnings);
                    command.Parameters.AddWithValue("@JockeyThisSeasonAvgHorseEarnings", horseData.JockeyThisSeasonAvgHorseEarnings);
                    command.Parameters.AddWithValue("@JockeyThisSeasonStarts", horseData.JockeyThisSeasonStarts);
                    command.Parameters.AddWithValue("@JockeyThisSeasonWins", horseData.JockeyThisSeasonWins);
                    command.Parameters.AddWithValue("@JockeyThisSeasonStrikeRate", horseData.JockeyThisSeasonStrikeRate);
                    command.Parameters.AddWithValue("@JockeyThisSeasonROI", horseData.JockeyThisSeasonROI);
                    command.Parameters.AddWithValue("@JockeyThisSeasonPlaces", horseData.JockeyThisSeasonPlaces);
                    command.Parameters.AddWithValue("@JockeyThisSeasonPlaceStrikeRate", horseData.JockeyThisSeasonPlaceStrikeRate);
                    command.Parameters.AddWithValue("@JockeyLastSeasonHorseEarnings", horseData.JockeyLastSeasonHorseEarnings);
                    command.Parameters.AddWithValue("@JockeyLastSeasonAvgHorseEarnings", horseData.JockeyLastSeasonAvgHorseEarnings);
                    command.Parameters.AddWithValue("@JockeyLastSeasonStarts", horseData.JockeyLastSeasonStarts);
                    command.Parameters.AddWithValue("@JockeyLastSeasonWins", horseData.JockeyLastSeasonWins);
                    command.Parameters.AddWithValue("@JockeyLastSeasonStrikeRate", horseData.JockeyLastSeasonStrikeRate);
                    command.Parameters.AddWithValue("@JockeyLastSeasonROI", horseData.JockeyLastSeasonROI);
                    command.Parameters.AddWithValue("@JockeyLastSeasonPlaces", horseData.JockeyLastSeasonPlaces);
                    command.Parameters.AddWithValue("@JockeyLastSeasonPlaceStrikeRate", horseData.JockeyLastSeasonPlaceStrikeRate);

                    // Trainer
                    command.Parameters.AddWithValue("@Trainer", horseData.Trainer ?? string.Empty);
                    command.Parameters.AddWithValue("@TrainerLast100HorseEarnings", horseData.TrainerLast100HorseEarnings);
                    command.Parameters.AddWithValue("@TrainerLast100AvgHorseEarnings", horseData.TrainerLast100AvgHorseEarnings);
                    command.Parameters.AddWithValue("@TrainerLast100Starts", horseData.TrainerLast100Starts);
                    command.Parameters.AddWithValue("@TrainerLast100Wins", horseData.TrainerLast100Wins);
                    command.Parameters.AddWithValue("@TrainerLast100StrikeRate", horseData.TrainerLast100StrikeRate);
                    command.Parameters.AddWithValue("@TrainerLast100ROI", horseData.TrainerLast100ROI);
                    command.Parameters.AddWithValue("@TrainerLast100Places", horseData.TrainerLast100Places);
                    command.Parameters.AddWithValue("@TrainerLast100PlaceStrikeRate", horseData.TrainerLast100PlaceStrikeRate);
                    command.Parameters.AddWithValue("@Trainer12MonthHorseEarnings", horseData.Trainer12MonthHorseEarnings);
                    command.Parameters.AddWithValue("@Trainer12MonthAvgHorseEarnings", horseData.Trainer12MonthAvgHorseEarnings);
                    command.Parameters.AddWithValue("@Trainer12MonthsStarts", horseData.Trainer12MonthsStarts);
                    command.Parameters.AddWithValue("@Trainer12MonthsWins", horseData.Trainer12MonthsWins);
                    command.Parameters.AddWithValue("@Trainer12MonthsStrikeRate", horseData.Trainer12MonthsStrikeRate);
                    command.Parameters.AddWithValue("@Trainer12MonthsROI", horseData.Trainer12MonthsROI);
                    command.Parameters.AddWithValue("@Trainer12MonthsPlaces", horseData.Trainer12MonthsPlaces);
                    command.Parameters.AddWithValue("@Trainer12MonthsPlaceStrikeRate", horseData.Trainer12MonthsPlaceStrikeRate);
                    command.Parameters.AddWithValue("@TrainerThisSeasonHorseEarnings", horseData.TrainerThisSeasonHorseEarnings);
                    command.Parameters.AddWithValue("@TrainerThisSeasonAvgHorseEarnings", horseData.TrainerThisSeasonAvgHorseEarnings);
                    command.Parameters.AddWithValue("@TrainerThisSeasonStarts", horseData.TrainerThisSeasonStarts);
                    command.Parameters.AddWithValue("@TrainerThisSeasonWins", horseData.TrainerThisSeasonWins);
                    command.Parameters.AddWithValue("@TrainerThisSeasonStrikeRate", horseData.TrainerThisSeasonStrikeRate);
                    command.Parameters.AddWithValue("@TrainerThisSeasonROI", horseData.TrainerThisSeasonROI);
                    command.Parameters.AddWithValue("@TrainerThisSeasonPlaces", horseData.TrainerThisSeasonPlaces);
                    command.Parameters.AddWithValue("@TrainerThisSeasonPlaceStrikeRate", horseData.TrainerThisSeasonPlaceStrikeRate);
                    command.Parameters.AddWithValue("@TrainerLastSeasonHorseEarnings", horseData.TrainerLastSeasonHorseEarnings);
                    command.Parameters.AddWithValue("@TrainerLastSeasonAvgHorseEarnings", horseData.TrainerLastSeasonAvgHorseEarnings);
                    command.Parameters.AddWithValue("@TrainerLastSeasonStarts", horseData.TrainerLastSeasonStarts);
                    command.Parameters.AddWithValue("@TrainerLastSeasonWins", horseData.TrainerLastSeasonWins);
                    command.Parameters.AddWithValue("@TrainerLastSeasonStrikeRate", horseData.TrainerLastSeasonStrikeRate);
                    command.Parameters.AddWithValue("@TrainerLastSeasonROI", horseData.TrainerLastSeasonROI);
                    command.Parameters.AddWithValue("@TrainerLastSeasonPlaces", horseData.TrainerLastSeasonPlaces);
                    command.Parameters.AddWithValue("@TrainerLastSeasonPlaceStrikeRate", horseData.TrainerLastSeasonPlaceStrikeRate);

                    // Informazioni ultima corsa
                    command.Parameters.AddWithValue("@LastStartFinishPosition", horseData.LastStartFinishPosition);
                    command.Parameters.AddWithValue("@LastStartMargin", horseData.LastStartMargin);
                    command.Parameters.AddWithValue("@LastStartDistance", horseData.LastStartDistance);
                    command.Parameters.AddWithValue("@LastStartDistanceChange", horseData.LastStartDistanceChange);
                    command.Parameters.AddWithValue("@LastStartPrizeMoney", horseData.LastStartPrizeMoney);

                    // URL e link
                    command.Parameters.AddWithValue("@FormGuideUrl", horseData.FormGuideUrl ?? string.Empty);
                    command.Parameters.AddWithValue("@HorseProfileUrl", horseData.HorseProfileUrl ?? string.Empty);
                    command.Parameters.AddWithValue("@JockeyProfileUrl", horseData.JockeyProfileUrl ?? string.Empty);
                    command.Parameters.AddWithValue("@TrainerProfileUrl", horseData.TrainerProfileUrl ?? string.Empty);

                    // Risultato finale
                    command.Parameters.AddWithValue("@FinishResult", horseData.FinishResult ?? string.Empty);

                    // Campi per timestamp
                    command.Parameters.AddWithValue("@Created", currentDateTime);
                    command.Parameters.AddWithValue("@Updated", currentDateTime);

                    command.ExecuteNonQuery();
                }
            }
            catch (Exception ex)
            {
                LogError($"l'upsert dei dati del cavallo {horseData.HorseName}", ex);
            }
        }
    }
}
