using apiwrappercli;
using apiwrappercli.listener;
using apiwrappercli.poco.margincheck;
using apiwrappercli.spmessage.margincheck;
using SPTrader;
using SPTrader.BusinessLayer;
using SPTrader.Common;
using SPTrader.Interface;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;

namespace SPTrader.Views
{
    /// <summary>
    /// Interaction logic for MarginCheckWindow.xaml
    /// </summary>
    public partial class MarginCheckWindow : SPBindableWindowChrome, MarginDataListener, IWindowDesktopConfig, IDataGridSetting
    {
        private IndexedObservableCollectionEx<SPAeMarginData, string> aeMarginModel = new IndexedObservableCollectionEx<SPAeMarginData, string>();
        private IndexedObservableCollectionEx<SPAccountMarginData, string> accountMarginModel = new IndexedObservableCollectionEx<SPAccountMarginData, string>();

        private DatagridSettingWindow dgs_aem_win = null;
        private DatagridSettingWindow dgs_acm_win = null;
        private SPBindableWindowChrome parentWin = null;
        private int tabId = 0;
        private string activeAeCode = string.Empty;

        private double tot_acc_margin = 0.0;
        
        public MarginCheckWindow()
        {
            InitializeComponent();
            DataContext = this;
            DesktopSetting.Instance.Add(windowId, winName);

            dgs_aem_win = new DatagridSettingWindow(aeMarginModel.GetType());
            dgs_acm_win = new DatagridSettingWindow(accountMarginModel.GetType());
        }

        public MarginCheckWindow(string winId)
        {
            InitializeComponent();
            DataContext = this;
            windowId = winId;

            dgs_aem_win = new DatagridSettingWindow(aeMarginModel.GetType());
            dgs_acm_win = new DatagridSettingWindow(accountMarginModel.GetType());

            LoadSavedContent();
        }

        public void InitGridMetaSetting(SPBindableWindowChrome win, string windowId, int ctrlId, int tabId)
        {
            parentWin = win;
            this.windowId = windowId;
            this.tabId = tabId;
        }

        public void OnLoaded(object sender, RoutedEventArgs e)
        {
            ea.GetEvent<SwitchLanguageEvent>().Subscribe(OnLanguageChanged);

            aeMarginListView.DataContext = aeMarginModel;
            accountMarginListView.DataContext = accountMarginModel;

            apiProxy.MarginDataService.AddListener(this);

            List<SPAeMarginData> dataList = apiProxy.MarginDataService.GetAeMarginDataList();
            RefreshAeMarginDataList(dataList);

            dgs_aem_win.SetDataGrid(aeMarginListView);
            dgs_acm_win.SetDataGrid(accountMarginListView);

            LoadSavedTabMetaData();
            OnLanguageChanged(SPGlobal.GetLanguage());
        }

        public void LoadSavedTabMetaData()
        {
            LoadSavedMetaData(dgs_aem_win, aeMarginListView, 0, aeMarginModel.GetType());
            LoadSavedMetaData(dgs_acm_win, accountMarginListView, 1, accountMarginModel.GetType());
        }

        private void LoadSavedMetaData(DatagridSettingWindow dgs_win, DataGrid grid, int ctrlId, Type type)
        {
            var dt = SQLiteDataGridSetting.Instance.SelectTableRecord(windowId, ctrlId, tabId);

            var result = dt.AsEnumerable();
            int fnum = 0;
            string data = string.Empty;

            foreach (var res in result)
            {
                var dd = res.ItemArray;

                // tab headers
                fnum = Convert.ToInt32(dd[4]);
                data = Convert.ToString(dd[5]);
                break;
            }

            if (data != string.Empty)
            {
                dgs_win.SetDataGrid(grid);
                dgs_win.SetDataGrid(data, fnum);
            }
        }

        public void OnUnloaded(object sender, RoutedEventArgs e)
        {
            if (!DesktopSetting.Instance.IsLoadingPreviousDB && !DesktopSetting.Instance.IsLoggingOut)
            {
                DesktopSetting.Instance.Remove(windowId);
                SQLiteMarginCheck.Instance.DeleteRecord(windowId);
                SQLiteDataGridSetting.Instance.DeleteRecord(windowId);
            }
            apiProxy.MarginDataService.RemoveListener(this);
            apiProxy.MarginDataService.StopMarginMonitoring();

            ea.GetEvent<RefreshDesktopSubWindowEvent>().Publish();
        }

        public void OnClosed(object sender, EventArgs e)
        {
            SaveDesktop();
            SaveDataGridSettting();
        }

        public override void SaveDesktop()
        {
            int x = Convert.ToInt32(this.Left);
            int y = Convert.ToInt32(this.Top);
            int h = Convert.ToInt32(this.Height);
            int w = Convert.ToInt32(this.Width);

            SQLiteMarginCheck.Instance.InsertOrUpdateRecord(windowId, x, y, h, w, activeAeCode);
        }

        public void LoadSavedContent()
        {
            var dt = SQLiteMarginCheck.Instance.SelectTableRecord(windowId);
            var result = dt.AsEnumerable();
            int x = 0, y = 0, h = 0, w = 0;

            foreach (var res in result)
            {
                var dd = res.ItemArray;

                x = Convert.ToInt32(dd[1]);
                y = Convert.ToInt32(dd[2]);
                h = Convert.ToInt32(dd[3]);
                w = Convert.ToInt32(dd[4]);
                activeAeCode = Convert.ToString(dd[5]);
                break;
            }

            this.Left = x;
            this.Top = y;
            this.Height = h;
            this.Width = w;

            //apiProxy.MarginDataService.SelectAe(activeAeCode);
        }

        private void OnLanguageChanged(LanguageEnum lang)
        {
            Title = LanguageSetting.GetLanguageValue("ACCMGN_CAPTION");
            ea.GetEvent<RefreshDesktopSubWindowEvent>().Publish();
        }

        private void RefreshAeMarginDataList(List<SPAeMarginData> dataList)
        {
            aeMarginModel.Clear();

            double tot_call = 0.0;

            foreach (SPAeMarginData data in dataList) {
                aeMarginModel.SaveOrUpdate(data, data.AECode);
                tot_call += data.MarginCall;
            }

            if (tot_call > 0)
                imgMargin.Source = CommonUtil.GetImage("/Resource/Assets/redicon3x.png");
            else
                imgMargin.Source = CommonUtil.GetImage("/Resource/Assets/greenicon.png");

            //if (dataList.Count > 0)
            //{
            //    //apiProxy.MarginDataService.
            //}
        }

        private void RefreshAcountMarginInfo(SPAccountMarginData marginData)
        {
            var tot_call = marginData.MarginCall;
            if (tot_call > 0)
                tot_acc_margin += tot_call;

            if (tot_acc_margin > 0)
                imgAccount.Source = CommonUtil.GetImage("/Resource/Assets/redicon3x.png");
            else
                imgAccount.Source = CommonUtil.GetImage("/Resource/Assets/greenicon.png");
        }

        public void OnLoginReply(LoginMcServerReplyMessage message)
        {
        }

        public void OnLogoutReply(LogoutMcServerReplyMessage message)
        {
        }

        public void OnAccountMarginReply(AccountMarginReplyMessage message)
        {
            if (aeMarginModel.SelectedItem == null)
                return;

            if (aeMarginModel.SelectedItem != null &&
                !String.Equals(message.marginData.Mkt.AEId, aeMarginModel.SelectedItem.AECode))
            {
                return;
            }

            accountMarginListView.Dispatcher.InvokeAsync((Action)delegate ()
            {
                accountMarginModel.SaveOrUpdate(message.marginData, message.marginData.AccNo);

                // change icon image
                RefreshAcountMarginInfo(message.marginData);
            });
        }

        public void OnAeMarginReply(AeMarginReplyMessage message)
        {
            aeMarginListView.Dispatcher.InvokeAsync((Action)delegate ()
            {
                aeMarginModel.SaveOrUpdate(message.marginData, message.marginData.AECode);
            });
        }

        public void OnAccountListPush(AccountListPushMessage message)
        {
            accountMarginListView.Dispatcher.InvokeAsync((Action)delegate ()
            {
                accountMarginModel.SaveOrUpdate(message.marginData, message.marginData.AccNo);
            });
        }

        public void OnAeCodeListPush(AeCodeListPushMessage message)
        {
        }

        public void OnMarginAlertPush(MarginAlertPushMessage message)
        {
        }

        public void OnMarginCallListPush(MarginCallListPushMessage message)
        {
        }

        private void aeMarginListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            tot_acc_margin = 0.0;

            var item = aeMarginListView.SelectedItem;
            if (item != null && item is SPAeMarginData)
            {
                accountMarginModel.Clear();

                var marginData = (SPAeMarginData)item;
                apiProxy.MarginDataService.SelectAe(marginData.AECode);
                activeAeCode = marginData.AECode;

                aeMarginModel.SelectedItem = marginData;
            }
        }

        private void accountMarginSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var item = accountMarginListView.SelectedItem;
            if (item != null && item is SPAccountMarginData)
            {
                var marginData = (SPAccountMarginData)item;
                accNo.Text = marginData.AccNo;
            }
        }

        private void accountMarginDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var item = accountMarginListView.SelectedItem;
            if (item != null && item is SPAccountMarginData)
            {
                var marginData = (SPAccountMarginData)item;
                ea.GetEvent<SwitchAccountEvent>().Publish(marginData.AccNo);
            }
        }

        private void OnAccNo_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                ea.GetEvent<SwitchAccountEvent>().Publish(accNo.Text);
            }
        }

        private void Access_Click(object sender, RoutedEventArgs e)
        {
            ea.GetEvent<SwitchAccountEvent>().Publish(accNo.Text);
        }

        private void Release_Click(object sender, RoutedEventArgs e)
        {
            ea.GetEvent<SwitchAccountEvent>().Publish(string.Empty);
        }

        public void OpenDataGridSetting()
        {
        }

        public void OpenDataGridSetting(DatagridSettingWindow dgs_win, DataGrid grid)
        {
            dgs_win.OnResultOk = new Action(SaveDataGridSettting);
            dgs_win.PopulateSetting(grid);
            dgs_win.ShowInTaskbar = false;
            dgs_win.Owner = parentWin;
            dgs_win.ShowDialog();
        }

        public void SaveDataGridSettting()
        {
            SaveDataGridSettting(dgs_aem_win, aeMarginListView, 0);
            SaveDataGridSettting(dgs_acm_win, accountMarginListView, 1);
        }

        public void SaveDataGridSettting(DatagridSettingWindow dgs_win, DataGrid grid, int ctrlId)
        {
            var data = dgs_win.GetEncodedDataGrid(grid);
            var froze_count = grid.FrozenColumnCount;
            SQLiteDataGridSetting.Instance.InsertOrUpdateRecord(windowId, ctrlId, tabId, froze_count, 0, data);
        }

        public void OnDataGridMouseRight_Click(object sender, MouseButtonEventArgs e)
        {
            var dep = (DependencyObject)e.OriginalSource;

            // iteratively traverse the visual tree
            while ((dep != null) &&
                    !(dep is DataGridCell) &&
                    !(dep is DataGridColumnHeader))
            {
                dep = VisualTreeHelper.GetParent(dep);
            }

            if (dep == null)
                return;

            if (dep is DataGridColumnHeader)
            {
                var s = sender as DataGrid;

                if (s.Name.StartsWith("ae"))
                {
                    OpenDataGridSetting(dgs_aem_win, aeMarginListView);
                }
                else if (s.Name.StartsWith("account"))
                {
                    OpenDataGridSetting(dgs_acm_win, accountMarginListView);
                }
            }
        }

        private void OnReloadAcc_Click(object sender, RoutedEventArgs e)
        {
            var acc = accountMarginListView.SelectedItem as SPAccountMarginData;
            if (acc == null) return;

            var title = LanguageSetting.GetLanguageValue("ACCMGN_RELOADACC");
            var cap = LanguageSetting.GetLanguageValue("ACCMGN_RELOADACC");
            var caption = string.Format($"{cap} [{acc.AccNo}]?");

            var sb = new SimpleMessageBox(title, caption, SimpleMessageBoxMode.YESNO);
            var b = sb.ShowDialog();

            if (b == true)
            {
                var req = LanguageSetting.GetLanguageValue("ACCMGN_REQSENT");
                caption = string.Format($"{cap} [{acc.AccNo}] {req}!");

                apiProxy.AccountDataService.SwitchAccount(acc.AccNo);

                sb = new SimpleMessageBox(title, caption, SimpleMessageBoxMode.OK);
                sb.ShowDialog();
            }
        }

        private void OnSidePanelChanged(object sender, RoutedEventArgs e)
        {
            if (tbSidePanel.IsChecked == true)
            {
                cdSide1.Width = new GridLength(0);
                cdSide2.Width = new GridLength(0);
            }
            else
            {
                cdSide1.Width = new GridLength(260);
                cdSide2.Width = new GridLength(5);
            }
        }
    }
}