using MaterialSkin;
using MaterialSkin.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AutoSellerNS
{
	public partial class AutoSeller : MaterialForm
	{
		public class ITEM
		{
			public string m_strCodeName;
			public string m_strCode;
			public int m_iItemCnt;
			public long m_iAssessedValue;
			public long m_iValuationGains;
			public double m_dYield;
			public int m_iAvailableQuantity;
			public double m_dBookUnitPrice;
			public long m_iProfitUnitPrice;
			public int m_iSellableCnt;

			public int m_iCurPrice;
		}

		public class NCITEM
		{
			public string m_strCodeName;
			public string m_strCode;
			public int m_iRemainCnt;
			public int m_iOrderPrice;
			public string m_strDesc;
		}


		int m_iCurPricePanelWith;
		CybosHelper m_CybosHelper = null;
		List<ITEM> m_Items = new List<ITEM>();
		string m_strSelectedCode = "";
		bool m_bSell = false;

		public AutoSeller()
		{
			InitializeComponent();
			cbSMMethod.SelectedIndex = 0;

			Util.SetLogView(tbLog);
			Config.Init();

			btUpdate.Enabled = false;
			btSell.Enabled = false;
			

			for (int i = 0; i < 21; i++)
			{
				lvCurPrice.Items.Add(new ListViewItem(new string[] { "", "", "", "" }));
				lvCurPrice.Items[i].UseItemStyleForSubItems = false;
				if (i < 10)
				{
					lvCurPrice.Items[i].SubItems[chAskCount.Index].BackColor = Color.FromArgb(215, 233, 255);
					lvCurPrice.Items[i].SubItems[chCallPrice.Index].BackColor = Color.FromArgb(215, 233, 255);
				}
				else if (i > 10)
				{
					lvCurPrice.Items[i].SubItems[chBidCount.Index].BackColor = Color.FromArgb(255, 227, 227);
					lvCurPrice.Items[i].SubItems[chCallPrice.Index].BackColor = Color.FromArgb(255, 227, 227);
				}
			}
			lvCurPrice.Items[10].SubItems[chAskCount.Index].Text = "현재가";
			lvCurPrice.Items[10].SubItems[chCallPrice.Index].Font = new Font(lvCurPrice.Items[0].SubItems[0].Font, FontStyle.Bold);

			cbAccount.Text = Config.GetAccount();
			tbSubAccount.Text = Config.GetSubAccount();
			tbBidCount.Text = Config.GetBidCount().ToString();
			tbTrailingP.Text = Config.GetTrailingRate().ToString();
			tbTrailingCnt.Text = Config.GetTrailingCnt().ToString();

			m_CybosHelper = new CybosHelper(this);

			m_iCurPricePanelWith = 240;

			var materialSkinManager = MaterialSkinManager.Instance;
			materialSkinManager.AddFormToManage(this);
			materialSkinManager.Theme = MaterialSkinManager.Themes.DARK;
			materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.LightBlue200, TextShade.WHITE);
		}

		public void SetAccountList(string[] aAccountList)
		{
			cbAccount.Items.Clear();
			cbAccount.Items.AddRange(aAccountList);
			foreach (var account in aAccountList)
			{
				if (account == Config.GetAccount())
				{
					cbAccount.SelectedItem = account;
					break;
				}
			}
		}

		private void splitContainer2_SizeChanged(object sender, EventArgs e)
		{
			int iDist = Math.Min(Math.Max(splitContainer2.Width-m_iCurPricePanelWith, splitContainer2.Panel1MinSize), splitContainer2.Width-splitContainer2.Panel2MinSize);
			if(iDist >= splitContainer2.Panel1MinSize && iDist <= splitContainer2.Width - splitContainer2.Panel2MinSize)
				splitContainer2.SplitterDistance = iDist;
		}

		private void btCybos_Click(object sender, EventArgs e)
		{
			m_CybosHelper.InitCybos();

			btCybos.Primary = false;
			btCybos.Enabled = false;

			btUpdate.Enabled = true;
			btSell.Enabled = true;

			//btUpdate_Click(null, null);
		}

		private void AddItem(ITEM Item)
		{
			m_Items.Add(Item);

			if(lvItems.InvokeRequired)
			{
				CybosHelper.STOCK_CUR_ITEM ItemCur = m_CybosHelper.GetItem(Item.m_strCode);

				lvItems.Invoke(new Action(() => {
						lvItems.Items.Add(new ListViewItem(new string[] {
						Item.m_strCode,
						Item.m_strCodeName,
						string.Format("{0:n0}", Item.m_iCurPrice),
						string.Format("{0:n0}", Item.m_iAvailableQuantity),
						string.Format("{0:n2}", Item.m_dBookUnitPrice),
						string.Format("{0:n0}", Item.m_iProfitUnitPrice),
						string.Format("{0:n0}", Item.m_iAssessedValue),
						string.Format("{0:n0}", Item.m_iValuationGains),
						string.Format("{0:n2}", Item.m_dYield),
						ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iMaxPrice) : "",
						ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iCheckCount) : "",
					}));

					var listviewItem = lvItems.Items[lvItems.Items.Count - 1];

					lvItems.Items[lvItems.Items.Count - 1].UseItemStyleForSubItems = false;
					lvItems.Items[lvItems.Items.Count - 1].SubItems[chValuation.Index].ForeColor = (Item.m_iValuationGains > 0) ? Color.Red : (Item.m_iValuationGains < 0) ? Color.Blue : Color.Black;
					lvItems.Items[lvItems.Items.Count - 1].SubItems[chYield.Index].ForeColor = (Item.m_dYield > 0) ? Color.Red : (Item.m_dYield < 0) ? Color.Blue : Color.Black;

					m_CybosHelper.Subscribe(Item);
				}));
			}
			else
			{
				CybosHelper.STOCK_CUR_ITEM ItemCur = m_CybosHelper.GetItem(Item.m_strCode);

				lvItems.Items.Add(new ListViewItem(new string[] {
					Item.m_strCode,
					Item.m_strCodeName,
					string.Format("{0:n0}", Item.m_iCurPrice),
					string.Format("{0:n0}", Item.m_iAvailableQuantity),
					string.Format("{0:n2}", Item.m_dBookUnitPrice),
					string.Format("{0:n0}", Item.m_iProfitUnitPrice),
					string.Format("{0:n0}", Item.m_iAssessedValue),
					string.Format("{0:n0}", Item.m_iValuationGains),
					string.Format("{0:n2}", Item.m_dYield),
					ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iMaxPrice) : "",
					ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iCheckCount) : "",
					}));

				

				var listviewItem = lvItems.Items[lvItems.Items.Count - 1];

				lvItems.Items[lvItems.Items.Count - 1].UseItemStyleForSubItems = false;
				lvItems.Items[lvItems.Items.Count - 1].SubItems[chValuation.Index].ForeColor = (Item.m_iValuationGains > 0) ? Color.Red : (Item.m_iValuationGains < 0) ? Color.Blue : Color.Black;
				lvItems.Items[lvItems.Items.Count - 1].SubItems[chYield.Index].ForeColor = (Item.m_dYield > 0) ? Color.Red : (Item.m_dYield < 0) ? Color.Blue : Color.Black;

				m_CybosHelper.Subscribe(Item);
			}
		}

		private void btUpdate_Click(object sender, EventArgs e)
		{
			// 잔고
			var Items = m_CybosHelper.UpdateItems();

			m_Items.Clear();
			lvItems.Items.Clear();
			foreach (var Item in Items)
				AddItem(Item);

			// 미체결
			UpdateNC();
		}

		void UpdateNC()
		{
			var NCItems = m_CybosHelper.UpdateNC();
			lvNCItem.Items.Clear();
			if(lvNCItem.InvokeRequired)
			{
				lvNCItem.Invoke(new Action(() => {
					foreach(var NCItem in NCItems)
					{
						lvNCItem.Items.Add(new ListViewItem(new string[] {
							NCItem.m_strCode,
							NCItem.m_strCodeName,
							NCItem.m_strDesc,
							string.Format("{0:n0}", NCItem.m_iOrderPrice),
							string.Format("{0:n0}", NCItem.m_iRemainCnt),
							}));
					}
				}));
			}
			else
			{
				foreach(var NCItem in NCItems)
				{
					lvNCItem.Items.Add(new ListViewItem(new string[] {
						NCItem.m_strCode,
						NCItem.m_strCodeName,
						NCItem.m_strDesc,
						string.Format("{0:n0}", NCItem.m_iOrderPrice),
						string.Format("{0:n0}", NCItem.m_iRemainCnt),
						}));
				}
			}
		}

		public void UpdateItem(string strCode, string strCodeName, bool bBid, int iConclusionCnt, int iRemainCnt, int iBookValue)
		{
			btUpdate_Click(null, null);
			//if(lvList.InvokeRequired)
			//{

			//}
			//else
			//{
			//	ListViewItem Item = lvList.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chCode.Index].Text == strCode);
			//	if(Item == default(ListViewItem) && iRemainCnt > 0)
			//	{
			//		// 아이템 추가
			//	}
			//	else
			//	{
			//		// 갱신
			//		Item.SubItems[chCount.Index].Text = string.Format("{0:n0}", iRemainCnt);
			//		Item.SubItems[chBookValue.Index].Text = string.Format("{0:n2}", iBookValue);
			//	}
			//}
		}

		public void OnReceipt()
		{
			UpdateNC();
		}

		private void btSell_Click(object sender, EventArgs e)
		{
			btSell.Primary = !btSell.Primary;
			m_bSell = (btSell.Primary == false);
		}

		public bool IsSelling()
		{
			return m_bSell;
		}

		public void OnReceivedCurPrice(string strCode, int iPrice, int iMaxPrice, int iCheckCount, bool bReal)
		{
			ITEM Item = m_Items.FirstOrDefault(s => s.m_strCode == strCode);
			if (Item == default(ITEM))
				return;

			Item.m_iCurPrice = iPrice;
			Item.m_iAssessedValue = (int)(iPrice * Item.m_iAvailableQuantity * 99.94 / 100);
			Item.m_dYield = (Item.m_iCurPrice - Item.m_iProfitUnitPrice) * 100 / (double)Item.m_iProfitUnitPrice;

			if (lvItems.InvokeRequired)
			{
				lvItems.Invoke(new Action(() =>
				{
					ListViewItem row = lvItems.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chCode.Index].Text == strCode);
					if (row == default(ListViewItem))
						return;

					row.SubItems[chCurPrice.Index].Text = string.Format("{0}{1:n0}", bReal?"":"*", Item.m_iCurPrice);
					row.SubItems[chAssessedValue.Index].Text = string.Format("{0:n0}", Item.m_iAssessedValue);
					row.SubItems[chYield.Index].Text = string.Format("{0:n2}", Item.m_dYield);
					row.SubItems[chMaxPrice.Index].Text = string.Format("{0:n0}", iMaxPrice);
					row.SubItems[chCheckCount.Index].Text = string.Format("{0:n0}", iCheckCount);
				}));
			}
			else
			{
				ListViewItem row = lvItems.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chCode.Index].Text == strCode);
				if (row == default(ListViewItem))
					return;

				row.SubItems[chCurPrice.Index].Text = string.Format("{0}{1:n0}", bReal?"":"*", Item.m_iCurPrice);
				row.SubItems[chAssessedValue.Index].Text = string.Format("{0:n0}", Item.m_iAssessedValue);
				row.SubItems[chYield.Index].Text = string.Format("{0:n2}", Item.m_dYield);
				row.SubItems[chMaxPrice.Index].Text = string.Format("{0:n0}", iMaxPrice);
				row.SubItems[chCheckCount.Index].Text = string.Format("{0:n0}", iCheckCount);
			}

			if(strCode == m_strSelectedCode)
			{
				if (lvCurPrice.InvokeRequired)
				{
					lvCurPrice.Invoke(new Action(() => {
						lvCurPrice.Items[10].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", Item.m_iCurPrice);
					}));
				}
				else
				{
					lvCurPrice.Items[10].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", Item.m_iCurPrice);
				}
			}
		}

		public void OnReceivedCall(string strCode, int iCurPrice, int[] aiBidPrice, int[] aiBidCount, int[] aiAskPrice, int[] aiAskCount)
		{
			if (strCode != m_strSelectedCode)
				return;

			ITEM Item = m_Items.FirstOrDefault(s => s.m_strCode == strCode);
			if (Item == default(ITEM))
				return;

			if (lvCurPrice.InvokeRequired)
			{
				lvCurPrice.Invoke(new Action(() => {

					if(iCurPrice > 0)
						lvCurPrice.Items[10].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", iCurPrice);

					for (int i = 0; i < 10; i++)
					{
						lvCurPrice.Items[i].SubItems[chAskCount.Index].Text = string.Format("{0:n0}", aiAskCount[9-i]);
						lvCurPrice.Items[i].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", aiAskPrice[9-i]);
					}

					for (int i = 0; i < 10; i++)
					{
						lvCurPrice.Items[11 + i].SubItems[chBidCount.Index].Text = string.Format("{0:n0}", aiBidCount[i]);
						lvCurPrice.Items[11 + i].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", aiBidPrice[i]);
					}
				}));
			}
			else
			{
				if(iCurPrice > 0)
					lvCurPrice.Items[10].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", iCurPrice);

				for (int i = 0; i < 10; i++)
				{
					lvCurPrice.Items[i].SubItems[chAskCount.Index].Text = string.Format("{0:n0}", aiAskCount[9-i]);
					lvCurPrice.Items[i].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", aiAskPrice[9-i]);
				}

				for (int i = 0; i < 10; i++)
				{
					lvCurPrice.Items[11+i].SubItems[chBidCount.Index].Text = string.Format("{0:n0}", aiBidCount[i]);
					lvCurPrice.Items[11+i].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", aiBidPrice[i]);
				}
			}
		}

		public int GetSellableCount(string strCode)
		{
			ITEM Item = m_Items.FirstOrDefault(s => s.m_strCode == strCode);
			if(Item == default(ITEM))
				return 0;

			return Item.m_iSellableCnt;
		}

		private void lvList_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (lvItems.SelectedItems.Count <= 0)
				return;

			string strCode = lvItems.SelectedItems[0].SubItems[chCode.Index].Text;
			CybosHelper.STOCK_CUR_ITEM Item = m_CybosHelper.GetItem(strCode);
			if (Item == null)
				return;

			m_strSelectedCode = strCode;
			OnReceivedCall(strCode, Item.m_iCurPrice, Item.m_aiBidPrice, Item.m_aiBidCount, Item.m_aiAskPrice, Item.m_aiAskCount);
			//OnReceivedCurPrice(strCode, Item.m_iCurPrice);
		}

		private void btApply_Click(object sender, EventArgs e)
		{
			string strAccount = (string)cbAccount.SelectedItem;
			string strSubAccount = tbSubAccount.Text;
			Config.SetAccount(strAccount, strSubAccount);

			int iBidCount = 0;
			int.TryParse(tbBidCount.Text, out iBidCount);
			Config.SetBidCount(iBidCount);

			float fTrailingPercent = 0;
			float.TryParse(tbTrailingP.Text, out fTrailingPercent);
			int iTrailingCnt = 0;
			int.TryParse(tbTrailingCnt.Text, out iTrailingCnt);
			Config.SetTrailing(fTrailingPercent, iTrailingCnt);
		}

		#region Simulation
		private void btLoad_Click(object sender, EventArgs e)
		{
			SimulationHelper helper = new SimulationHelper(this, m_CybosHelper, tbSimulationLog);
			helper.LoadExcel2();
		}

		private void btSimulate_Click(object sender, EventArgs e)
		{
			SimulationHelper helper = new SimulationHelper(this, m_CybosHelper, tbSimulationLog);
			helper.StartSimuation2();
		}
		#endregion
	}
}
