﻿using JLGames.RocketDriver.Games.RpgMaterial.Common;
using JLGames.RocketDriver.Games.RpgMaterial.Material;
using JLGames.RocketDriver.Samples.RpgMaterialDemo.Cfg.CfgTitle;
using JLGames.RocketDriver.Samples.RpgMaterialDemo.Global.Const;

namespace JLGames.RocketDriver.Samples.RpgMaterialDemo.Service.Material
{
    public class MaterialItem : Material<CfgMaterialItem>, IMaterialItem
    {
        protected MetaWorth m_WorthData;
        protected MetaDisplay m_DisplayData;
        protected MetaOper m_OperData;
        protected MetaValidStamp m_StampValidData;
        protected MetaValidDuration m_DurationValidData;

        // IMaterialWorth

        public int Worth => m_WorthData.Worth;
        public int Quality => m_DisplayData.Quality;

        public int GetNumByWorth(int worth, bool ceil)
        {
            return m_WorthData.GetNumByWorth(worth, ceil);
        }

        public int GetWorthByNum(int num)
        {
            return m_WorthData.GetWorthByNum(num);
        }

        // IMaterialDisplay

        public int IconId => m_DisplayData.IconId == 0 ? m_Data.Id : m_DisplayData.IconId;
        public string IconBundleName => AssetBundles.BundleIcon;
        public string IconPath => GameMaterialPathUtils.GetIconPath(m_Data.Type);
        public string IconSubName => GameMaterialPathUtils.GetIconSubName(m_Data.Type, IconId);
        public int Weight => m_DisplayData.Weight;

        // IMaterialOper

        public bool CheckOperability(int index)
        {
            return m_OperData.CheckOperability(index);
        }

        // IMaterialValid

        public bool ValidEnabled
        {
            get
            {
                if (null != m_DurationValidData) return m_DurationValidData.ValidEnabled;
                if (null != m_StampValidData) return m_StampValidData.ValidEnabled;
                return false;
            }
        }

        public MaterialValidType ValidType
        {
            get
            {
                if (null != m_DurationValidData) return MaterialValidType.Duration;
                if (null != m_StampValidData) return MaterialValidType.Stamp;
                return MaterialValidType.None;
            }
        }

        public bool CheckValid(long ticks)
        {
            if (null != m_DurationValidData) return !m_DurationValidData.ValidEnabled || m_DurationValidData.CheckInValid(ticks);
            if (null != m_StampValidData) return !m_StampValidData.ValidEnabled || m_StampValidData.CheckInValid(ticks);
            return true;
        }

        // IInitMaterial<TCfg>

        public void InitMaterial(CfgMaterialItem data)
        {
            m_RawData = data;
            m_Data = new MetaData((int) data.Id, data.Name, data.Type, (int) data.Limit[0], (int) data.Limit[1],
                data.Desc);
            m_WorthData = new MetaWorth(data.Worth);
            m_DisplayData = new MetaDisplay(data.Quality, (int) data.IconId, data.Weight);
            m_OperData = new MetaOper(data.OperMark);
            InitValid(data.Start, data.End, data.Duration);
        }

        private void InitValid(string start, string end, string duration)
        {
            if (!string.IsNullOrEmpty(duration))
            {
                m_DurationValidData = new MetaValidDuration(GameMaterialValidUtils.TryParseDuration(duration));
                return;
            }

            if (!string.IsNullOrEmpty(start) || !string.IsNullOrEmpty(end))
            {
                var startStamp = GameMaterialValidUtils.TryParseStamp(start); // from 0001.01.01
                var endStamp = GameMaterialValidUtils.TryParseStamp(end); // from 0001.01.01
                m_StampValidData = new MetaValidStamp(startStamp, endStamp);
                return;
            }
        }
    }
}