using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QMAPP.FJC.Entity;
using QMFrameWork.Data;
using QMAPP.Entity;
using System.Reflection;
using QMAPP.FJC.Entity.Basic;

namespace QMAPP.FJC.TRACING.DAInterface
{
    /// <summary>
    /// 采集数据对象
    /// </summary>
    public class DAObject:IDisposable
    {
        public DAObject():this(AppDataFactory.CreateMainSession())
        {
            //AnalyzedValue = new Dictionary<string, string>();
        }
        public Dictionary<string, string> AttachData { get; set; }
        public DAObject(IDataSession datasession)
        {
            this.DataSession = datasession;
            PersistentEntityList = new Dictionary<string, BaseEntity>();
            SQLCommands = new List<SQLCommand>();
            ObjectCacheList = new List<object>();

        }
        /// <summary>
        /// 统一事务数据会话
        /// </summary>
        public IDataSession DataSession { get; private set; }
        /// <summary>
        /// 工位状态
        /// </summary>
        public WorkLocState WorkLocState { get; set; }
        /// <summary>
        /// 物料号
        /// </summary>
        public string MaterialCode { get; set; }
        /// <summary>
        /// 采集点
        /// </summary>
        public Entity.QT.DAI DAI { get; set; }
        /// <summary>
        /// 采集值
        /// </summary>
        public object DAValue { get; set; }
        /// <summary>
        /// 解析后的值
        /// </summary>
        public string AnalyzedValue
        {
            get;
            set;
        }
        /// <summary>
        /// 数据对象主键
        /// </summary>
        public string ObjectPID
        {
            get;
            set;
        }
        /// <summary>
        /// userid
        /// </summary>
        public string UserID { get; set; }
        /// <summary>
        /// 设备代码
        /// </summary>
        public string MachineCode { get; set; }
        /// <summary>
        /// 设备名称
        /// </summary>
        public string MachineName { get; set; }
        /// <summary>
        /// 设备是否受控制 0:不发送不读取  1:只发送不读取   2:不发送至读取   3:即发送也读取
        /// </summary>
        public int IsControl { get; set; }
        /// <summary>
        /// 当前设备是否发送信号
        /// </summary>
        public bool SendSignal
        {
            get { return (IsControl & 1) > 0; }
        }
        /// <summary>
        /// 当前设备是否读取信号
        /// </summary>
        public bool ReadSignal
        {
            get { return (IsControl & 2) > 0; }
        }

        /// <summary>
        /// 数据对象缓存
        /// 将重复查询的数据存入此列表,二次查询时可直接从此列表搜索,减少数据库操作;
        /// </summary>
        public List<object> ObjectCacheList { get; private set; }
        /// <summary>
        /// 获取单个数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="match"></param>
        /// <returns></returns>
        public T GetObjectFromCache<T>(Predicate<T> match)
        {
            var result = from obj in ObjectCacheList
                         where obj.GetType() == typeof(T)
                         && match.Invoke((T)obj)
                         select (T)obj;
            return result.FirstOrDefault();
        }
        /// <summary>
        /// 获取数据列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="match"></param>
        /// <returns></returns>
        public List<T> GetObjectsFromCache<T>(Predicate<T> match)
        {
            var result = from obj in ObjectCacheList
                         where obj.GetType() == typeof(T)
                         && match.Invoke((T)obj)
                         select (T)obj;
            return result.ToList();
        }

        /// <summary>
        /// 需要持久化的实体列表 
        /// Key的格式为“{ClassName}:{PID}" 例如"Product:QWER230-123F1QF-FWGER220-234W11"
        /// </summary>
        public Dictionary<string, BaseEntity> PersistentEntityList
        {
            get;
            private set;
        }
        /// <summary>
        /// 添加实体到持久化列表
        /// </summary>
        /// <param name="entity"></param>
        public void AddToPersistentList(BaseEntity entity,string pid)
        {
            string classname = entity.GetType().Name;
            string key = string.Format("{0}:{1}", classname, pid);
            if (PersistentEntityList.ContainsKey(key))
            {
                PersistentEntityList[key] = entity;
            }
            else
            {
                PersistentEntityList.Add(key, entity);
            }
        }
        /// <summary>
        /// 获取持久化列表中的实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pid"></param>
        /// <returns></returns>
        public T GetPersistentEntity<T>(string pid) where T : BaseEntity
        {
            string classname = typeof(T).Name;
            string key = string.Format("{0}:{1}", classname, pid);
            if (PersistentEntityList.ContainsKey(key))
            {
                return (T)PersistentEntityList[key];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 持久化实体数据
        /// </summary>
        public void PersistEntitys()
        {
            var dbsessiontype=this.DataSession.GetType();
            var methods = dbsessiontype.GetMethods();
            foreach (var entity in PersistentEntityList.Values)
            {
                MethodInfo method = null;
                if (entity.IsDelete)
                {
                    method = methods.FirstOrDefault(p => p.Name == "Delete" && p.ToString() == "Int32 Delete[T](T)");
                }
                else if (entity.IsNewInfo)
                {
                    method = methods.FirstOrDefault(p => p.Name == "Insert" && p.ToString() == "Int32 Insert[T](T)");
                }
                else
                {
                    method = methods.FirstOrDefault(p => p.Name == "Update" && p.ToString() == "Int32 Update[T](T)");
                }
                if (method != null)
                {
                    var closedmethod = method.MakeGenericMethod(entity.GetType());
                    closedmethod.Invoke(this.DataSession, new object[] { entity });
                }
                else
                {
                    throw new Exception("method not found!");
                }

            }
        }
        
        /// <summary>
        /// SQL命令列表
        /// </summary>
        public List<SQLCommand> SQLCommands { get; private set; }
        /// <summary>
        /// 执行SQL
        /// </summary>
        public void ExcuteSQL()
        {
            foreach (var cmd in SQLCommands)
            {
                this.DataSession.ExecuteSql(cmd.SQL, cmd.Parameters.ToArray());
            }
        }

        public void Dispose()
        {
            if (this.DataSession != null)
            {
                this.DataSession.Dispose();
            }
            if (PersistentEntityList != null)
            {
                PersistentEntityList.Clear();
                PersistentEntityList = null;
            }
            if (ObjectCacheList != null)
            {
                ObjectCacheList.Clear();
                ObjectCacheList = null;
            }
        }
        /// <summary>
        /// 模架号
        /// </summary>
        public string MouldCode { get; set; }
        /// <summary>
        /// 采集时间
        /// </summary>
        public DateTime Date { get; set; }
        /// <summary>
        /// 当前班次
        /// </summary>
        public ProduceShift Shift { get; set; }
        /// <summary>
        /// 派工单ID
        /// </summary>
        public string WorkOrderID { get; set; }
        /// <summary>
        /// 生产计划
        /// </summary>
        public Entity.ProductionPlan.WorkOrder OrderPlan { get; set; }

        /// <summary>
        /// True代表本次采集为提前输入
        /// </summary>
        public bool PreInput { get; set; }

        public string MaterialName { get; set; }
        /// <summary>
        /// 模架信息是否重新定位
        /// </summary>
        public bool MouldReLocate { get; set; }
    }
}