using InitializerModel;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using PhihongEv.Lib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ConfigEditor.SubPage.EvseConfig
{
    /// <summary>
    /// EvseConfigPanel.xaml 的互動邏輯
    /// </summary>
    public partial class EvseConfigPanel : UserControl
    {
        public EvseConfigPanel()
        {
            InitializeComponent();

            uxEvseModelNameList.SelectionChanged += UxEvseModelNameList_SelectionChanged;
        }

        internal void Reset()
        {
            var modelList = EvseSettingConfig.GetModelList();
            uxEvseModelNameList.SelectedIndex = -1;
            uxEvseModelNameList.ItemsSource = modelList;

            uxButtonTestMode.ItemsSource = Enum.GetValues(typeof(ButtonTestModeType)).Cast<ButtonTestModeType>();

            uxFrimwareStackPanel.Children.Clear();

            this.DataContext = new EvseSettingConfigModel();
        }

        private void UxEvseModelNameList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ReloadEvseConfig();
        }

        private void uxSaveConfigBtn_Click(object sender, RoutedEventArgs e)
        {
            if (!CheckSetting())
            {
                return;
            }
            SaveCurrent();
        }

        private void uxNewConfigBtn_Click(object sender, RoutedEventArgs e)
        {
            CreateNewConfig();
        }

        private void ReloadEvseConfig()
        {
            var modelName = uxEvseModelNameList.SelectedItem as string;
            if (string.IsNullOrEmpty(modelName))
            {
                //this.DataContext = new EvseSettingConfigModel();
                Reset();
                return;
            }

            var loadResult = EvseSettingConfig.TryLoad(modelName);

            EvseSettingConfigModel config = null;

            if (loadResult != null && loadResult.Error == EvseSettingConfigLoadError.LoadConfigModelInitNotfound)
            {
                config = new EvseSettingConfigModel() {
                    ModelName = modelName
                };
            }

            if (loadResult != null && loadResult.Error == EvseSettingConfigLoadError.None)
            {
                config = loadResult.Result;
            }

            if (config is null)
            {
                MessageBox.Show($"load failed:{loadResult.Error}");
                return;
            }

            //EvseSettingConfigModel config = loadResult.Result;
            //string folderPath = loadResult.ConfigFolderPath;
            string folderPath = EvseSettingConfig.GetModelFolder(modelName);
            SystemID.TryLooseParse(modelName, out var systemID);

            this.DataContext = config;

            uxFirstTelcom.Visibility = systemID.ModelName.GetTelecomCnt() > 0 ? Visibility.Visible : Visibility.Collapsed;
            uxSecondTelcom.Visibility = systemID.ModelName.GetTelecomCnt() > 1 ? Visibility.Visible : Visibility.Collapsed;

            var groupedFrimware = config.FirmwareUpdateList is null ? new List<IGrouping<int, FirmwareUpdateModel>>() : config.FirmwareUpdateList.GroupBy(x => EvseVersion.GetVersionIndex(x.Module));
            groupedFrimware = groupedFrimware.OrderBy(x => x.Key);
            uxFrimwareStackPanel.Children.Clear();

            foreach (var firmwareGroup in groupedFrimware)
            {
                FirmwareVersionPanel firmwarePanel = CreateFirmwarePanel(folderPath, firmwareGroup.Key, firmwareGroup.ToList());

                uxFrimwareStackPanel.Children.Add(new Rectangle() { Height = 10 });
                uxFrimwareStackPanel.Children.Add(firmwarePanel);
            }

            if (!groupedFrimware.Select(x => x.Key).Contains(0))
            {
                FirmwareVersionPanel firmwarePanel = CreateFirmwarePanel(folderPath, 0, new List<FirmwareUpdateModel>());
                uxFrimwareStackPanel.Children.Add(new Rectangle() { Height = 10 });
                uxFrimwareStackPanel.Children.Add(firmwarePanel);
            }
        }

        private void ClearUi()
        {
            //uxIpAddress.Text = string.Empty;
            uxFirstTelcom.Visibility = Visibility.Collapsed;
            uxSecondTelcom.Visibility = Visibility.Collapsed;
        }

        private FirmwareVersionPanel CreateFirmwarePanel(string folderPath, int key, List<FirmwareUpdateModel> firmwareUpdateModels)
        {
            var toReturn = new FirmwareVersionPanel();
            toReturn.Index = key;
            toReturn.FileFolderPath = folderPath;
            toReturn.VersionPairs = firmwareUpdateModels;
            //{ Index = key , VersionPairs = firmwareUpdateModels, FileFolderPath = folderPath };
            return toReturn;
        }

        private bool CheckSetting()
        {
            var modelNameString = uxEvseModelNameList.SelectedItem as string;
            EvseSettingConfigModel config = this.DataContext as EvseSettingConfigModel;

            if (string.IsNullOrEmpty(modelNameString) ||
                config == null)
            {
                MessageBox.Show("load model failed");
                return false;
            }

            var systemidParse = SystemID.TryLooseParse(modelNameString, out var systemID);
            if (!systemidParse)
            {
                MessageBox.Show("model name error");
                return false;
            }
            var modelName = systemID.ModelName;

            if (modelName.GetTelecomCnt() > 0 && string.IsNullOrEmpty(config.FourGenModuleVersion))
            {
                MessageBox.Show("ModuleVersion should not be empty");
                return false;
            }

            if (modelName.GetTelecomCnt() > 1 && string.IsNullOrEmpty(config.SubFourGenModuleVersion))
            {
                MessageBox.Show("ModuleVersion should not be empty");
                return false;
            }

            if (config.IsSimInsert)
            {
                if (string.IsNullOrEmpty(config.SimICCID) ||
                    string.IsNullOrEmpty(config.SimIMSI))
                {
                    MessageBox.Show("ICCID and IMSI should not be empty");
                    return false;
                }
            }

            if (config.IsSubSimInsert)
            {
                if (string.IsNullOrEmpty(config.SubSimICCID) ||
                    string.IsNullOrEmpty(config.SubSimIMSI))
                {
                    MessageBox.Show("Sub ICCID and IMSI should not be empty");
                    return false;
                }
            }
            return true;
        }

        private void SaveCurrent()
        {
            var modelName = uxEvseModelNameList.SelectedItem as string;

            EvseSettingConfigModel config = this.DataContext as EvseSettingConfigModel;

            var firmwareUpdateList = LoadFirmwareUpdateListFromPanel();
            CopyAndRenameFirmwareUpdateList(config.ModelName, firmwareUpdateList);
            config.FirmwareUpdateList = firmwareUpdateList;

            //var test = JsonConvert.SerializeObject(config);
            File.WriteAllText(
                EvseSettingConfig.GetModelIniPath(config.ModelName),
                JsonConvert.SerializeObject(
                    config,
                    Formatting.Indented,
                    new StringEnumConverter()
                    ));

            Reset();
        }

        private List<FirmwareUpdateModel> LoadFirmwareUpdateListFromPanel()
        {
            var toReturn = new List<FirmwareUpdateModel>();

            foreach (var uiPanel in uxFrimwareStackPanel.Children)
            {
                FirmwareVersionPanel firmwareVersionPanel = uiPanel as FirmwareVersionPanel;
                if (firmwareVersionPanel is null)
                {
                    continue;
                }
                toReturn.AddRange(firmwareVersionPanel.VersionPairs);
            }

            return toReturn;
        }

        private void CopyAndRenameFirmwareUpdateList(string modelName, List<FirmwareUpdateModel> firmwareUpdateList)
        {
            if (firmwareUpdateList == null)
            {
                return;
            }
            var modelPath = EvseSettingConfig.GetModelFolder(modelName);

            foreach (var model in firmwareUpdateList)
            {
                if (string.IsNullOrEmpty(model.FirmwareFileName))
                {
                    continue;
                }

                var firmwarePath = System.IO.Path.GetDirectoryName(model.FirmwareFileName);
                var firmwareName = System.IO.Path.GetFileName(model.FirmwareFileName);

                if (firmwarePath != modelPath)
                {
                    //Copy
                    var copyToPathFileName = System.IO.Path.Combine(modelPath, firmwareName);
                    if (File.Exists(copyToPathFileName))
                    {
                        File.Delete(copyToPathFileName);
                    }
                    File.Copy(model.FirmwareFileName, copyToPathFileName);
                }

                model.FirmwareFileName = firmwareName;
            }
        }

        private void CreateNewConfig()
        {
            var dlg = new NewModelNameDlg();
            dlg.Owner = MainWindow.Instance;
            dlg.ShowDialog();

            if (dlg.DialogResult != true)
            {
                return;
            }

            var modelName = dlg.ModelName;
            var modelFolderPath = EvseSettingConfig.GetModelFolder(modelName);
            var modelIniPath = EvseSettingConfig.GetModelIniPath(modelName);

            if (!Directory.Exists(modelFolderPath))
            {
                Directory.CreateDirectory(modelFolderPath);
            }

            var initModelSetting = new EvseSettingConfigModel() { ModelName = modelName };
            File.WriteAllText(
                modelIniPath,
                JsonConvert.SerializeObject(
                    initModelSetting,
                    Formatting.Indented,
                    new StringEnumConverter()
                    ));

            Reset();
        }

        private void AddDispenser_Click(object sender, RoutedEventArgs e)
        {
            List<int> createdFrimwareIndex = new List<int>();
            foreach (var uiElement in uxFrimwareStackPanel.Children)
            {
                FirmwareVersionPanel firmwarePanel = uiElement as FirmwareVersionPanel;
                if (firmwarePanel is null)
                {
                    continue;
                }

                createdFrimwareIndex.Add(firmwarePanel.Index);

                //FirmwareVersionPanel firmwarePanel = CreateFirmwarePanel(folderPath, firmwareGroup.Key, firmwareGroup.ToList());

                //uxFrimwareStackPanel.Children.Add(new Rectangle() { Height = 10 });
                //uxFrimwareStackPanel.Children.Add(firmwarePanel);
            }

            int toCreateIndex = 0;
            while (createdFrimwareIndex.Contains(toCreateIndex))
            {
                toCreateIndex++;
            }

            var modelName = uxEvseModelNameList.SelectedItem as string;
            var folderPath = EvseSettingConfig.GetModelFolder(modelName);

            FirmwareVersionPanel createdFirmwarePanel = CreateFirmwarePanel(folderPath, toCreateIndex, new List<FirmwareUpdateModel>());
            uxFrimwareStackPanel.Children.Add(new Rectangle() { Height = 10 });
            uxFrimwareStackPanel.Children.Add(createdFirmwarePanel);
        }
    }
}