using BPA.KitChen.GroupMeal.Application.BaseDto;
using BPA.KitChen.GroupMeal.Application.Service.Applet.Dtos;
using BPA.KitChen.GroupMeal.Application.Service.OneCard.StoredValueCard;
using BPA.KitChen.GroupMeal.Core.Common.Const;
using BPA.KitChen.GroupMeal.Core.Entity;
using BPA.KitChen.GroupMeal.SqlSugar;
using Furion;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace BPA.KitChen.GroupMeal.Application.Service.Applet
{

    [ApiDescriptionSettings("小程序管理", Tag = "页面管理", SplitCamelCase = false)]
    public class AppletService : SupperRepository, IDynamicApiController, IAppletService, ITransient
    {
        private readonly SqlSugarScope db;

        public AppletService()
        {
            db = SqlSugarDb.Db; ;   // 推荐操作
        }
        #region 页面管理
        /// <summary>
        /// 增加小程序页面
        /// </summary>
        /// <param name="input"></param>
        [HttpPost("/api/AppletService/add")]
        public async Task Add(AddMiniStorePageInput input)
        {

            MiniStorePage data = input.Adapt<MiniStorePage>();
            //var res = await db.Queryable<MiniStorePage>().FirstAsync(x => x.PageRoute == input.PageRoute);
            //if (res !=null)
            //{
            //    throw Oops.Bah("页面路由地址相同");
            //}
            data.FranchiseeId = App.User?.FindFirstValue(ClaimConst.GroupId);
            await db.Insertable(data).ExecuteCommandAsync();
        }

        /// <summary>
        /// 小程序页面分页查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/api/AppletService/page")]
        public async Task<SqlSugarPagedList<MiniStorePageOutput>> Page(QueryMiniStorePageInput input)
        {
            var datas = await db.Queryable<MiniStorePage>().Where(x => x.StoreId == input.StoreId).Select(o =>
                new MiniStorePageOutput
                {
                    StoreId = o.StoreId,
                    FranchiseeId = o.FranchiseeId,
                    PageName = o.PageName,
                    PageRoute = o.PageRoute,
                    Id = o.Id
                }).ToPagedListAsync(input.Current, input.PageSize);
            return datas;
        }

        /// <summary>
        /// 删除小程序页面
        /// </summary>
        [HttpPost("/api/AppletService/del")]
        public async Task Del(DelMiniStorePageInput input)
        {
            var data = await db.Queryable<MiniStorePage>().FirstAsync(x => x.Id == input.Id);
            if (data == null)
            {
                throw Oops.Bah("没有找到数据");
            }
            db.Deleteable<MiniStorePage>().Where(x => x.Id == input.Id).ExecuteCommand();
        }
        /// <summary>
        /// 小程序页面下拉列表
        /// </summary>
        /// <exception cref="System.NotImplementedException"></exception>
        [HttpGet("/api/AppletService/list")]
        public async Task<List<MiniStoreSelection>> List(QueryMiniStorePageInput input)
        {

            var datas = await db.Queryable<MiniStorePage>().WhereIF(!string.IsNullOrEmpty(input.StoreId), x => x.StoreId == input.StoreId).ToListAsync();
            var res = datas.Select(x => new MiniStoreSelection
            {
                Key = x.Id,
                Value = x.PageName
            }).ToList();
            return res;
        }

        /// <summary>
        /// 更新小程序页面
        /// </summary>
        /// <param name="input"></param>
        [HttpPost("/api/AppletService/update")]
        public async Task Update(UpdateMiniStorePageInput input)
        {
            var data = await db.Queryable<MiniStorePage>().FirstAsync(x => x.Id == input.Id);
            if (data == null)
            {
                throw Oops.Bah("没有找到数据");
            }
            data.PageName = input.PageName;
            data.PageRoute = input.PageRoute;
            data.StoreId = input.StoreId;
            db.Updateable(data).Where(x => x.Id == input.Id).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand();
        }
        #endregion

        #region 素材管理
        /// <summary>
        /// 页面素材添加
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        [HttpPost("/api/AppletService/MaterialAdd")]
        public async Task MaterialAdd(AddMiniStorePageMaterialInput input)
        {
            //var res = await db.Queryable<MiniStorePageConfig>().FirstAsync(x => x.MaterialCode == input.MaterialCode && x.PageId==input.PageId);
            //if (res != null)
            //{
            //    throw Oops.Bah("素材编码重复");
            //}
            MiniStorePageConfig data = input.Adapt<MiniStorePageConfig>();
            await db.Insertable(data).ExecuteCommandAsync();
        }

        /// <summary>
        /// 页面素材删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        [HttpPost("/api/AppletService/MaterialDel")]
        public async Task MaterialDel(DelMiniStorePageMaterialInput input)
        {
            var data = await db.Queryable<MiniStorePageConfig>().FirstAsync(x => x.Id == input.Id);
            if (data == null)
            {
                throw Oops.Bah("没有找到数据");
            }
            db.Deleteable<MiniStorePageConfig>().Where(x => x.Id == input.Id).ExecuteCommand();
        }


        /// <summary>
        /// 页面素材下拉列表
        /// </summary>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        [HttpGet("/api/AppletService/MaterialList")]
        public async Task<List<MiniStoreSelection>> MaterialList()
        {
            var datas = await db.Queryable<MiniStorePageConfig>().ToListAsync();
            var res = datas.Select(x => new MiniStoreSelection
            {
                Key = x.Id,
                Value = x.MaterialName
            }).ToList();
            return res;
        }

        /// <summary>
        /// 页面素材分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        [HttpPost("/api/AppletService/MaterialPage")]
        public async Task<SqlSugarPagedList<MiniStorePageMaterialOutput>> MaterialPage(QueryMiniStorePageMaterialInput input)
        {
            var datas = await db.Queryable<MiniStorePageConfig>().Where(x => x.PageId == input.PageId).Select(o =>
             new MiniStorePageMaterialOutput
             {
                 MaterialCode = o.MaterialCode,
                 MaterialName = o.MaterialName,
                 MaterialPath = o.MaterialPath,
                 PageId = o.PageId,
                 Id = o.Id
             }).ToPagedListAsync(input.Current, input.PageSize);
            return datas;
        }


        /// <summary>
        /// 页面素材更新
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        [HttpPost("/api/AppletService/MaterialUpdate")]
        public async Task MaterialUpdate(UpdateMiniStorePageMaterialInput input)
        {
            var data = await db.Queryable<MiniStorePageConfig>().FirstAsync(x => x.Id == input.Id);
            if (data == null)
            {
                throw Oops.Bah("没有找到数据");
            }
            //判断编码重复
            //var data1 = await db.Queryable<MiniStorePageConfig>().FirstAsync(x => x.Id != input.Id && x.MaterialCode == input.MaterialCode&& x.PageId != input.PageId);
            //if (data1!=null)
            //{
            //    throw Oops.Bah("编码重复");
            //}
            data.MaterialName = input.MaterialName;
            data.MaterialPath = input.MaterialPath;
            data.PageId = input.PageId;
            data.MaterialCode = input.MaterialCode;
            db.Updateable(data).Where(x => x.Id == input.Id).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand();
        }


        /// <summary>
        /// 根据店铺id查询页面布局素材
        /// </summary>
        /// <returns></returns>
        [HttpPost("/api/AppletService/MiniStoreMaterial")]
        [AllowAnonymous]
        public async Task<List<MiniStorePageConfigOutput>> MiniStoreMaterial(QueryMiniStorePageInput input)
        {
            List<MiniStorePageConfigOutput> outputs = new();
            var datas = await db.Queryable<MiniStorePage>().Where(x => x.StoreId == input.StoreId).ToListAsync();
            foreach (var item in datas)
            {
                MiniStorePageConfigOutput output = new();
                output.PageName = item.PageName;
                output.PageRoute = item.PageRoute;
                var lists = await db.Queryable<MiniStorePageConfig>().Where(x => x.PageId == item.Id).ToListAsync();
                foreach (var materialItem in lists)
                {
                    MiniStorePageMaterialOutput material = new();
                    material.MaterialName = materialItem.MaterialName;
                    material.MaterialPath = materialItem.MaterialPath;
                    material.PageId = materialItem.PageId;
                    material.MaterialCode = materialItem.MaterialCode;
                    material.Id = materialItem.Id;
                    output.List.Add(material);
                }
                outputs.Add(output);
            }

            return outputs;
        }
        #endregion


        #region 支付管理
        [HttpPost("/api/paytemplate/add")]
        public async Task<bool> Add(PayTemplateCreateOrUpdateInputDto inputDto)
        {
            try
            {
                db.Ado.BeginTran();
                var payTemplate = await db.Insertable(new BPA_PayTemplate()
                {
                    Name = inputDto.Name,
                }).CallEntityMethod(t => t.Create()).ExecuteReturnEntityAsync();

                var payTemplateIdInfo = new List<BPA_PayTemplateInfo>()
            {
                new BPA_PayTemplateInfo()
                {
                    AppId=inputDto.WXAppId,
                    Key=inputDto.WXKey,
                    PayTemplateId=payTemplate.Id,
                    PayType=1,
                    PrivateKey=inputDto.WXPrivateKey,
                    PubLicKey=inputDto.WXPubLicKey,
                    PId=inputDto.WXPId,

                },
                new BPA_PayTemplateInfo()
                {
                    AppId=inputDto.ZFBAppId,
                    Key=inputDto.ZFBKey,
                    PayTemplateId=payTemplate.Id,
                    PayType=2,
                    PrivateKey=inputDto.ZFBPrivateKey,
                    PubLicKey=inputDto.ZFBPubLicKey,
                    PId=inputDto.ZFBPId,
                }

            };


                var result = await db.Insertable(payTemplateIdInfo).CallEntityMethod(t => t.Create()).ExecuteCommandAsync() > 0;
                db.Ado.CommitTran();
                return result;
            }
            catch (Exception)
            {
                db.Ado.RollbackTran();
                return false;
            }
        }

        [HttpPost("/api/paytemplate/delete")]
        public async Task<bool> Delete(List<string> Ids)
        {
            var data = db.Queryable<BPA_PayTemplate>().Where(x => Ids.Contains(x.Id) && x.IsDeleted == 0).ToList();
            foreach (var item in data)
            {
                item.IsDeleted = 1;
            }
            var data2 = db.Queryable<BPA_PayTemplateInfo>().Where(x => data.Select(x => x.Id).ToList().Contains(x.PayTemplateId)).ToList();
            foreach (var item in data2)
            {
                item.IsDeleted = 1;
            }
            try
            {
                db.Ado.BeginTran();
                var result = await db.Updateable(data).CallEntityMethod(t => t.Delete()).ExecuteCommandHasChangeAsync();
                if (data2.Count > 0)
                {
                    await db.Updateable(data2).CallEntityMethod(t => t.Delete()).ExecuteCommandHasChangeAsync();
                }
                db.Ado.CommitTran();
                return result;
            }
            catch (Exception)
            {
                db.Ado.RollbackTran();
                return false;
            }

        }

        [HttpPost("/api/paytemplate/getPayTemplatePageList")]
        public async Task<PageUtil> GetPayTemplatePageList(PayTemplatePageInputDto inputDto)
        {
            int total = 0;
            var res = db.Queryable<BPA_PayTemplate>()
                .Where(x => x.IsDeleted == 0)
                .WhereIF(!string.IsNullOrEmpty(inputDto.Name),x=>x.Name.Contains(inputDto.Name))
                .Select(t => new PayTemplateOutDto
                {
                    Id = t.Id.SelectAll(),
                }).ToPageList(inputDto.Current, inputDto.PageSize, ref total);

            var data = db.Queryable<BPA_PayTemplateInfo>().Where(x => res.Select(x => x.Id).ToList().Contains(x.PayTemplateId)).ToList();
            foreach (var item in res)
            {
                item.PayTemplateOutDtoInfo = new List<PayTemplateOutDtoInfo>();
                foreach (var item2 in data)
                {
                    if (item.Id == item2.PayTemplateId)
                    {
                        item.PayTemplateOutDtoInfo.Add(new PayTemplateOutDtoInfo()
                        {
                            AppId = item2.AppId,
                            Id = item2.Id,
                            Key = item2.Key,
                            PayType = item2.PayType,
                            PId = item2.PId,
                            PrivateKey = item2.PrivateKey,
                            PubLicKey = item2.PubLicKey,
                        });
                    }

                }
            }
            PageUtil util = new PageUtil()
            {
                Total = total,
                Data = res

            };
            return util;
        }

        [HttpPost("/api/paytemplate/update")]
        public async Task<bool> Update(PayTemplateCreateOrUpdateInputDto inputDto)
        {
            var payTemplate = db.Queryable<BPA_PayTemplate>().First(x => x.Id == inputDto.Id && x.IsDeleted == 0);
            if (payTemplate == null) return false;
            payTemplate.Name = inputDto.Name;

            var payTemplateInfo = db.Queryable<BPA_PayTemplateInfo>().Where(x => x.PayTemplateId == inputDto.Id).ToList();
            foreach (var item in payTemplateInfo)
            {
                if (item.PayType == 1)
                {
                    item.AppId = inputDto.WXAppId;
                    item.Key = inputDto.WXKey;
                    item.PrivateKey = inputDto.WXPrivateKey;
                    item.PubLicKey = inputDto.WXPubLicKey;
                    item.PId = inputDto.WXPId;


                }
                else
                {
                    item.AppId = inputDto.ZFBAppId;
                    item.Key = inputDto.ZFBKey;
                    item.PrivateKey = inputDto.ZFBPrivateKey;
                    item.PubLicKey = inputDto.ZFBPubLicKey;
                    item.PId = inputDto.ZFBPId;
                }

            }
            try
            {
                db.Ado.BeginTran();
                var result = await db.Updateable(payTemplate).CallEntityMethod(t => t.Modify()).ExecuteCommandHasChangeAsync();
                await db.Updateable(payTemplateInfo).CallEntityMethod(t => t.Modify()).ExecuteCommandHasChangeAsync();
                db.Ado.CommitTran();
                return result;
            }
            catch (Exception)
            {
                db.Ado.RollbackTran();
                return false;
            }
        }
        #endregion

        #region appId
        [HttpPost("/api/appid/add")]
        public async Task<bool> AppidAdd(BPA_AppIdConfig inputDto)
        {
            try
            {
                var result = await db.Insertable(inputDto).CallEntityMethod(t => t.Create()).ExecuteCommandAsync() > 0;
                return result;
            }
            catch (Exception)
            {
                return false;
            }
        }

        [HttpPost("/api/appid/delete")]
        public async Task<bool> AppidDelete(List<string> Ids)
        {
            var data = db.Queryable<BPA_AppIdConfig>().Where(x => Ids.Contains(x.Id) && x.IsDeleted == 0).ToList();
            foreach (var item in data)
            {
                item.IsDeleted = 1;
            }
            try
            {
                db.Ado.BeginTran();
                var result = await db.Updateable(data).CallEntityMethod(t => t.Delete()).ExecuteCommandHasChangeAsync();
                db.Ado.CommitTran();
                return result;
            }
            catch (Exception)
            {
                db.Ado.RollbackTran();
                return false;
            }

        }

        [HttpPost("/api/appid/getappidpage")]
        public async Task<PageUtil> GetAppIdPage(PageInputBase inputDto)
        {
            int total = 0;
            var res = db.Queryable<BPA_AppIdConfig>()
                .Where(x => x.IsDeleted == 0)
                .Select(t => new BPA_AppIdConfig
                {
                    Id = t.Id.SelectAll(),
                }).ToPageList(inputDto.Current, inputDto.PageSize, ref total);

            PageUtil util = new PageUtil()
            {
                Total = total,
                Data = res

            };
            return util;
        }

        [HttpPost("/api/appid/update")]
        public async Task<bool> AppidUpdate(BPA_AppIdConfig inputDto)
        {
            var data = db.Queryable<BPA_AppIdConfig>().First(x => x.Id == inputDto.Id && x.IsDeleted == 0);
            if (data == null) return false;
            data.AppId = inputDto.AppId;
            try
            {
                var result = await db.Updateable(data).CallEntityMethod(t => t.Modify()).ExecuteCommandHasChangeAsync();
                return result;
            }
            catch (Exception)
            {
                db.Ado.RollbackTran();
                return false;
            }
        }
        #endregion



    }
}
