using System;
using System.Collections.Generic;
using System.Linq;

using Newtonsoft.Json.Linq;

using Vit.Core.Module.Serialization;
using Vit.Core.Util.ComponentModel.Data;
using Vit.Core.Util.ComponentModel.SsError;
using Vit.Db.Module.Schema;
using Vit.Extensions.Newtonsoft_Extensions;
using Vit.Extensions.Object_Extensions;
using Vit.Extensions.Serialize_Extensions;
using Vit.Linq;
using Vit.Linq.ComponentModel;
using Vit.Linq.FilterRules.ComponentModel;

using Vitorm;

namespace Vit.AutoTemp.DataProvider
{
    public class DataProvider_VitormData<Model> : IDataProvider_Vitorm
        where Model : class
    {

        public string template { get; private set; }
        public bool isTree => pidField != null;
        public TableSchema tableSchema { get; private set; }


        string idField => controllerConfig?.idField;
        string pidField => controllerConfig?.pidField;
        readonly Type entityType;
        AutoTempControllerConfig controllerConfig;



        public DataProvider_VitormData(string template, TableSchema tableSchema = null, AutoTempControllerConfig controllerConfig = null)
        {
            this.template = template;

            entityType = typeof(Model);

            tableSchema ??= AutoTempHelp.EntityTypeToTableSchema(entityType);
            this.tableSchema = tableSchema;

            controllerConfig ??= AutoTempHelp.BuildControllerConfigByTable(tableSchema);
            this.controllerConfig = controllerConfig;
        }


        #region getConfig
        public ApiReturn<AutoTempControllerConfig> getControllerConfig(object sender)
        {
            var config = Json.ConvertBySerialize<AutoTempControllerConfig>(controllerConfig);
            return config;
        }
        #endregion



        #region getList
        public ApiReturn getList(object sender, FilterRule filter, IEnumerable<OrderField> sort, PageInfo page, JObject arg)
        {
            var query = Data.Query<Model>();

            var data = query.ToPageData(filter, sort, page);
            var pageData = Json.Deserialize<PageData<JObject>>(Json.Serialize(data));

            #region _childrenCount
            if (isTree)
            {
                pageData.items.ForEach(m =>
                {
                    var id = m[idField];
                    var filter = new FilterRule { field = pidField, @operator = "=", value = id };
                    var count = query.Where(filter).Count();
                    m["_childrenCount"] = count;
                });
            }
            #endregion

            return new ApiReturn<object> { data = pageData };
        }
        #endregion


        #region getModel
        public ApiReturn getModel(object sender, string id)
        {
            var entity = Data.Get<Model>(id);

            return new ApiReturn<object> { data = entity };
        }
        #endregion

        #region insert
        public ApiReturn insert(object sender, JObject model)
        {
            var userModel = model.ConvertBySerialize<Model>();

            Data.Add(userModel);
            return new ApiReturn<object>(userModel);
        }
        #endregion


        #region update
        public ApiReturn update(object sender, JObject model, string id)
        {
            var userModel = model.ConvertBySerialize(entityType);



            var _id = model[idField].GetValue();
            var entity = Data.Get<Model>(_id);

            if (entity == null)
            {
                return new SsError
                {
                    errorMessage = "待修改的数据不存在"
                };
            }

            entity.CopyNotNullProrertyFrom(userModel);

            Data.Update(entity);

            return new ApiReturn<object> { data = entity };

        }
        #endregion


        #region delete
        public ApiReturn delete(object sender, JObject arg)
        {
            var id = arg["id"].GetValue();
            var count = Data.DeleteByKey<Model>(id);

            if (count == 0)
            {
                return new SsError
                {
                    errorMessage = "数据不存在"
                };
            }

            return new ApiReturn();
        }
        #endregion
    }
}
