using CPSYSDIBLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace VICrawlerNS
{
	class CybosHelper
	{
		VICrawler m_Listener = null;

		CPUTILLib.CpCybos m_CPCybos = new CPUTILLib.CpCybos();
		CPFORETRADELib.CpForeTdUtil m_CPUtil = new CPFORETRADELib.CpForeTdUtil();

		CpSvr9619S m_9619S = new CpSvr9619S();

		public CybosHelper(VICrawler Listener)
		{
			m_Listener = Listener;
		}

		public void InitCybos()
        {
            short iResult = m_CPUtil.TradeInit();
            switch (iResult)
            {
                case -1:
                    Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 4");
                    break;

                case 0:
                    Util.Log(Util.LOG_TYPE.VERVOSE, "[TradeInit] 로그인 되었습니다");
                    break;

                case 1:
                    Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 업무 키 입력 잘못됨");
                    break;

                case 2:
                    Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 계좌 비밀번호가 잘못되었습니다");
                    break;

                case 3:
                    Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 취소되었습니다");
                    break;
            }

			m_Listener.SetAccountList(m_CPUtil.AccountNumber);
			SubscribeVICrawler();
        }

		public int GetLimitRemainCountTrade()
		{
			return m_CPCybos.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_TRADE_REQUEST);
		}

		public int GetLimitRemainCountRQ()
		{
			return m_CPCybos.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_NONTRADE_REQUEST);
		}

		public int GetLimitRemainCountSB()
		{
			return m_CPCybos.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_SUBSCRIBE);
		}

		public bool IsConnected()
		{
			return (m_CPCybos.IsConnect==1);
		}

		void SubscribeVICrawler()
		{
			m_9619S.Received += VICrawler_Received;
			m_9619S.Subscribe();
		}

		private void VICrawler_Received()
		{
			uint uiTime = m_9619S.GetHeaderValue(0);
			sbyte cType = m_9619S.GetHeaderValue(1);
			string strCode = m_9619S.GetHeaderValue(3);
			ushort uiEventCode = m_9619S.GetHeaderValue(4);
			string strDesc = m_9619S.GetHeaderValue(5);
			uint uiEndTime = m_9619S.GetHeaderValue(7);
			sbyte cUpDown = m_9619S.GetHeaderValue(8);
			ushort uiDegree = m_9619S.GetHeaderValue(9);

			Console.WriteLine(string.Format("{0} | {1} | {2} | {3} | {4} | {5} | {6} | {7} | {8} | {9}",
				m_9619S.GetHeaderValue(0),
				m_9619S.GetHeaderValue(1),
				m_9619S.GetHeaderValue(2),
				m_9619S.GetHeaderValue(3),
				m_9619S.GetHeaderValue(4),
				m_9619S.GetHeaderValue(5),
				m_9619S.GetHeaderValue(6),
				m_9619S.GetHeaderValue(7),
				m_9619S.GetHeaderValue(8),
				m_9619S.GetHeaderValue(9)
				));

			m_Listener.OnReceivedEvent(uiTime, strCode, uiEventCode, strDesc, cUpDown=='U');
		}

		int GetCallUnitValue(int iValue)
		{
			int iUnit = 1;
			if(iValue < 1000)
				iUnit = 1;
			else if(iValue < 5000)
				iUnit = 5;
			else if(iValue < 10000)
				iUnit = 10;
			else if(iValue < 50000)
				iUnit = 50;
			else if(iValue < 100000)
				iUnit = 100;
			else if(iValue < 500000)
				iUnit = 500;
			else
				iUnit = 1000;

			return (iValue/iUnit)*iUnit;
		}

		public void Buy(CodeList.CODE_VALUE Code, int iBuyPrice)
		{
			try
			{
				DSCBO1Lib.StockMst CPStockMst = new DSCBO1Lib.StockMst();
				CPStockMst.SetInputValue(0, Code.m_strCode);
				CPStockMst.BlockRequest2(0);
				int iCurPrice = CPStockMst.GetHeaderValue(11);
				int iCallValue = GetCallUnitValue((int)(iCurPrice*1.015));
				int iCount = iBuyPrice/iCallValue;

				CPTRADELib.CpTd0311 CP0311 = new CPTRADELib.CpTd0311();
				CP0311.SetInputValue(0, 2);
				CP0311.SetInputValue(1, Config.GetAccount());
				CP0311.SetInputValue(2, Config.GetSubAccount());
				CP0311.SetInputValue(3, Code.m_strCode);
				CP0311.SetInputValue(4, iCount);
				CP0311.SetInputValue(5, iCallValue);
				CP0311.SetInputValue(7, "01");
				CP0311.SetInputValue(8, "01");
				CP0311.BlockRequest2(1);

				Util.Log(Util.LOG_TYPE.BUY, string.Format("code:{0} {1}주 현재가 {2}원, 지정가 {3} IOC 매수", Code.ToString(), iCount, iCurPrice, iCallValue));
			}
			catch(Exception ex)
			{
				Util.Log(Util.LOG_TYPE.ERROR, ex.Message+Environment.NewLine+ex.StackTrace);
			}
		}
	}
}
