using System;
using System.Data;
using DapperORM.Common.Enums;

namespace DapperORM.Common.Models
{
    /// <summary>
    /// 通用返回结果实体
    /// </summary>
    public class ResultModel
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public ResultModel() { }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="result">操作结果，1=success，0=failure</param>
        /// <param name="msg">返回信息</param>
        public ResultModel(int result, string msg = "")
        {
            this.Result = result;
            this.Msg = msg;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="result">操作结果</param>
        /// <param name="msg">返回信息</param>
        public ResultModel(ResultType result, string msg = "")
        {
            this.Result = (int)result;
            this.Msg = msg;
        }

        /// <summary>
        /// 操作结果
        /// </summary>
        public int Result { get; set; }

        /// <summary>
        /// 返回信息（错误描述等）
        /// </summary>
        public string Msg { get; set; }
    }

    /// <summary>
    /// ResultModel 扩展
    /// </summary>
    public static class ResultExtention
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        /// <param name="resultModel"></param>
        /// <returns></returns>
        public static bool IsSuccess(this ResultModel resultModel) => resultModel.Result == (int)ResultType.Success;

        /// <summary>
        /// 是否对应的结果类型
        /// </summary>
        /// <param name="resultModel"></param>
        /// <param name="resultType"></param>
        /// <returns></returns>
        public static bool IsResultType(this ResultModel resultModel, ResultType result) => resultModel.Result == (int)result;
    }

    /// <summary>
    /// 带ID的结果实体
    /// </summary>
    public class ResultIdModel : ResultModel
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public ResultIdModel()
        {

        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="id"></param>
        public ResultIdModel(string id)
        {
            this.Id = id;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="result">操作结果，1=success，0=failure</param>
        /// <param name="msg">返回信息</param>
        public ResultIdModel(int result, string msg = "") : base(result, msg)
        {

        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="result">操作结果</param>
        /// <param name="msg">返回信息</param>
        public ResultIdModel(ResultType result, string msg = "") : base(result, msg)
        {

        }

        /// <summary>
        /// ID
        /// </summary>
        public string Id { get; set; }
    }

    /// <summary>
    /// 自定义泛型结果实体
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ResultModel<T> : ResultModel
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public ResultModel()
        {

        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="data"></param>
        public ResultModel(T data)
        {
            this.Result = (int)ResultType.Success;
            this.Data = data;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="result">操作结果，1=success，0=failure</param>
        /// <param name="msg">返回信息</param>
        public ResultModel(int result, string msg = "") : base(result, msg)
        {

        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="result">操作结果</param>
        /// <param name="msg">返回信息</param>
        public ResultModel(ResultType result, string msg = "") : base(result, msg)
        {

        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="result"></param>
        /// <param name="data"></param>
        /// <param name="msg"></param>
        public ResultModel(ResultType result, T data, string msg = "")
        {
            Result = (int)result;
            Data = data;
            Msg = msg;
        }

        /// <summary>
        /// 结果类型数据
        /// </summary>
        public T Data { get; set; }
    }

    public class ResultModelDataSet : ResultModel
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="data"></param>
        public ResultModelDataSet(DataSet data)
        {
            this.Result = (int)ResultType.Success;
            this.Data = data;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="result">操作结果，1=success，0=failure</param>
        /// <param name="msg">返回信息</param>
        public ResultModelDataSet(int result, string msg = "") : base(result, msg)
        {

        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="result">操作结果</param>
        /// <param name="msg">返回信息</param>
        public ResultModelDataSet(ResultType result, string msg = "") : base(result, msg)
        {

        }

        /// <summary>
        /// 结果类型数据
        /// </summary>
        public DataSet Data { get; set; }
    }

    /// <summary>
    /// ResultModel 转化
    /// </summary>
    public static class ResultModelMap
    {
        /// <summary>
        /// 将结果实体转换成其他结果实体
        /// </summary>
        /// <typeparam name="TResult">输出对象</typeparam>
        /// <typeparam name="TPara"></typeparam>
        /// <returns>输出对象</returns>
        public static ResultModel<TResult> ConvertToResult<TPara, TResult>(this ResultModel<TPara> source,
            Func<TPara, TResult> func = null)
        {
            var ot = new ResultModel<TResult>
            {
                Result = source.Result,
                Msg = source.Msg
            };

            if (func != null && source.Data != null)
            {
                ot.Data = func(source.Data);
            }
            return ot;
        }

        /// <summary>
        /// 将结果实体转换成其他结果实体   --转化结果是通过 泛型 定义的Result实体
        /// 仅转化 Ret和 Message 的值  
        /// </summary>
        /// <typeparam name="TResult">输出对象</typeparam>
        /// <returns>输出对象</returns>
        public static ResultModel<TResult> ConvertToResultOnly<TResult>(this ResultModel source)
        {
            var ot = new ResultModel<TResult>
            {
                Result = source.Result,
                Msg = source.Msg
            };
            return ot;
        }

        /// <summary>
        /// 将结果实体转换成其他结果实体   --转化结果是通过 继承 定义的Result实体  
        /// 仅转化 Ret和 Message 的值
        /// </summary>
        /// <typeparam name="TResult">输出对象</typeparam>
        /// <returns>输出对象</returns>
        public static TResult ConvertToResult<TResult>(this ResultModel source)
            where TResult : ResultModel, new()
        {
            var ot = new TResult
            {
                Result = source.Result,
                Msg = source.Msg
            };
            return ot;
        }
    }
}
