using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net;
using System.Security;
using System.Windows;
using Ecng.Common;
using Ecng.Xaml;
using MoreLinq;
using StockSharp.Algo;
using StockSharp.Algo.Strategies;
using StockSharp.Algo.Testing;
using StockSharp.BusinessEntities;
using StockSharp.Logging;
using StockSharp.Messages;
using StockSharp.Quik;
using StockSharp.Quik.Lua;

namespace TestBag02
{
    public partial class MainWindow : Window
    {
        static RealTimeEmulationTrader<IMessageAdapter> _connector;
        //private readonly QuikTrader _connector;
        private Portfolio _portfolio;
        private Strategy _strategy;
        private Security _security, _ri, _si, _mi;

        private LogManager _logManager;

        private readonly TimeSpan _timeError = TimeSpan.FromSeconds(3); // погрешность синхронизации локального и биржевого времени

        public MainWindow()
        {
            InitializeComponent();

            _logManager = new LogManager();
            _logManager.Listeners.Add(new FileLogListener("log.log") { LogDirectory = "Logs" });

            //_connector = new QuikTrader(QuikTerminal.GetDefaultPath());

            InitDemoConnect();


            _connector.Connected += () =>
            {
                Console.WriteLine(@"Соединение установлено! Синхронизация !!!");

                // выводим текущее локальное время
                Console.WriteLine(TimeHelper.Now);

                // синхронизируем локальное время с атомными часами
                TimeHelper.SyncMarketTime(10000);

                // выводим синхронизированное текущее локальное время
                Console.WriteLine(TimeHelper.Now);
            };

            _connector.Disconnected += () =>
            {
                Console.WriteLine(@"Соединение разорвано!");
            };

            _connector.NewPortfolios += portfolios =>
            {
                portfolios.ForEach(portfolio =>
                {
                    Console.WriteLine(@"Получен портфель: {0}", portfolio.Name);

                    _connector.RegisterPortfolio(portfolio);

                    if (portfolio.Name == "Симулятор") _portfolio = portfolio;
                });
            };

            _connector.NewSecurities += _connector_NewSecurities;
            

            _connector.NewTrade += (trade) => this.GuiAsync(() =>
            {
                // вывод в окно времени
                if (TimeHelper.Now - trade.Time > _timeError)
                {
                    //tbTime.Text = "Загрузка "+trade.Time;
                }
                else
                {
                    tbTime.Text = trade.Time.TimeOfDay.ToString();
                }
            });

            _connector.Connect();
        }

        private void _connector_NewSecurities(IEnumerable<Security> securities)
        {
            securities.ForEach(s =>
            {
                if (s.Id == "MICEXINDEXCF@INDX")
                {
                    Registracija(s);
                    _mi = s;
                }
                if (s.Id == "SIM7@FORTS")
                {
                    Registracija(s);
                    _si = s;
                }
                if (s.Id == "RIM7@FORTS")
                {
                    Registracija(s);
                    _ri = s;
                    _security = s;
                }
            });
        }

        private void Registracija(Security security)
        {
            //_connector.RegisterMarketDepth(security);
            _connector.RegisterSecurity(security);
            _connector.RegisterTrades(security);
            Console.WriteLine(@"{0} - зарегестрирован, все ок", security);
        }

        private void InitDemoConnect()
        {
            BasketMessageAdapter realAdapter = new StockSharp.Algo.BasketMessageAdapter(new MillisecondIncrementalIdGenerator());

            // Создаем адаптер вручную
            realAdapter.AssociatedBoardCode = "ALL";
            realAdapter.LogLevel = LogLevels.Inherit;

            realAdapter.InnerAdapters.Add(new LuaFixMarketDataMessageAdapter(realAdapter.TransactionIdGenerator)
            {
                Dialect = StockSharp.Fix.FixDialects.Default,
                SenderCompId = "quik",
                TargetCompId = "StockSharpMD",
                Login = "quik",
                Password = "quik".To<SecureString>(),
                Address = "localhost:5001".To<EndPoint>(),
                RequestAllPortfolios = false,
                RequestAllSecurities = true,
                IsResetCounter = true,
                ReadTimeout = TimeSpan.Zero,
                WriteTimeout = TimeSpan.Zero,
                HeartbeatInterval = TimeSpan.Zero,
                SupportedMessages =
                    new MessageTypes[]
                    {MessageTypes.MarketData, MessageTypes.SecurityLookup, MessageTypes.ChangePassword},
                AssociatedBoardCode = "ALL",
                LogLevel = LogLevels.Inherit
            });

            // Добавляем адаптер к коннектору
            _connector = new RealTimeEmulationTrader<IMessageAdapter>(realAdapter);
            _connector.EmulationAdapter.Emulator.Settings.TimeZone = TimeHelper.Moscow;
            _connector.EmulationAdapter.Emulator.Settings.ConvertTime = true;

        }

        private void btStartStrategy_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _strategy = new Strategy03()
                {
                    Connector = _connector,
                    Portfolio = _portfolio,
                    Security = _security,
                    Volume = 1
                };

                _logManager.Sources.Add(_strategy);

            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message, @"Ошибка запуска стратегии");
                throw;
            }

            //Событие изменения позиции
            _strategy.PositionChanged += () => this.GuiAsync(() =>
            {
                tbPnL.Text = _strategy.PnL.ToString();
                tbPoz.Text = _strategy.Position.ToString();
                //Console.WriteLine(@"Изменение позы {0} PnL={1}", _strategy.Position,_strategy.PnL);
            });
            
            _strategy.Start();
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if(_connector != null) _connector.Dispose();
            base.OnClosing(e);
        }
    }
}
