using System;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Runtime.InteropServices;

using Cosmos.BaseFrame;
using Cosmos.UserFrame;
using Cosmos.ServiceProvider;
using Cosmos.Common;
using Cosmos.Service;
using Cosmos.CommonManager;
using System.Threading;
using SPC.Kiosk.Common;
using SPC.Kiosk.PB.Model;

namespace SPC.Kiosk.DataHelper
{
    public class CommonDataHelper : IDisposable
    {
        #region [ Members ]
        private SManager sManager = null;                                   // 이 객체를 통해 업무 Service 호출
        private StateServer StateObject = null;                             // StateObject : StateServer Object (객체)
        private PosStatus m_cPosStatus = null;                              // 기본정보 참조
        private TranStatus m_cTrnStatus = null;                             // 거래정보 참조
        protected IDataCommonUs m_cDataCommon = null;
        /// <summary>
        /// POS 초기화 필요 유무
        /// </summary>
        public bool NeedInitModule { get; set; }
        #endregion Members

        #region [ Ctor & Dispose ]
        /// <summary>
        /// Ctor
        /// </summary>
        public CommonDataHelper()
        {
            sManager = new SManager();
            StateObject = (StateServer)StateServer.GetInstance();
            if (!NeedInitModule)
            {
                m_cPosStatus = (PosStatus)StateObject.POS;      // POS 기본정보
                m_cTrnStatus = (TranStatus)StateObject.TRAN;    // POS 거래정보 
                m_cDataCommon = (IDataCommonUs)sManager.InitServiceInstance(ServiceLists.ASV_DATA_PROCESS.DLL, ServiceLists.ASV_DATA_PROCESS.DATA_COMMON);
            }
        }
        /// <summary>
        /// Dispose
        /// </summary>
        public void Dispose()
        {
            sManager = null;                                  // 이 객체를 통해 업무 Service 호출
            StateObject = null;                               // StateObject : StateServer Object (객체)
            m_cPosStatus = null;                              // 기본정보 참조
            m_cTrnStatus = null;                              // 거래정보 참조
            m_cDataCommon = null;
        }
        #endregion Ctor & Dispose

        #region [ Methods ]
        /// <summary>
        /// Set Common Language Data 
        /// </summary>
        public void SetCommonLanguage()
        {
            if (NeedInitModule) return;
            var getLanguageData = m_cDataCommon.Select_NHS_LANG_MSG("PROD");//m_cDataCommon.Select_NHS_LANG_MSG("COMMON");
            if (getLanguageData is DataTable)
            {
                foreach (var aLanguageData in getLanguageData.Rows)
                {
                    if (aLanguageData is DataRow aRow)
                    {
                        var languageCode = aRow["LANG_MESSAGE_CD"] is null ? string.Empty : aRow["LANG_MESSAGE_CD"].ToString();
                        var languageType = SupportLanguageType.ko;
                        if (!(aRow["LANG_CD"] is null) && aRow["LANG_CD"].ToString().Length > 2)
                        {
                            languageType = (SupportLanguageType)Enum.Parse(typeof(SupportLanguageType), aRow["LANG_CD"].ToString().Substring(0, 2));
                        }
                        var languageData = aRow["LANG_MESSAGE"] is null ? string.Empty : aRow["LANG_MESSAGE"].ToString();
                        Languages.SetMessage(languageCode, languageType, languageData);
                    }
                }
            }
        }
        /// <summary>
        /// Get Language Data 
        /// _gubunCD
        /// 상품/제품 = "PROD" Item
        /// 카데고리 = "CATE" Category
        /// 옵션 = "OPTN" Option
        /// 옵션그룹 = "OPTNGRP" Option Group
        /// </summary>
        /// <param name="_gubunCD"></param>
        /// <param name="_messageCD"></param>
        /// <returns></returns>
        public List<M_Language> GetLaguageData(string _gubunCD, string _messageCD)
        {
            if (NeedInitModule) return null;
            List<M_Language> result = null;
            try
            {
                var getLanguageData = m_cDataCommon.Select_NHS_LANG_MSG(_gubunCD, _messageCD);
                if (getLanguageData is DataTable && getLanguageData.Rows.Count > 0)
                {
                    result = new List<M_Language>();
                    foreach (var aLanguageData in getLanguageData.Rows)
                    {
                        if (aLanguageData is DataRow aRow)
                        {
                            var languageCode = aRow["LANG_MESSAGE_CD"] is null ? string.Empty : aRow["LANG_MESSAGE_CD"].ToString(); 
                            var languageType = SupportLanguageType.ko;
                            if (!(aRow["LANG_CD"] is null) && aRow["LANG_CD"].ToString().Length > 2)
                            {
                                languageType = (SupportLanguageType)Enum.Parse(typeof(SupportLanguageType), aRow["LANG_CD"].ToString().Substring(0, 2));
                            }
                            var languageData = aRow["LANG_MESSAGE"] is null ? string.Empty : aRow["LANG_MESSAGE"].ToString();
                            var dataFinded = result.Where(r => r.Type.Equals(languageType)).FirstOrDefault();
                            if (dataFinded is M_Language)
                            {
                                dataFinded.LanguageData = languageData;
                            }
                            else
                            {
                                var addDada = new M_Language
                                {
                                    Type = languageType,
                                    LanguageData = languageData
                                };
                                result.Add(addDada);
                            }
                        }
                    }
                }
            }
            catch 
            {
                result = null;
            }
            return result;
        }
        /// <summary>
        /// Get Into Data
        /// </summary>
        /// <returns></returns>
        public List<M_IntroItems> GetIntroData(double _screenWidth)
        {
            if (NeedInitModule) return null;
            List<M_IntroItems> result = null;
            try
            {

                var getIntroItem = m_cDataCommon.Select_NHS_SCREEN();
                if (getIntroItem is DataTable && getIntroItem.Rows.Count > 0)
                {
                    result = new List<M_IntroItems>();
                    var screenRow = getIntroItem.Rows[0];
                    var screenCD = screenRow["SCREEN_CD"] is null ? string.Empty : screenRow["SCREEN_CD"].ToString();
                    if (!string.IsNullOrEmpty(screenCD))
                    {
                        var getFrames = m_cDataCommon.Select_NHS_SCREEN_LAYER_GROUPBY_FRAMECD(screenCD);
                        var stackWidth = _screenWidth;
                        if (getFrames.Rows.Count.Equals(2)) stackWidth = _screenWidth / 2;
                        var stackIndex = 0;
                        foreach (var getFramesItem in getFrames.Rows)
                        {
                            if (getFramesItem is DataRow aFrameRow)
                            {

                                var frameCD = aFrameRow["FRAME_CD"] is null ? string.Empty : aFrameRow["FRAME_CD"].ToString();
                                if (!string.IsNullOrEmpty(frameCD))
                                {
                                    var getStackContents = GetStackContents(screenCD, frameCD);
                                    var newIntroItems = new M_IntroItems
                                    {
                                        ItemsStack = stackIndex,
                                        StackWidth = stackWidth,
                                        StackContents = getStackContents
                                    };
                                    result.Add(newIntroItems);
                                    stackIndex++;
                                }
                            }
                        }


                    }
                }
            }
            catch 
            {
                result = null;
            }
            return result;
        }

        private List<M_StackContents> GetStackContents(string _screenCD, string _frameCD)
        {
            List<M_StackContents> result = null;
            try
            {
                var getScreenLayer = m_cDataCommon.Select_NHS_SCREEN_LAYER(_screenCD, _frameCD);
                if (getScreenLayer is DataTable && getScreenLayer.Rows.Count > 0)
                {
                    result = new List<M_StackContents>();
                    int setIndex = 0;
                    foreach (var aStackItem in getScreenLayer.Rows)
                    {
                        if (aStackItem is DataRow aRow)
                        {
                            var layerCD = aRow["LAYER_CD"] is null ? string.Empty : aRow["LAYER_CD"].ToString();
                            if (!string.IsNullOrEmpty(layerCD))
                            {
                                var mediaItems = GetMediaRollItems(_screenCD, _frameCD, layerCD);
                                var newStackItems = new M_StackContents
                                {
                                    ItemsIndex = setIndex,
                                    MediaRollItems = mediaItems,
                                };
                                result.Add(newStackItems);
                                setIndex++;
                            }
                            
                        }
                    }
                }
            }
            catch
            {
                result = null;
            }
            return result;
        }

        private List<M_MediaRollItem> GetMediaRollItems(string _screenCD, string _frameCD, string _layerCD)
        {
            List<M_MediaRollItem> result = null;
            try
            {
                var getScreenContents = m_cDataCommon.Select_NHS_SCREEN_CONTENTS(_screenCD, _frameCD, _layerCD);
                if (getScreenContents is DataTable && getScreenContents.Rows.Count > 0)
                {
                    result = new List<M_MediaRollItem>();
                    foreach (var aContents in getScreenContents.Rows)
                    {
                        if (aContents is DataRow aRow)
                        {
                            var fileType = aRow["FILE_MIME_TYPE"].ToString().Equals("PNG")
                                        ? MediaType.Image
                                        : aRow["FILE_MIME_TYPE"].ToString().Equals("MP4")
                                        ? MediaType.VOD
                                        : MediaType.None;
                            var linkType = aRow["LINK_YN"].ToString().Equals("1")
                                        ? IntroLinkType.Page
                                        : aRow["LINK_YN"].ToString().Equals("2")
                                        ? IntroLinkType.Category
                                        : aRow["LINK_YN"].ToString().Equals("3")
                                        ? IntroLinkType.ItemCode
                                        : IntroLinkType.None;
                            var param1 = aRow["PRD_CATE_L"] is null ? string.Empty : aRow["PRD_CATE_L"].ToString();
                            var param2 = aRow["PRD_CATE_M"] is null ? string.Empty : aRow["PRD_CATE_M"].ToString();
                            var linkParameter = string.Empty;
                            switch (linkType)
                            {
                                case IntroLinkType.Page:
                                    switch (param1)
                                    {
                                        case "0":
                                            linkParameter = "FirstSelect";
                                            break;
                                        case "1":
                                            linkParameter = "SensingPage";
                                            break;
                                        case "2":
                                            linkParameter = "ItemPage";
                                            break;
                                        default:
                                            linkParameter = "FirstSelect";
                                            break;
                                    }
                                    break;
                                case IntroLinkType.Category:
                                    linkParameter = string.Format("category&{0}&{1}", param1, param2);
                                    break;
                                case IntroLinkType.ItemCode:
                                    linkParameter = param1;
                                    break;

                            }
                            var mediaPath = aRow["FILE_NAME"] is null ? string.Empty : aRow["FILE_NAME"].ToString();
                            var runnigSeconds = aRow["PLAY_TIME"] is null ? 0 : int.Parse(aRow["PLAY_TIME"].ToString());
                            var startTime = aRow["DISPLAY_START_TIME"] is null ? string.Empty : aRow["DISPLAY_START_TIME"].ToString();
                            var endTime = aRow["DISPLAY_END_TIME"] is null ? string.Empty : aRow["DISPLAY_END_TIME"].ToString();
                            if (!startTime.Length.Equals(4)) startTime = string.Empty;
                            if (!endTime.Length.Equals(4)) startTime = string.Empty;
                            var newMediaItem = new M_MediaRollItem
                            {
                                Type = fileType,
                                MediaPath = ResourceManager.GetCDPimagePath(mediaPath),
                                LinkType = linkType,
                                LinkParameter = linkParameter,
                                RunnigSeconds = runnigSeconds,
                                StartTime = startTime.Equals(string.Empty) 
                                          ? default(TimeSpan)
                                          : new TimeSpan(int.Parse(startTime.Substring(0,2)), int.Parse(startTime.Substring(2, 2)), 0),
                                EndTime = endTime.Equals(string.Empty)
                                          ? default(TimeSpan)
                                          : new TimeSpan(int.Parse(endTime.Substring(0, 2)), int.Parse(endTime.Substring(2, 2)), 59)

                            };
                            result.Add(newMediaItem);
                        }
                    }

                }
            }
            catch 
            {

                result = null;
            }
            return result;
        }

        /// <summary>
        /// Get Category Data
        /// </summary>
        /// <returns></returns>
        public List<M_CategoryItems> GetCategoryData()
        {
            if (NeedInitModule) return null;
            List<M_CategoryItems> result = null;
            try
            {
                var getCategory1Items = m_cDataCommon.Select_NHS_PRD_CATE("0000");
                if (getCategory1Items is DataTable)
                {
                    result = new List<M_CategoryItems>();
                    int setIndex = 0;
                    foreach (var aCategoryItem in getCategory1Items.Rows)
                    {
                        if (aCategoryItem is DataRow aRow)
                        {
                            var category1Code = aRow["PRD_CATE_CD"] is null ? string.Empty : aRow["PRD_CATE_CD"].ToString();
                            if (!result.Exists(r => r.Catalog1Item.Category1.Equals(category1Code)))
                            {
                                result.Add
                                (
                                    new M_CategoryItems
                                    {
                                        Catalog1Item = new M_ItemData
                                        {
                                            Index = setIndex,
                                            ItemCode = category1Code,
                                            Category1 = category1Code,
                                        },
                                        Catalog2Items = GetCategory2Data(category1Code)
                                    }
                                );
                                setIndex++;
                            }
                        }
                    }
                }
            }
            catch
            {
                result = null;
            }
            return result;
        }
        /// <summary>
        /// Get Category2 Data
        /// </summary>
        /// <returns></returns>
        public List<M_ItemData> GetCategory2Data(string _category1Code)
        {
            if (NeedInitModule) return new List<M_ItemData>();
            var result = new List<M_ItemData>();
            try
            {
                var getCategory2Item = m_cDataCommon.Select_NHS_PRD_CATE(_category1Code);
                if (getCategory2Item is DataTable)
                {
                    int setIndex = 0;
                    foreach (var aCategoryItem in getCategory2Item.Rows)
                    {
                        if (aCategoryItem is DataRow aRow)
                        {
                            var category2Code = aRow["PRD_CATE_CD"] is null ? string.Empty : aRow["PRD_CATE_CD"].ToString();
                            if (!result.Exists(r => r.Category2.Equals(category2Code)))
                            {
                                result.Add
                                (
                                    new M_ItemData
                                    {
                                        Index = setIndex,
                                        ItemCode = category2Code,
                                        Category1 = _category1Code,
                                        Category2 = category2Code,
                                    }
                                );
                                setIndex++;
                            }
                        }
                    }
                }
            }
            catch 
            {
                result = new List<M_ItemData>();
            }
            return result;
        }
        /// <summary>
        /// Get Item Data
        /// </summary>
        /// <param name="_categoryItems"></param>
        /// <returns></returns>
        public List<M_ItemData> GetItemsData()
        {
            if (NeedInitModule) return new List<M_ItemData>();
            var result = new List<M_ItemData>();
            try
            {
                var getItems = m_cDataCommon.Select_NHS_STOR_PRD_KEY();
                if (getItems is DataTable)
                {
                    int setIndex = 0;
                    foreach (var aItem in getItems.Rows)
                    {
                        if (aItem is DataRow aRow)
                        {
                            try
                            {
                                var itemCode = aRow["ITEM_CD"] is null ? string.Empty : aRow["ITEM_CD"].ToString();
                                if (!result.Exists(r => r.ItemCode.Equals(itemCode)))
                                {
                                    var category1 = aRow["PRD_CATE_UP_CD"] is null ? string.Empty : aRow["PRD_CATE_UP_CD"].ToString();
                                    var category2 = aRow["PRD_CATE_CD"] is null ? string.Empty : aRow["PRD_CATE_CD"].ToString();
                                    var imageFile = aRow["FILE_NAME"] is null ? string.Empty : aRow["FILE_NAME"].ToString();
                                    var isOption = aRow["OPTN_YN"] is null ? false : aRow["OPTN_YN"].ToString().Equals("1");
                                    var isSoldOut = aRow["SOLDOUT_YN"] is null ? false : aRow["SOLDOUT_YN"].ToString().Equals("1");
                                    var itemPrice = aRow["SALES_PRC"] is null ? 0d : double.Parse(aRow["SALES_PRC"].ToString());
                                    var option = isOption ? GetItemOption(itemCode) : null;
                                    result.Add
                                    (
                                        new M_ItemData
                                        {
                                            Index = setIndex,
                                            ItemCode = itemCode,
                                            Category1 = category1,
                                            Category2 = category2,
                                            ImageFile = imageFile,
                                            IsOption = isOption,
                                            IsSoldOut = isSoldOut,
                                            Price = itemPrice,
                                            Option = option
                                        }
                                    );


                                    setIndex++;
                                }
                            }
                            catch 
                            {
                            }
                        }
                    }
                }
            }
            catch 
            {
                result = new List<M_ItemData>();
            }
            return result;
        }
        /// <summary>
        /// Get Option Data
        /// </summary>
        /// <param name="_itemCode"></param>
        /// <returns></returns>
        public List<M_ItemOptionGroup> GetItemOption(string _itemCode)
        {
            if (NeedInitModule) return null;
            List<M_ItemOptionGroup> result = null;
            try
            {
                var getOptionGroup = m_cDataCommon.Select_NHS_PRD_OPTN(_itemCode);
                if (getOptionGroup is DataTable && getOptionGroup.Rows.Count > 0 )
                {
                    result = new List<M_ItemOptionGroup>();
                        
                    int setIndex = 0;
                    foreach (var aItem in getOptionGroup.Rows)
                    {
                        if (aItem is DataRow aRow)
                        {
                            try
                            {
                                var optionGroupCode = aRow["ITEM_OPTN_GRP_CD"] is null ? string.Empty : aRow["ITEM_OPTN_GRP_CD"].ToString();

                                if (!result.Exists(r => r.Code.Equals(optionGroupCode)))
                                {
                                    var getOptionGroupItem = m_cDataCommon.Select_NHS_PRD_OPTN_GRP(optionGroupCode);
                                    if (getOptionGroupItem is DataTable && getOptionGroupItem.Rows.Count.Equals(1))
                                    {
                                        var optionGroupItem = getOptionGroupItem.Rows[0];
                                        var selectMode = optionGroupItem["SEL_MTD"].ToString().Equals("S")
                                                       ? OptionSelectMode.Single
                                                       : optionGroupItem["SEL_MTD"].ToString().Equals("M")
                                                       ? OptionSelectMode.Multi
                                                       : OptionSelectMode.None;
                                        var imageFile = optionGroupItem["FILE_NAME"] is null ? string.Empty : optionGroupItem["FILE_NAME"].ToString();
                                        var isMustSelect = optionGroupItem["RQRD_YN"] is null ? false : optionGroupItem["RQRD_YN"].ToString().Equals("1");
                                        result.Add
                                        (
                                            new M_ItemOptionGroup
                                            {
                                                Index = setIndex,
                                                Code = optionGroupCode,
                                                ImageFile = imageFile,
                                                SelectMode = selectMode,
                                                IsMustSelect = isMustSelect,
                                                Name = GetLaguageData("OPTNGRP", optionGroupCode),
                                                Options = GetOptions(optionGroupCode),
                                            }
                                        );
                                        setIndex++;
                                    }
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                }
            }
            catch
            {
                result = null;
            }
            return result;
        }
        /// <summary>
        /// Get Option Group Data With Options Data
        /// </summary>
        /// <param name="_optionGroupCode"></param>
        /// <returns></returns>
        public List<M_ItemOption> GetOptions(string _optionGroupCode)
        {
            if (NeedInitModule) return null;
            List<M_ItemOption> result = null;
            try
            {
                var getOption = m_cDataCommon.Select_NHS_OPTN_MST(_optionGroupCode);
                if (getOption is DataTable && getOption.Rows.Count > 0)
                {
                    result = new List<M_ItemOption>();
                    int setIndex = 0;
                    foreach (var aItem in getOption.Rows)
                    {
                        if (aItem is DataRow aRow)
                        {
                            try
                            {
                                var optionCode = aRow["ITEM_OPTN_CD"] is null ? string.Empty : aRow["ITEM_OPTN_CD"].ToString();
                                if (!result.Exists(r => r.Code.Equals(optionCode)))
                                {
                                    var kind = aRow["KIND"].ToString().Equals("DIS") 
                                                   ? OptionKind.Discount
                                                   : aRow["KIND"].ToString().Equals("BTN")
                                                   ? OptionKind.Button
                                                   : aRow["KIND"].ToString().Equals("UPC")
                                                   ? OptionKind.UpCharge
                                                   : aRow["KIND"].ToString().Equals("CNT")
                                                   ? OptionKind.Count
                                                   : OptionKind.None;
                                    var kindCode = aRow["KIND_CODE"] is null ? string.Empty : aRow["KIND_CODE"].ToString();
                                    var amountMin = aRow["MIN_AMT"] is null ? 0 : int.Parse(aRow["MIN_AMT"].ToString());
                                    var amountMax = aRow["MAX_AMT"] is null ? 0 : int.Parse(aRow["MAX_AMT"].ToString());
                                    var amount = aRow["AMT"] is null ? 0d : double.Parse(aRow["AMT"].ToString());
                                    result.Add
                                    (
                                        new M_ItemOption
                                        {
                                            Index = setIndex,
                                            Code = optionCode,
                                            Name = GetLaguageData("OPTN", optionCode),
                                            SelectValue = 0d,
                                            Kind = kind,
                                            KindCode = kindCode,
                                            Amount = amount,
                                            AmountMin = amountMin,
                                            AmountMax = amountMax
                                        }
                                    );
                                    setIndex++;
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                }
            }
            catch
            {
                result = null;
            }
            return result;
        }
        #endregion Methods
    }
}