using System;
using System.Data;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace HorseRacingPredictor
{
    public partial class MainWindow : Window
    {
        private readonly Football.Main _footballManager;
        private HorseRacing.Main _racingManager;
        private DataTable _footballData;
        private DataTable _racingData;

        private const string DefaultRacingUser = "qi1mHOHPquDY9KNDASAeGipy";
        private const string DefaultRacingPass = "RXNFU1YX27R9rTnk8Vop8ZfH";

        public MainWindow()
        {
            InitializeComponent();
            _footballManager = new Football.Main();
            _racingManager = new HorseRacing.Main(DefaultRacingUser, DefaultRacingPass);
        }

        // ???????????????????? LIFECYCLE ????????????????????

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            dpFootball.SelectedDate = DateTime.Today;
            cmbDay.Items.Add("Oggi");
            cmbDay.Items.Add("Domani");
            cmbDay.SelectedIndex = 0;
            LoadSettings();
        }

        // ???????????????????? NAVIGATION ????????????????????

        private void ShowPage(string name)
        {
            // Guard against UI elements not being initialized (possible when called early)
            if (pageFootball != null) pageFootball.Visibility = name == "football" ? Visibility.Visible : Visibility.Collapsed;
            if (pageRacing != null)   pageRacing.Visibility   = name == "racing"   ? Visibility.Visible : Visibility.Collapsed;
            if (pageSettings != null) pageSettings.Visibility = name == "settings" ? Visibility.Visible : Visibility.Collapsed;
            if (pageInfo != null)     pageInfo.Visibility     = name == "info"     ? Visibility.Visible : Visibility.Collapsed;

            // Update title if available
            if (lblTitle != null)
            {
                switch (name)
                {
                    case "football": lblTitle.Text = "Calcio"; break;
                    case "racing":   lblTitle.Text = "Corse Cavalli"; break;
                    case "settings": lblTitle.Text = "Impostazioni"; break;
                    case "info":     lblTitle.Text = "Informazioni"; break;
                }
            }
        }

        private void navFootball_Checked(object sender, RoutedEventArgs e) => ShowPage("football");
        private void navRacing_Checked(object sender, RoutedEventArgs e)   => ShowPage("racing");
        private void navSettings_Checked(object sender, RoutedEventArgs e) => ShowPage("settings");
        private void navInfo_Checked(object sender, RoutedEventArgs e)     => ShowPage("info");

        // ???????????????????? FOOTBALL ????????????????????

        private async void btnDownloadFb_Click(object sender, RoutedEventArgs e)
        {
            var date = dpFootball.SelectedDate ?? DateTime.Today;
            await DownloadFootballAsync(date);
        }

        private async Task DownloadFootballAsync(DateTime date)
        {
            try
            {
                pbFootball.Value = 0;
                lblStatusFb.Text = "Scaricamento elenco partite…";
                btnDownloadFb.IsEnabled = false;
                dpFootball.IsEnabled = false;
                btnExportFbCsv.IsEnabled = false;

                var progress = new Progress<int>(v => pbFootball.Value = v);
                var status   = new Progress<string>(s => lblStatusFb.Text = s);

                var table = await Task.Run(() =>
                    _footballManager.GetTodayFixtures(date, progress, status));

                _footballData = table;
                dgFootball.ItemsSource = _footballData?.DefaultView;

                if (_footballData != null && _footballData.Rows.Count > 0)
                {
                    btnExportFbCsv.IsEnabled = true;
                    lblStatusFb.Text = $"Scaricate {_footballData.Rows.Count} partite";
                }
                else
                {
                    lblStatusFb.Text = "Nessuna partita trovata per la data selezionata";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Errore durante lo scaricamento:\n{ex.Message}",
                    "Errore", MessageBoxButton.OK, MessageBoxImage.Error);
                lblStatusFb.Text = "Errore nello scaricamento";
                pbFootball.Value = 0;
            }
            finally
            {
                btnDownloadFb.IsEnabled = true;
                dpFootball.IsEnabled = true;
            }
        }

        private void btnExportFbCsv_Click(object sender, RoutedEventArgs e)
        {
            ExportToCsv(_footballData, txtFbExportPath.Text,
                $"Partite_{dpFootball.SelectedDate:yyyy-MM-dd}.csv",
                s => lblStatusFb.Text = s);
        }

        // ???????????????????? HORSE RACING ????????????????????

        private async void btnDownloadRc_Click(object sender, RoutedEventArgs e)
        {
            await DownloadRacecardsAsync();
        }

        private async Task DownloadRacecardsAsync()
        {
            try
            {
                pbRacing.Value = 0;
                lblStatusRc.Text = "Scaricamento racecard…";
                btnDownloadRc.IsEnabled = false;
                cmbDay.IsEnabled = false;
                btnExportRcCsv.IsEnabled = false;

                var progress = new Progress<int>(v => pbRacing.Value = v);
                var status   = new Progress<string>(s => lblStatusRc.Text = s);

                string day = cmbDay.SelectedIndex == 0 ? "today" : "tomorrow";

                var table = await Task.Run(() =>
                    _racingManager.GetRacecards(day, progress, status));

                _racingData = table;
                dgRacing.ItemsSource = _racingData?.DefaultView;

                if (_racingData != null && _racingData.Rows.Count > 0)
                {
                    btnExportRcCsv.IsEnabled = true;
                    lblStatusRc.Text = $"Trovate {_racingData.Rows.Count} corse";
                }
                else
                {
                    lblStatusRc.Text = "Nessuna corsa trovata";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Errore durante lo scaricamento:\n{ex.Message}",
                    "Errore", MessageBoxButton.OK, MessageBoxImage.Error);
                lblStatusRc.Text = "Errore nello scaricamento";
                pbRacing.Value = 0;
            }
            finally
            {
                btnDownloadRc.IsEnabled = true;
                cmbDay.IsEnabled = true;
            }
        }

        private void btnExportRcCsv_Click(object sender, RoutedEventArgs e)
        {
            string dayLabel = cmbDay.SelectedIndex == 0 ? "oggi" : "domani";
            ExportToCsv(_racingData, txtRcExportPath.Text,
                $"Corse_{dayLabel}_{DateTime.Now:yyyy-MM-dd}.csv",
                s => lblStatusRc.Text = s);
        }

        // ???????????????????? SHARED CSV EXPORT ????????????????????

        private void ExportToCsv(DataTable data, string folder, string defaultName, Action<string> setStatus)
        {
            if (data == null || data.Rows.Count == 0)
            {
                MessageBox.Show("Nessun dato da esportare.",
                    "Nessun dato", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            string filePath;
            if (!string.IsNullOrEmpty(folder) && Directory.Exists(folder))
            {
                filePath = Path.Combine(folder, defaultName);
            }
            else
            {
                var dlg = new Microsoft.Win32.SaveFileDialog
                {
                    Filter = "File CSV|*.csv",
                    FileName = defaultName
                };
                if (dlg.ShowDialog() != true) return;
                filePath = dlg.FileName;
            }

            try
            {
                var sb = new StringBuilder();
                var headers = new string[data.Columns.Count];
                for (int i = 0; i < data.Columns.Count; i++)
                    headers[i] = data.Columns[i].ColumnName;
                sb.AppendLine(string.Join(";", headers));

                foreach (DataRow row in data.Rows)
                {
                    var vals = new string[data.Columns.Count];
                    for (int i = 0; i < data.Columns.Count; i++)
                    {
                        var v = row[i]?.ToString() ?? "";
                        if (v.Contains(";") || v.Contains("\""))
                            v = "\"" + v.Replace("\"", "\"\"") + "\"";
                        vals[i] = v;
                    }
                    sb.AppendLine(string.Join(";", vals));
                }

                File.WriteAllText(filePath, sb.ToString(), Encoding.UTF8);
                setStatus?.Invoke($"CSV esportato: {Path.GetFileName(filePath)}");
                MessageBox.Show($"Esportate {data.Rows.Count} righe in:\n{filePath}",
                    "Esportazione completata", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Errore durante l'esportazione CSV:\n{ex.Message}",
                    "Errore", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        // ???????????????????? FOLDER BROWSE ????????????????????

        private void btnBrowseFbExport_Click(object sender, RoutedEventArgs e)
        {
            var path = BrowseFolder("Seleziona la cartella di esportazione per Calcio");
            if (path != null) txtFbExportPath.Text = path;
        }

        private void btnBrowseRcExport_Click(object sender, RoutedEventArgs e)
        {
            var path = BrowseFolder("Seleziona la cartella di esportazione per Corse Cavalli");
            if (path != null) txtRcExportPath.Text = path;
        }

        private static string BrowseFolder(string description)
        {
            using (var dlg = new System.Windows.Forms.FolderBrowserDialog())
            {
                dlg.Description = description;
                if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    return dlg.SelectedPath;
            }
            return null;
        }

        // ???????????????????? SETTINGS ????????????????????

        private string SettingsFilePath =>
            Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "settings.ini");

        private void LoadSettings()
        {
            try
            {
                txtRacingUser.Text = DefaultRacingUser;
                txtRacingPass.Password = DefaultRacingPass;

                if (!File.Exists(SettingsFilePath)) return;
                foreach (var line in File.ReadAllLines(SettingsFilePath))
                {
                    var idx = line.IndexOf('=');
                    if (idx < 0) continue;
                    var key = line.Substring(0, idx).Trim();
                    var val = line.Substring(idx + 1).Trim();

                    if (key == "ApiKey")           txtApiKey.Text = val;
                    else if (key == "FbExportPath") txtFbExportPath.Text = val;
                    else if (key == "RcExportPath") txtRcExportPath.Text = val;
                    else if (key == "RacingUser")  txtRacingUser.Text = val;
                    else if (key == "RacingPass")  txtRacingPass.Password = val;
                }

                _racingManager.UpdateCredentials(txtRacingUser.Text, txtRacingPass.Password);
            }
            catch { }
        }

        private void btnSaveSettings_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var sb = new StringBuilder();
                sb.AppendLine($"ApiKey={txtApiKey.Text.Trim()}");
                sb.AppendLine($"FbExportPath={txtFbExportPath.Text.Trim()}");
                sb.AppendLine($"RcExportPath={txtRcExportPath.Text.Trim()}");
                sb.AppendLine($"RacingUser={txtRacingUser.Text.Trim()}");
                sb.AppendLine($"RacingPass={txtRacingPass.Password.Trim()}");
                File.WriteAllText(SettingsFilePath, sb.ToString(), Encoding.UTF8);

                _racingManager.UpdateCredentials(txtRacingUser.Text.Trim(), txtRacingPass.Password.Trim());

                MessageBox.Show("Impostazioni salvate con successo.",
                    "Salvato", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Errore nel salvataggio:\n{ex.Message}",
                    "Errore", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
    }
}
