using MMoneyCoderSharp.Data.Request;
using MMoneyCoderSharp.Data.Request.봉차트;
using MMoneyCoderSharp.DB;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
//using System.Threading.Tasks;
using static MMoneyCoderSharp.DBDefine;

namespace MMoneyCoderSharp.Data
{
    /// <summary>
    /// 씬단위로 요청사항을 매핑해서 DB에서 받은 데이터를 리턴해줄 매니저 객체.
    /// </summary>
    public class DataManager
    {


        #region "싱글턴"
        private static volatile DataManager mInstance = null;

        private static object mSingletonLocker = new object();

        private DataManager()
        {

        }

        public static DataManager getInstance()
        {
            lock (mSingletonLocker)
            {
                if (mInstance == null)
                {
                    mInstance = new DataManager();
                }
            }

            return mInstance;
        }

        #endregion


        /// <summary>
        /// 스탁포멧정리기준.hwp로 컷 대 기준을 작성함.
        /// 1. 1열판 기본 -> 판그래프데이터참조
        /// 2. 2열판 상세 -> 판그래프데이터참조
        /// 3. 2열판 기본 -> 판그래프데이터참조
        /// 4. 3열판 그래프 -> 판3데이터분류
        /// 5. 라인그래프 -> 선그래프데이터분류
        /// 6. 캔들차트 -> 봉차트데이터분류
        /// 7. 캔들차트                     -> 봉차트데이터분류
        /// 8. 주체별매매동향                 -> 그리드표
        /// 9. 지수별매매동향                 -> 그리드표
        /// 10. 매매동향선그래프              -> 선그래프데이터분류
        /// 11. 기관순매수현황                -> 그리드표
        /// 12. 매매동향막대그래프            -> 막대그래프데이터분류
        /// 13. 프로그램매매 표그래프         -> 그리드표
        /// 14. 외국인투자자 순매도 상위                   -> 쿼리가 없음
        /// 15~18                           -> 지도그래프
        /// 19. 이미지 그래프                -> 아직안함
        /// 20. 네모그래프                   -> 네모그래프
        /// 21. 섹터지수 막대그래프          -> 막대그래프데이터분류
        /// 22. 캔들차트 두개                -> 이거 고민되네..
        /// 23. 선그래프 두개                 -> 이거도 고민되네..
        /// 24. 종목별 수익률                 -> 선그래프데이터분류(아직안함)
        /// 25. 5단그래프                     -> 
        /// 26. 호가창
        /// 27. 거래원
        /// 28. 수급동향
        /// 29. 매출구성 원그래프
        /// 30. 성장지표 선그래프
        /// 31. 종목매출액 막대그래프                 -> 쿼리가 없음
        /// 32. 영업이익 막대그래프                 -> 쿼리가 없음
        /// </summary>


        private DataSet mStockInfoDataSet = null;

        public DataSet getStocksInfoTable()
        {

            if (mStockInfoDataSet == null)
            {
                updateStocksInfoSet();
            }

            return mStockInfoDataSet;

        }


        public void updateStocksInfoSet()
        {

            string sql = string.Empty;

            mStockInfoDataSet = new DataSet();

            DataTable bufTableKospi = DataQueryExecutor.Current.Execute(DataSourceKind.Oracle, "코스피", "SELECT F_STOCK_WANNAME, F_STOCK_CODE FROM T_STOCK WHERE F_MKT_HALT = 'N'");                                                                                      
            mStockInfoDataSet.Tables.Add(bufTableKospi);

            DataTable bufTableKosdaq = DataQueryExecutor.Current.Execute(DataSourceKind.Oracle, "코스닥", "SELECT F_STOCK_WANNAME, F_STOCK_CODE FROM T_KOSDAQ_STOCK WHERE F_MKT_HALT = 'N'");
            mStockInfoDataSet.Tables.Add(bufTableKosdaq);

            DataTable bufTableNXTKospi = DataQueryExecutor.Current.Execute(DataSourceKind.MariaDb, "NXT코스피", "SELECT CONCAT(F_STOCK_NAME, '(NXT)') F_STOCK_NAME, F_STOCK_CODE FROM N_STOCK WHERE F_STOP_GUBUN = 'N'");
            mStockInfoDataSet.Tables.Add(bufTableNXTKospi);

            DataTable bufTableNXTKosdaq = DataQueryExecutor.Current.Execute(DataSourceKind.MariaDb, "NXT코스닥", "SELECT CONCAT(F_STOCK_NAME, '(NXT)') F_STOCK_NAME, F_STOCK_CODE FROM N_KOSDAQ_STOCK WHERE F_STOP_GUBUN = 'N'");
            mStockInfoDataSet.Tables.Add(bufTableNXTKosdaq);

            DataTable bufTableForgien = DataQueryExecutor.Current.Execute(DataSourceKind.Oracle, "해외", "SELECT F_KNAM, F_SYMB FROM T_WORLD_IX_EQ_MASTER");
            mStockInfoDataSet.Tables.Add(bufTableForgien);

            DataTable bufTableKOSPI_INDUSTRY = DataQueryExecutor.Current.Execute(DataSourceKind.Oracle, "코스피업종", "select a.f_part_code, b.f_part_name from t_index a, t_part b where a.f_part_code = b.f_part_code order by a.f_part_code");
            mStockInfoDataSet.Tables.Add(bufTableKOSPI_INDUSTRY);

            DataTable bufTableKOSDAQ_INDUSTRY = DataQueryExecutor.Current.Execute(DataSourceKind.Oracle, "코스닥업종", "select a.f_part_code, b.f_part_name from t_kosdaq_index a, t_kosdaq_part b where a.f_part_code = b.f_part_code order by a.f_part_code");
            mStockInfoDataSet.Tables.Add(bufTableKOSDAQ_INDUSTRY);

            DataTable bufTableKFORGIEN_INDUSTRY = DataQueryExecutor.Current.Execute(DataSourceKind.Oracle, "해외업종", "select F_INPUT_NAME, f_knam, f_symb from t_world_ix_eq_master WHERE f_fdtc = '0' and f_natc = 'US' ORDER BY F_KNAM");
            mStockInfoDataSet.Tables.Add(bufTableKFORGIEN_INDUSTRY);

            DataTable bufTableKFORGIEN_INDEX = DataQueryExecutor.Current.Execute(DataSourceKind.Oracle, "해외지수", "select F_SYMB, F_KNAM, F_ENAM, F_INPUT_NAME from t_world_ix_eq_master WHERE F_FDTC = '0'");
            mStockInfoDataSet.Tables.Add(bufTableKFORGIEN_INDEX);

            DataTable bufTableKFORGIEN_STOCK = DataQueryExecutor.Current.Execute(DataSourceKind.Oracle, "해외종목", "select F_INPUT_NAME, f_symb from t_world_ix_eq_master WHERE f_fdtc = '1' and (f_natc = 'US' or f_natc = 'TW') ORDER BY F_INPUT_NAME");
            mStockInfoDataSet.Tables.Add(bufTableKFORGIEN_STOCK);

        }


        /// <summary>
        /// 선그래프 데이터 요청 메서드
        /// 마지막 매개변수는 종목일때는 한글종목명, 지수일때는 분류코드.
        /// 
        /// 여기가 기존 코드 중 cut_5,10으로 검색해서 나오는 데이터 모두.
        /// 
        /// </summary>
        /// <param name="recvDataType">선그래프씬 데이터 분류</param>
        /// <param name="recvDataLength">선그래프씬 데이터 길이</param>
        /// <param name="recvArgData">종목은 해당 종목의 한글명으로, 지수는 코드값으로....</param>
        /// <returns></returns>
        public DataSet createLineGraphData(선그래프데이터분류 recvDataType, 데이터기간 recvDataLength, string recvArgData = null)
        {

            IDataRequest bufInstance = null;

            switch (recvDataType)
            {
                case 선그래프데이터분류.원달러:
                    bufInstance = new Exchange(환율.달러, recvDataLength);
                    break;
                case 선그래프데이터분류.원엔:
                    bufInstance = new Exchange(환율.엔, recvDataLength);
                    break;
                case 선그래프데이터분류.원위엔:
                    bufInstance = new Exchange(환율.위엔, recvDataLength);
                    break;
                case 선그래프데이터분류.원유로:
                    bufInstance = new Exchange(환율.유로, recvDataLength);
                    break;
                case 선그래프데이터분류.코스피수익률:
                    bufInstance = new IndexYield(recvDataLength, 국내지수종류.KOSPI);
                    break;
                case 선그래프데이터분류.코스닥수익률:
                    bufInstance = new IndexYield(recvDataLength, 국내지수종류.KOSDAQ);
                    break;
                case 선그래프데이터분류.코스피200수익률:
                    bufInstance = new IndexYield(recvDataLength, 국내지수종류.KOSPI200);
                    break;
                case 선그래프데이터분류.KRX100수익률:
                    bufInstance = new IndexYield(recvDataLength, 국내지수종류.KRX100);
                    break;
                case 선그래프데이터분류.코스피업종지수수익률:
                    bufInstance = new IndexIndustryYield(recvArgData, recvDataLength, 국내시장종류.KOSPI);
                    break;
                case 선그래프데이터분류.코스닥업종지수수익률:
                    bufInstance = new IndexIndustryYield(recvArgData, recvDataLength, 국내시장종류.KOSDAQ);
                    break;
                case 선그래프데이터분류.코스피종목수익률:
                    bufInstance = new StockYield(recvArgData, recvDataLength, 국내시장종류.KOSPI);
                    break;
                case 선그래프데이터분류.코스닥종목수익률:
                    bufInstance = new StockYield(recvArgData, recvDataLength, 국내시장종류.KOSDAQ);
                    break;
                case 선그래프데이터분류.개인매매동향:
                case 선그래프데이터분류.기관매매동향:
                case 선그래프데이터분류.외국인매매동향:
                case 선그래프데이터분류.코스피매매동향:
                case 선그래프데이터분류.코스닥매매동향:
                    bufInstance = new Trading(recvDataType);
                    break;
                default:
                    break;
            }

            bufInstance.buildData();

            return bufInstance.getResult();

        }

        /// <summary>
        /// 봉차트를 위한데이터
        /// 종목과 업종지수 모두 추가 데이터로는 Code를 받는다.
        /// 
        /// 기존 코드에서 6,7컷부분
        /// </summary>
        /// <param name="recvDataTypeMain"></param>
        /// <param name="recvDataTypeSub"></param>
        /// <param name="recvDataLength"></param>
        /// <param name="recvArgData">종목은 코드값 지수는 한글명..</param>
        /// <returns></returns>
        public DataSet createCandleChartData(봉차트데이터분류 recvDataTypeMain, 봉차트세부종목 recvDataTypeSub, 데이터기간 recvDataLength, string recvArgData = null)
        {

            IDataRequest bufInstance = null;

            switch (recvDataTypeMain)
            {
                case 봉차트데이터분류.KOSPI:
                    bufInstance = new CandleKOSPI(recvDataTypeSub, recvDataLength);
                    break;
                case 봉차트데이터분류.KOSDAQ:
                    bufInstance = new CandleKOSDAQ(recvDataTypeSub, recvDataLength);
                    break;
                case 봉차트데이터분류.KOSPI200:
                    bufInstance = new CandleKOSPI200(recvDataTypeSub, recvDataLength);
                    break;
                case 봉차트데이터분류.KRX100:
                    bufInstance = new CandleKRX100(recvDataTypeSub, recvDataLength);
                    break;
                case 봉차트데이터분류.선물:
                    bufInstance = new CandleFutures(recvDataTypeSub, recvDataLength);
                    break;
                case 봉차트데이터분류.코스피종목:
                    bufInstance = new CandleStockKOSPI(recvDataTypeSub, recvDataLength, recvArgData);
                    break;
                case 봉차트데이터분류.코스닥종목:
                    bufInstance = new CandleStockKOSDAQ(recvDataTypeSub, recvDataLength, recvArgData);
                    break;
                case 봉차트데이터분류.코스피업종지수:
                    bufInstance = new CandleIndustryKOSPI(recvDataTypeSub, recvDataLength, recvArgData);
                    break;
                case 봉차트데이터분류.코스닥업종지수:
                    bufInstance = new CandleIndustryKOSDAQ(recvDataTypeSub, recvDataLength, recvArgData);
                    break;

                case 봉차트데이터분류.해외지수:
                    bufInstance = new Candleforeign(recvDataTypeSub, recvDataLength, recvArgData);
                    break;

                case 봉차트데이터분류.해외종목:
                    bufInstance = new CandleforeignStock(recvDataTypeSub, recvDataLength, recvArgData);
                    break;

                case 봉차트데이터분류.거래정지:
                    bufInstance = new CandleStockDIS(recvDataTypeSub, recvDataLength, recvArgData);

                    break;

                case 봉차트데이터분류.거래정지k:
                    bufInstance = new CandleStockDISK(recvDataTypeSub, recvDataLength, recvArgData);

                    break;
                default:
                    break;
            }

            bufInstance.buildData();

            return bufInstance.getResult();

        }

        /// <summary>
        /// 그리드표 그래프 데이터
        /// 컷14번은 쿼리가 없음
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        public DataSet createGridChartData(그리드표그래프종류 recvDataType, 국내시장종류? recvMarketType = null)
        {
            IDataRequest bufInstance = null;

            switch (recvDataType)
            {
                case 그리드표그래프종류.투자자순매수매도상위14번컷:
                    throw new Exception("쿼리가 없음");
                    //break;
                case 그리드표그래프종류.프로그램매매13번컷:
                    bufInstance = new Grid13();
                    break;
                case 그리드표그래프종류.기관순매수현황11번컷:
                    bufInstance = new Grid11();
                    break;
                case 그리드표그래프종류.지수별매매동향9번컷:
                    bufInstance = new Grid9(recvMarketType.Value);
                    break;
                case 그리드표그래프종류.주체별매매동향8번컷:
                    bufInstance = new Grid8();
                    break;
            }

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        /// <summary>
        /// 20번컷 사각그래프용 데이터.
        /// 국내시장 업종별 네모그래프
        /// 15개종목이 이미 정해져있음.(선택불가)
        /// </summary>
        /// <param name="recvDataType">시장종류</param>
        /// <returns></returns>
        public DataSet createSquareChartData_Cut20(국내시장종류 recvDataType)
        {

            IDataRequest bufInstance = new Square20(recvDataType);

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        /// <summary>
        /// 12번컷 데이터.
        /// HWP 표와는 다르게 선물은 없음.
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        public DataSet createCut12StickData(국내시장종류 recvDataType)
        {
            IDataRequest bufInstance = new Stick12(recvDataType);

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        /// <summary>
        /// 21번컷 데이터.
        /// 12번과 헷갈리지 말 것
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        public DataSet createCut21StickData(섹터지수막대그래프분류 recvDataType)
        {
            IDataRequest bufInstance = new Stick21(recvDataType);

            bufInstance.buildData(); 

            return bufInstance.getResult();
        }

     

        public DataSet createWorldMapData(지도데이터분류 recvDataType)
        {
            IDataRequest bufInstance = null;

            switch (recvDataType)
            {
                case 지도데이터분류.글로벌:
                    bufInstance = new MapWorld();
                    break;
                case 지도데이터분류.아시아:
                    bufInstance = new MapAsia();
                    break;
                case 지도데이터분류.미국:
                    bufInstance = new MapUSA();
                    break;
                case 지도데이터분류.유럽:
                    bufInstance = new MapEurope();
                    break;
                default:
                    break;
            }

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        #region "판데이터"

        /// <summary>
        /// 1열판 국내지수류 데이터
        /// </summary>
        /// <param name="recvDataList"></param>
        /// <param name="recvDataType"></param>
        /// <returns></returns>
        public DataSet createPlateData(판1그래프데이터지수류 recvDataList, 국내지수종류 recvDataType)
        {
            IDataRequest bufInstance = null;

            switch (recvDataList)
            {
                case 판1그래프데이터지수류.현재지수:
                    bufInstance = new INDEX_PAN(recvDataType);
                    break;
                case 판1그래프데이터지수류.예상지수:
                    bufInstance = new INDEX_FORECAST_PAN(recvDataType);
                    break;
            }


            bufInstance.buildData();

            return bufInstance.getResult();
        }

        /// <summary>
        /// 1열판 산업종목류 데이터
        /// </summary>
        /// <param name="recvDataList"></param>
        /// <param name="recvDataType"></param>
        /// <param name="recvDataCode"></param>
        /// <returns></returns>
        public DataSet createPlateData(판1그래프데이터산업및종목류 recvDataList, 국내시장종류 recvDataType, string recvDataCode)
        {
            IDataRequest bufInstance = null;
            Nxt_IDataRequest Nxt_bufInstance = null;

            switch (recvDataList)
            {
                case 판1그래프데이터산업및종목류.종목현재가:
                    if ((recvDataType == 국내시장종류.NXT_KOSPI) || (recvDataType == 국내시장종류.NXT_KOSDAQ))
                        Nxt_bufInstance = new Nxt_STOCK_PAN(recvDataType, recvDataCode);
                    else
                        bufInstance = new STOCK_PAN(recvDataType, recvDataCode);
                    break;
                case 판1그래프데이터산업및종목류.종목예상체결가:
                    bufInstance = new STOCK_FORECAST_PAN(recvDataType, recvDataCode);
                    break;
                case 판1그래프데이터산업및종목류.종목시간외단일가:
                    bufInstance = new STOCK_OVERTIME_PAN(recvDataType, recvDataCode);
                    break;
                case 판1그래프데이터산업및종목류.지수업종:
                    bufInstance = new INDUSTRY_PAN(recvDataType, recvDataCode);
                    break;
            }

            if ((recvDataType == 국내시장종류.NXT_KOSPI) || (recvDataType == 국내시장종류.NXT_KOSDAQ))
            {
                Nxt_bufInstance.Nxt_buildData();
                return Nxt_bufInstance.Nxt_getResult();
            }
            else
            {
                bufInstance.buildData();
                return bufInstance.getResult();
            }

        }

        /// <summary>
        /// 1열판 해외산업종목 데이터
        /// </summary>
        /// <param name="recvDataList"></param>
        /// <param name="recvDataCode"></param>
        /// <returns></returns>
        public DataSet createPlateData(판1그래프데이터해외류 recvDataList, string recvDataCode)
        {
            IDataRequest bufInstance = null;

            switch (recvDataList)
            {
                case 판1그래프데이터해외류.해외업종:
                    bufInstance = new INDUSTRY_FORGIEN_PAN(recvDataCode);
                    break;
                case 판1그래프데이터해외류.해외종목:
                    bufInstance = new STOCK_FORGIEN_PAN(recvDataCode);
                    break;
            }

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        /// <summary>
        /// 1열판해외지수류 데이터
        /// </summary>
        /// <param name="recvDataList"></param>
        /// <returns></returns>
        public DataSet createPlateData(해외지수종류 recvDataList, string recvDataCode)
        {
            IDataRequest bufInstance = new INDEX_FORGIEN_PAN(recvDataList, recvDataCode);

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        /// <summary>
        /// 1열판원환율
        /// </summary>
        /// <param name="recvDataList"></param>
        /// <returns></returns>
        public DataSet createPlateData(원환율 recvDataList)
        {
            IDataRequest bufInstance = new EXCHANGE_PAN(recvDataList);

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        public DataSet createPlate3Data_Cut4(판3데이터분류 recvDataList)
        {
            IDataRequest bufInstance = new DataObject_3PAN(recvDataList);

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        public DataSet createPlateData(국내시장종류 recvDataType1, 상세판데이터분류 recvDataType2, string recvStockCode)
        {
            IDataRequest bufInstance = new SANGSE_PAN(recvDataType1, recvDataType2, recvStockCode);

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        public DataSet createPlateNxtData(국내시장종류 recvDataType1, 상세판데이터분류 recvDataType2, string recvStockCode)
        {
            Nxt_IDataRequest bufInstance = new Nxt_SANGSE_PAN(recvDataType1, recvDataType2, recvStockCode);

            bufInstance.Nxt_buildData();

            return bufInstance.Nxt_getResult();
        }


        #endregion


        public DataSet createCut26Data(국내시장종류 recvDataType1, string recvStockCode)
        {
            IDataRequest bufInstance = new Quote_Stocks(recvDataType1, recvStockCode);

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        public DataSet createCut27Data(국내시장종류 recvDataType1, string recvStockCode)
        {
            IDataRequest bufInstance = new Trader_Stocks(recvDataType1, recvStockCode);

            bufInstance.buildData();

            return bufInstance.getResult();
        }

        public DataSet create5DanDataIndex(국내시장종류 recvDataType1, 데이터5단판지수별 recvDataType2)
        {
            IDataRequest bufInstance = null;

            switch (recvDataType2)
            {

                case 데이터5단판지수별.하락률:
                    bufInstance = new lower_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.신고가52주:
                    bufInstance = new high52_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.신저가52주:
                    bufInstance = new low52_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.시간외상승률:
                    bufInstance = new high_overtime_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.시간외하락률:
                    bufInstance = new low_overtime_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.예상가시가총액상위:
                    bufInstance = new capital_forecast_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.업종:
                    bufInstance = new upjong_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.시가총액:
                    bufInstance = new capital_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.상승률:
                    bufInstance = new upper_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.코스피200:
                    bufInstance = new kospi200(recvDataType1);
                    break;
                case 데이터5단판지수별.ETF:
                    bufInstance = new ETF(recvDataType1);

                    break;
            }

            bufInstance.buildData();

            return bufInstance.getResult();
        }
        public DataSet Nxt_create5DanDataIndex(국내시장종류 recvDataType1, 데이터5단판지수별 recvDataType2)
        {
            Nxt_IDataRequest Nxt_bufInstance = null;

            switch (recvDataType2)
            {
                case 데이터5단판지수별.상승률:
                    Nxt_bufInstance = new Nxt_upper_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.하락률:
                    Nxt_bufInstance = new Nxt_lower_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.거래량:
                    Nxt_bufInstance = new Nxt_vol_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.시간외상승률:
                    Nxt_bufInstance = new Nxt_high_overtime_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.시간외하락률:
                    Nxt_bufInstance = new Nxt_low_overtime_5dan(recvDataType1);
                    break;
                case 데이터5단판지수별.시가총액:
                    Nxt_bufInstance = new Nxt_capital_5dan(recvDataType1);
                    break;
            }

            Nxt_bufInstance.Nxt_buildData();

            return Nxt_bufInstance.Nxt_getResult();
        }

        public DataSet create5DanDataTheme(데이터5단판기타 recvDataType2, List<string> 테마주코드리스트)
        {
            IDataRequest bufInstance = null;

            switch (recvDataType2)
            {
                case 데이터5단판기타.전문가추천:
                    bufInstance = new suggest_5dan(테마주코드리스트);
                    break;
                case 데이터5단판기타.테마주:
                    bufInstance = new theme_5dan(테마주코드리스트);
                    break;
                case 데이터5단판기타.테마예상:
                    bufInstance = new theme_yesang_5dan(테마주코드리스트);
                    break;
            }

            bufInstance.buildData();

            return bufInstance.getResult();
        }

    }
}
