
using StockPortfolio.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using Windows.Data.Json;
using Windows.Storage;
using Windows.UI;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
// The data model defined by this file serves as a representative example of a strongly-typed
// model.  The property names chosen coincide with data bindings in the standard item templates.
//
// Applications may use this model as a starting point and build on it, or discard it entirely and
// replace it with something appropriate to their needs. If using this model, you might improve app 
// responsiveness by initiating the data loading task in the code behind for App.xaml when the app 
// is first launched.

namespace StockPortfolio
{
    /// <summary>
    /// Generic item data model.
    /// </summary>
    public class SampleDataItem
    {
        public SampleDataItem(String uniqueId, String title, String subtitle, String imagePath, String description, String content)
        {
            this.UniqueId = uniqueId;
            this.Title = title;
            this.Subtitle = subtitle;
            this.Description = description;
            this.ImagePath = imagePath;
            this.Content = content;
        }

        public string UniqueId { get; private set; }
        public string Title { get; private set; }
        public string Subtitle { get; private set; }
        public string Description { get; private set; }
        public string ImagePath { get; private set; }
        public string Content { get; private set; }

        public override string ToString()
        {
            return this.Title;
        }
    }

    /// <summary>
    /// Generic group data model.
    /// </summary>
    public class FunctionGroup
    {
        public FunctionGroup()
        {
        }

        public string UniqueId { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }



        public double Width
        {
            get
            {

                switch (TileItemContainerStyle)
                {
                    case TileItemContainerStyle.Style1x1:
                    case TileItemContainerStyle.Style1x2:
                        return 170;
                    case TileItemContainerStyle.Style2x1:
                    case TileItemContainerStyle.Style2x2:
                        return 350;
                    default:
                        return 180;
                }
            }

        }

        public double Height
        {
            get
            {

                switch (TileItemContainerStyle)
                {

                    case TileItemContainerStyle.Style1x2:
                    case TileItemContainerStyle.Style2x2:
                        return 350;
                    case TileItemContainerStyle.Style2x1:
                    case TileItemContainerStyle.Style1x1:
                        return 170;

                    default:
                        return 180;
                }
            }

        }

        public TileStyle TileStyle { get; set; }

        public TileItemContainerStyle TileItemContainerStyle { get; set; }

        private UserControl _mainPage;
        public Func<UserControl> CreateMainPage { get; set; }

        public UserControl MainPage
        {
            get
            {
                if (_mainPage == null)
                    _mainPage = CreateMainPage();
                return _mainPage;
            }
        }

        public override string ToString()
        {
            return this.Title;
        }
    }

    /// <summary>
    /// Creates a collection of groups and items with content read from a static json file.
    /// 
    /// SampleDataSource initializes with data read from a static json file included in the 
    /// project.  This provides sample data at both design-time and run-time.
    /// </summary>
    public sealed class DataSource
    {

        public static DataSource Instance { get; private set; }

        static DataSource()
        {
            Instance = new DataSource();
        }
        public DataSource()
        {
            GetSampleData();
        }

        private ObservableCollection<FunctionGroup> _groups = new ObservableCollection<FunctionGroup>();
        public ObservableCollection<FunctionGroup> Groups
        {
            get { return this._groups; }
        }

        public static async Task<IEnumerable<FunctionGroup>> GetGroupsAsync()
        {
            Instance.GetSampleData();

            return Instance.Groups;
        }

        public static async Task<FunctionGroup> GetGroupAsync(string uniqueId)
        {
            Instance.GetSampleData();
            // Simple linear search is acceptable for small data sets
            var matches = Instance.Groups.Where((group) => group.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        private void GetSampleData()
        {
            if (this._groups.Count != 0)
                return;


            this.Groups.Add(new FunctionGroup()
            {
                UniqueId = "MyPortfolio",
                Description = "MyPortfolio",

                Title = "MyPortfolio",
                TileStyle = TileStyle.Style1,
                TileItemContainerStyle = TileItemContainerStyle.Style2x1,
                CreateMainPage = () => new MyPortfolioMainPage()
            }
            );
            this.Groups.Add(new FunctionGroup()
            {
                UniqueId = "HistoricalTrade",
                Description = "HistoricalTrade",

                Title = "HistoricalTrade",
                TileStyle = TileStyle.Style7,
                TileItemContainerStyle = TileItemContainerStyle.Style1x1,
                CreateMainPage = () => new HistoricalTradeMainPage()
            }
           );
            this.Groups.Add(new FunctionGroup()
            {
                UniqueId = "MyInformation",
                Description = "MyInformation",

                Title = "MyInformation",
                TileStyle = TileStyle.Style3,
                TileItemContainerStyle = TileItemContainerStyle.Style1x1,
                CreateMainPage = () => new MyInformation()
            }
          );




        }
    }

    public sealed class SampleDataSource : Common.BindableBase
    {
        private static SampleDataSource _sampleDataSource = new SampleDataSource();
        //private static ApplicationSettings _applicationSettings = new ApplicationSettings();

        private ObservableCollection<StockDataItem> _MyStocks = new ObservableCollection<StockDataItem>();
        public ObservableCollection<StockDataItem> MyStocks
        {
            get { return this._MyStocks; }
        }


        private User _currentUser;

        public User CurrentUser
        {
            get { return _currentUser; }
            set { this.SetProperty(ref _currentUser, value); }
        }

        public static User GetCurrentUser()
        {
            return _sampleDataSource.CurrentUser;
        }

        

        public static async Task LoadUser()
        {

            var user = await LocalStorage.LoadUser<User>();
            if (user != null && !string.IsNullOrEmpty(user.Name) && !string.IsNullOrEmpty(user.Email))
            {
                _sampleDataSource._currentUser = user;
            }
            else
            {
                User defaultUser = new User()  {Balance = 100000, Name = "Lenna", Email = "Lenna@componentone.com", Phone = "13613653750"};
                
                List<Stock> myStocks = new List<Stock>();
                Stock stock1 = new Stock() { StockSymbol = "ACXM", Count = 100 };
                Stock stock2 = new Stock() { StockSymbol = "ADAM", Count = 200 };
                myStocks.Add(stock1);
                myStocks.Add(stock2);
                defaultUser.MyStocks = myStocks;


                List<HistoricalTradeStock> historicalTradeStocks = new List<Model.HistoricalTradeStock>();
                HistoricalTradeStock historicalTradeStock1 = new HistoricalTradeStock() { TradeCount = 100, TradeTime = DateTime.Now, TradeType = TradeType.Buy };
                StockDataItem item1 = new StockDataItem() { Symbol = "ACXM" };
                await item1.UpdateCurrentStockQuote();
                historicalTradeStock1.Stock= item1.CurrentStockQuote;

                HistoricalTradeStock historicalTradeStock2 = new HistoricalTradeStock() { TradeCount = 200, TradeTime = DateTime.Now, TradeType = TradeType.Buy };
                StockDataItem item2 = new StockDataItem() { Symbol = "ADAM" };
                await item2.UpdateCurrentStockQuote();
                historicalTradeStock2.Stock = item2.CurrentStockQuote;
                historicalTradeStocks.Add(historicalTradeStock1);
                historicalTradeStocks.Add(historicalTradeStock2);

                defaultUser.Balance -= item1.CurrentStockQuote.LastTrade * 100;
                defaultUser.Balance -= item2.CurrentStockQuote.LastTrade * 200;


                defaultUser.HistoricalTradeStock = historicalTradeStocks;

                _sampleDataSource._currentUser = defaultUser;

            }
        }

       

        public static async Task SaveUserAsync()
        {
            await LocalStorage.SaveUser<User>(_sampleDataSource._currentUser);
        }
        

        public static async Task RefreshItemsAsync()
        {
            foreach (StockDataItem item in _sampleDataSource.MyStocks)
            {
                await item.UpdateCurrentStockQuote();
            }
        }

        public static async Task<StockDataItem> GetStockBySymobol(string symbol)
        {
            StockDataItem item = new StockDataItem();
            item.Symbol = symbol;
            var stock = _sampleDataSource.CurrentUser.MyStocks.FirstOrDefault(x => x.StockSymbol == item.Symbol);
            if (stock!=null)
            {
                item.Count = stock.Count;
            }
            await item.UpdateCurrentStockQuote();
            return item;
        }

        public static async Task BuyStockAsync(StockDataItem item, int count)
        {
            
            var stock = _sampleDataSource.CurrentUser.MyStocks.FirstOrDefault(x => x.StockSymbol == item.Symbol);
            if (stock != null)
            {
                stock.Count += count;
                item.Count = stock.Count;
                var s = _sampleDataSource.MyStocks.FirstOrDefault(x => x.Symbol == item.Symbol);

                _sampleDataSource.MyStocks.Remove(s);
            }
            else
            {
                _sampleDataSource.CurrentUser.MyStocks.Add(new Stock() { StockSymbol = item.Symbol, Count = count });
                item.Count = count;
            }
            _sampleDataSource.CurrentUser.HistoricalTradeStock.Add(new HistoricalTradeStock() { Stock = item.CurrentStockQuote, TradeCount = count, TradeTime = DateTime.Now, TradeType = TradeType.Buy });
            _sampleDataSource.MyStocks.Add(item);
            _sampleDataSource.CurrentUser.Balance -= item.CurrentStockQuote.LastTrade * count;
            await LocalStorage.SaveUser<User>(_sampleDataSource.CurrentUser);

        }

        public static async Task SellStockAsync(StockDataItem item, int count)
        {
            
            var stock = _sampleDataSource.CurrentUser.MyStocks.FirstOrDefault(x => x.StockSymbol == item.Symbol);
            if (stock != null)
            {
                if (stock.Count > count)
                {
                    stock.Count -= count;
                    item.Count = stock.Count;
                }
                else
                {
                    _sampleDataSource.MyStocks.Remove(item);
                    _sampleDataSource.CurrentUser.MyStocks.Remove(stock);
                }
                _sampleDataSource.CurrentUser.Balance += item.CurrentStockQuote.LastTrade * count;

            }

            _sampleDataSource.CurrentUser.HistoricalTradeStock.Add(new HistoricalTradeStock() { Stock = item.CurrentStockQuote, TradeCount = count, TradeTime = DateTime.Now, TradeType = TradeType.Sell });

            await LocalStorage.SaveUser<User>(_sampleDataSource.CurrentUser);

        }

        public static async Task<IEnumerable<StockDataItem>> GetUserStocksAsync()
        {
            _sampleDataSource.MyStocks.Clear();
            if (_sampleDataSource.CurrentUser != null)
            {
                foreach (Stock item in _sampleDataSource.CurrentUser.MyStocks)
                {
                    StockDataItem stockItem = new StockDataItem() { Symbol = item.StockSymbol,Count=item.Count };
                    await stockItem.UpdateCurrentStockQuote();
                    _sampleDataSource.MyStocks.Add(stockItem);

                }
                return _sampleDataSource.MyStocks;
            }
            return null;

        }
        
    }
}