/*-------------------------------------------------------------------------
 * 功能描述:JBimParseContext
 * 作者:xulisong
 * 创建时间: 2019/6/13 16:50:43
 * 版本号:v1.0
 *  -------------------------------------------------------------------------*/

using System;
using System.Collections.Generic;
using JBIM;
using JBIM.Common;
using JBIM.Component;
using JBIM.Relationship;
using RevitExport;
using RevitExport.Export;
using RevitExport.Parse;
using RevitToJBim.ComponentParse;
using RevitToJBim.JsonConverter;
using RevitToJBim.ParseData;

namespace RevitToJBim
{
    /// <summary>
    /// JBimParseContext解析上下文
    /// </summary>
    public class JBimParseContext: ParseContext
    {
        public JBimParseContext(List<ParseBase> parsers)
        {
            Parser = new RevitToJBimParser(this, parsers);
            Document = new BimDocument();
            RelationShips = new List<ElementRelationShip>();
        }
        public RevitToJBimParser Parser { get; private set; }
        protected BimDocument Document { get;private set; }
        
        #region 数据缓存相关

        private Dictionary<string, BimId> m_RevitIdMap = new Dictionary<string, BimId>();
        public BimId GetBimId(string revitSourceId)
        {
            if (string.IsNullOrWhiteSpace(revitSourceId))
            {
                return null;
            }
            m_RevitIdMap.TryGetValue(revitSourceId, out BimId result);
            return result;
        }
        public List<BimId> GetBimIds(List<string> sourceIds)
        {
            List<BimId> relatedIds = null;
            if (sourceIds != null)
            {
                relatedIds = new List<BimId>();
                foreach (var sourceId in sourceIds)
                {
                    var relatedid = GetBimId(sourceId);
                    if (relatedid != null)
                    {
                        relatedIds.Add(relatedid);
                    }
                }
            }
            return relatedIds;
        }
        public BimId AddBimObject(BimObject obj)
        {
            var id= this.Document.NewObject(obj)?.Id;
            if (obj is ComponentObject cObject&&!string.IsNullOrWhiteSpace(cObject.SourceId))
            {
                m_RevitIdMap[cObject.SourceId] = id;
            }
          return id;
        }
        #endregion

        #region 关系数据统一存储
        public List<ElementRelationShip> RelationShips { get; private set; }
        #endregion

        #region 解析方法
        public List<BimId> Parse(ElementWrapper wrapper)
        {
            return Parser.ParseElement(wrapper);
        }
        #endregion

        #region 整理document数据
        private void ArrangeBimDocument()
        {
            #region 关系数据处理
            /*
             * 当前关系数据是一个临时数据,需要不全信息之后才能真实使用
             * 临时数据中,存储的是SourceId的对应关系
             */
            foreach (var relationshipBase in RelationShips)
            {
                if (relationshipBase.IsProperty)
                {
                    UpdateRelationShipInfo(relationshipBase);
                }
                else
                {
                    var bimRelation = ConvertRelationShipInfo(relationshipBase);
                    Document.NewObject(bimRelation);
                }
            }
            #endregion
        }
        /// <summary>
        /// 获取关联对象的BimId
        /// </summary>
        /// <param name="ship"></param>
        /// <returns></returns>
        private BimId GetRelatingBimId(ElementRelationShip ship)
        {
            BimId relatingid = null;
            if (ship.RelatingObjectIsBimId)
            {
                relatingid = new BimId(ship.RelatingObject);
            }
            else
            {
                relatingid = GetBimId(ship.RelatingObject);
            }

            return relatingid;
        }
        private RelationshipBase ConvertRelationShipInfo(ElementRelationShip ship)
        {
            BimId relatingid = GetRelatingBimId(ship);
            RelationshipBase useShip = null;
            if (relatingid == null)
            {
                return null;
            }
            if (ship is ElementOneToOneRel singleRel)
            {
                var relatedid = GetBimId(singleRel.RelatedObject);
                if (relatedid != null)
                {
                    useShip = new OneToOneRel(relatingid, relatedid);
                }

            }
            else if (ship is ElementOneToManyRel manyRel)
            {
                var relatedIds = GetBimIds(manyRel.RelatedObjects);
                if (relatedIds != null)
                {
                    useShip = new OneToManyRel(relatingid, relatedIds);
                }
            }
            return useShip;
        }

        private void UpdateRelationShipInfo(ElementRelationShip ship)
        {
            var relatingid = GetRelatingBimId(ship);
            if (relatingid == null)
            {
                return;
            }

            var bimObject = Document.GetBimObject(relatingid);
            if (bimObject == null)
            {
                return;
            }
            if (ship is ElementOneToOneRel singleRel)
            {
                var relatedid = GetBimId(singleRel.RelatedObject);

                if (relatedid != null)
                {
                    BimObjectUtil.AcceptRelation(bimObject, ship.PropertyName, relatedid);
                }

            }
            else if (ship is ElementOneToManyRel manyRel)
            {
                var relatedIds = GetBimIds(manyRel.RelatedObjects);
                if (relatedIds != null)
                {
                    BimObjectUtil.AcceptRelations(bimObject, ship.PropertyName, relatedIds);
                }
            }
            return;
        }
        #endregion

        /// <summary>
        /// 获取结果Document
        /// </summary>
        /// <returns></returns>
        public BimDocument GetResultDocument()
        {
            //没有经过整理的document是半成品,所以经document对应的属性取消公开
            ArrangeBimDocument();
            return Document;
        }
    }
}