using Infrastructure;
using Infrastructure.Extensions;
using OpenAuth.App.Base;
using OpenAuth.App.Interface;
using OpenAuth.App.SysDatabaseLink.Response;
using OpenAuth.Repository;
using OpenAuth.Repository.Core;
using OpenAuth.Repository.Domain;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenAuth.App.BaseApp.Base;

namespace OpenAuth.App.SysDatabaseLink
{
    public class SysDatabaseLinkApp : SqlSugarBaseApp<Repository.Domain.SysDatabaseLink, SugarDbContext>
    {
        public SysDatabaseLinkApp(ISugarUnitOfWork<SugarDbContext> unitWork, ISimpleClient<Repository.Domain.SysDatabaseLink> repository, IAuth auth) : base(unitWork, repository, auth)
        {

        }

        /// <summary>
        /// 获取树形数据
        /// </summary>
        /// <returns></returns>
        public async Task<Response<List<TreeModel>>> LoadDataBaseLinkTree()
        {
            var list = await this.Repository.AsQueryable().Where(r => r.DeleteMark == 0).ToListAsync();
            List<TreeModel> treelist = new List<TreeModel>();
            Dictionary<string, List<TreeModel>> dic = new Dictionary<string, List<TreeModel>>();

            TreeModel mynode = new TreeModel();
            mynode.id = "hcsystemdb";
            mynode.text = "本地数据库";
            mynode.value = "hcsystemdb";
            mynode.complete = true;
            mynode.hasChildren = false;
            treelist.Add(mynode);
            foreach (var item in list)
            {
                TreeModel node = new TreeModel();
                node.id = item.DBName;
                node.text = item.DBAlias;
                node.value = item.DBName;
                node.complete = true;
                node.hasChildren = false;

                if (!dic.ContainsKey(item.ServerAddress))
                {
                    TreeModel pnode = new TreeModel();
                    pnode.id = item.ServerAddress;
                    pnode.text = item.ServerAddress;
                    pnode.value = "hcServerAddress";
                    pnode.isexpand = true;
                    pnode.complete = true;
                    pnode.hasChildren = true;
                    pnode.ChildNodes = new List<TreeModel>();
                    treelist.Add(pnode);
                    dic.Add(item.ServerAddress, pnode.ChildNodes);
                }
                dic[item.ServerAddress].Add(node);
            }
            return new Response<List<TreeModel>>
            {
                Result = treelist
            };
        }

        /// <summary>
        /// 分页获取列表数据
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="pageindex"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        public async Task<Response<PageInfo<List<Repository.Domain.SysDatabaseLink>>>> LoadDataBaseInfo(string keyword, int pageindex, int pagesize)
        {
            //定义且实例化分页数据
            RefAsync<int> totalCount = 0;

            //数据查询并返回
            var info = await this.Repository.AsQueryable()
                .WhereIF(!string.IsNullOrEmpty(keyword), t => t.DBName.Contains(keyword))
                .OrderBy(r=>r.DBName)
                .ToPageListAsync(pageindex, pagesize, totalCount);

            return new Response<PageInfo<List<Repository.Domain.SysDatabaseLink>>>
            {
                Result = new PageInfo<List<Repository.Domain.SysDatabaseLink>>
                {
                    Items = info,
                    Total = totalCount
                }
            };
        }

        /// <summary>
        /// 获取实体数据
        /// </summary>
        /// <param name="id">数据库连接主键</param>
        /// <returns></returns>
        public async Task<Response<Repository.Domain.SysDatabaseLink>> GetDataBaseForm(string id)
        {
            var info = await this.Repository.GetByIdAsync(id);
            return new Response<Repository.Domain.SysDatabaseLink>
            {
                Result = info
            };
        }
        /// <summary>
        /// 添加数据库连接（新增、修改）
        /// </summary>
        /// <param name="keyValue">主键值</param>
        /// <param name="databaseLinkEntity">数据库实体</param>
        /// <returns></returns>
        public async Task<Response<bool>> SaveBaseLinkEntity(string keyValue, Repository.Domain.SysDatabaseLink baseLink)
        {
            /*测试数据库连接串"******";*/
            if (!string.IsNullOrEmpty(keyValue) && baseLink.DBConnection == "******")
            {
                baseLink.DBConnection = null;// 不更新连接串地址
            }
            else
            {
                var testRes = TestConnection(baseLink.DBConnection, baseLink.DBType);
                if (testRes != "success")
                {
                    return new Response<bool>
                    {
                        Result = false,
                        Message = "字符串连接失败"
                    };
                }
            }
            var user = _auth.GetCurrentUser().User;
            using (var uwo = base.UnitWork.CreateContext())
            {
                if (!string.IsNullOrEmpty(keyValue))
                {

                    baseLink.DatabaseLinkId = keyValue;
                    baseLink.ModifyDate = DateTime.Now;
                    baseLink.ModifyUserId = user.Id.ToString();
                    baseLink.ModifyUsername = user.Name;
                    await uwo.SysDatabaseLink.UpdateAsync(baseLink);
                }
                else
                {
                    baseLink.DatabaseLinkId = Guid.NewGuid().ToString();
                    baseLink.Createdate = DateTime.Now;
                    baseLink.DeleteMark = 0;
                    baseLink.EnabledMark = 1;
                    baseLink.CreateUserId = user.Id.ToString();
                    baseLink.CreateUsername = user.Name;
                    await uwo.SysDatabaseLink.InsertAsync(baseLink);
                }

                var flag = uwo.Commit();
                return new Response<bool>
                {
                    Result = flag,
                    Message = flag == true ? "操作成功" : "操作失败"
                };
            }
        }

        /// <summary>
        /// 删除数据库连接
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public async Task<Response<bool>> DeleteBaseLink(string id)
        {
            using (var uwo = base.UnitWork.CreateContext())
            {
                await uwo.SysDatabaseLink.DeleteByIdAsync(id);
                var flag = uwo.Commit();
                return new Response<bool>
                {
                    Result = flag,
                    Message = flag == true ? "操作成功" : "操作失败"
                };
            }
        }

        #region 扩展方法
        /// <summary>
        /// 测试数据数据库是否能连接成功
        /// </summary>
        /// <param name="connection">连接串</param>
        /// <param name="dbType">数据库类型</param>
        public string TestConnection(string connection, string dbType)
        {
            try
            {
                this.TestLinkClient(connection, dbType).BeginTran();
                this.TestLinkClient(connection, dbType).CommitTran();
                return "success";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 测试连接串是否正确
        /// </summary>
        /// <param name="connection">连接串</param>
        /// <param name="dbType">数据库类型</param>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public async Task<Response<bool>> TestDataBaseLink(string connection, string dbType, string id)
        {
            if (!string.IsNullOrEmpty(id) && connection == "******")
            {
                Repository.Domain.SysDatabaseLink entity = await this.Repository.GetByIdAsync(id);
                if (entity != null)
                {
                    connection = entity.DBConnection;
                }
            }
            string res = TestConnection(connection, dbType);
            var flag = false;
            if (res == "success")
            {
                flag = true;
            }
            return new Response<bool>
            {
                Result = flag,
                Message = flag == true ? "连接成功" : "连接失败"
            };
        }
        #endregion
    }
}
