using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.EntitiesExtension;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.BaseInfo.Models;
using Hncore.Pass.BaseInfo.Request;
using Hncore.Pass.BaseInfo.Request.User;
using Hncore.Pass.BaseInfo.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Hncore.Pass.BaseInfo.Controllers
{
    [ApiVersion("1.0")]
    [Route("api/baseinfo/v{version:apiVersion}/user/[action]")]
    public class UserController : HncoreControllerBase
    {
        private UserService _userService;
        private WxAppUserService m_WxAppUserService;
        private IConfiguration _Configuration;
        private UserScoreService m_UserScoreService;
        public UserController(UserService userService, UserScoreService _UserScoreService, WxAppUserService _WxAppUserService, IConfiguration configuration)
        {
            _userService = userService;
            _Configuration = configuration;
            m_WxAppUserService = _WxAppUserService;
            m_UserScoreService = _UserScoreService;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<ApiResult> WxLogin([FromBody] WxLoginRequest request)
        {
            return Success(await _userService.LoginAndBindWx(request));
        }


        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<ApiResult> WebLogin([FromBody] LoginRequest request)
        {
            return Success(await _userService.Login(request));
        }


        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> Post([FromBody]PostUserRequest request)
        {
            var entity = request.MapTo<User>();
            entity.CreateType = UserCreateType.ManagerAdd;
            return await _userService.Regist(entity);
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> Put([FromBody]PostUserRequest request)
        {
            var userEntity = await _userService.GetById(request.Id);
            userEntity.Phone = request.Phone;
            userEntity.QQ = request.QQ;
            userEntity.Wx = request.Wx;
            userEntity.TaoBao = request.TaoBao;
            userEntity.Email = request.Email;
            if (request.Password.Has()) {
                userEntity.Password =UserService.HashPassword(request.Password);
            }
            var ret= await _userService.Update(userEntity);
            if (ret)
            {
                return Success("设置成功");
            }
            else
            {
                return Error("设置失败");
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> Delete([FromQuery]int id)
        {
            var flag = await _userService.DeleteById(id);
            if (flag)
                return Success();
            else
                return Error("删除失败");
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>

        [HttpGet]
        public async Task<ApiResult> Page([FromQuery]PageRequestBase request)
        {
            var ret = await _userService.PageDesc(request.PageIndex, request.PageSize,
                m=> request.KeyWord.NotHas()
                ||m.LoginCode.Contains(request.KeyWord)
                || m.Phone.Contains(request.KeyWord)
                || m.Name.Contains(request.KeyWord),true,m=>m.Id);
            ret.List.ForEach(
                m => {m.Password = "";
                // m.LoginCode = m.LoginCode.Substring(0,3) + "***";
                if(m.id_code.Length > 3){
                    m.id_code = m.id_code.Substring(0,6) + "***";
                    if(m.is_verify == 1){
                        m.Remark = "认证成功";
                    } else {
                        m.Remark = "认证失败";
                    }
                } else {
                    m.Remark = "未认证";
                }
            });

            var data = ret.ToApiResult();

            return data;
        }

        [HttpGet]
        public async Task<ApiResult> Search([FromQuery]QueryUserRequest request)
        {
            Expression<Func<User, bool>> exp = (m) => 1 == 1;
            if (request.All.HasValue && request.All == 0)
            {
                exp = exp.And(m => m.ManagerId == 0);
            }
            if (request.KeyWord.Has())
            {
                exp = exp.And(m => m.Phone.Contains(request.KeyWord));
            }

            var ret = await _userService.PageDesc(request.PageIndex, request.PageSize, exp, true, m => m.Id);
            ret.List.ForEach(m => m.Password = "");
            var data = ret.ToApiResult();
            return data;

        }

        [HttpGet]
        public async Task<ApiResult> SearchInfo([FromQuery]PageRequestBase request)
        {
            if (request.KeyWord.Has())
            {
                var ret = await _userService.PageDesc(request.PageIndex, 50,
                    m => m.LoginCode== request.KeyWord
                      || m.Phone== request.KeyWord, true, m => m.Id);
                ret.List.ForEach(
                m => {m.Password = "";
                if(m.id_code.Length > 3){
                    m.id_code = m.id_code.Substring(0,6) + "***";
                    if(m.is_verify == 1){
                        m.Remark = "认证成功";
                    } else {
                        m.Remark = "认证失败";
                    }
                } else {
                    m.Remark = "未认证";
                }
            });
                var data = ret.ToApiResult();
                return data;
            }
            return Error("请输入关键字");

        }

        public async Task<ApiResult> UpdateAmount([FromBody] UpdateAmountRequest request)
        {
            request.OperateUserName = this.Request.GetManageUserInfo().LoginName;
            return await _userService.UpdateAmount(request);
        }

        public async Task<ApiResult> UpdateTestCount([FromBody] UpdateTestCountRequest request)
        {
            var userEntity = await _userService.GetById(request.UserId);
            userEntity.TestCountLimit = request.Limit;
            await _userService.Update(userEntity);
            return Success();
        }

        //public async Task<ApiResult> ChargeByTaoBao([FromBody] UpdateAmountRequest request)
        //{
        //    return await _userService.UpdateAmount(request);
        //}

        [HttpGet]
        public async Task<ApiResult> AmountDetail([FromQuery] int userId)
        {
            var model = await m_UserScoreService.Details(userId);
            return Success(model);
        }

        [HttpGet]
        public async Task<ApiResult> AmountDetails([FromQuery] QueryAmountRequest request)
        {
            var model = await m_UserScoreService.Details(request);
            // model.List.ForEach(
            //     m => {m.UserName = m.UserName.Substring(0,3) + "***";
            // });
            return model.ToApiResult();           
        }

        [HttpGet]
        public async Task<IActionResult> ExportAmount([FromQuery]QueryAmountRequest request)
        {
            var model = await m_UserScoreService.DetailsAll(request);


            var data = new ExcelData<UserScore>
            {
                SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
                Data = model
            };

            var title = new List<ExcelTitle>(){
                    new ExcelTitle { Property = "CreateTime", Title = "创建日期",Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd hh:mm:ss") },
                    new ExcelTitle { Property = "UserName", Title = "用户" },
                    new ExcelTitle { Property = "OperateUserName", Title = "操作人员" },
                    new ExcelTitle { Property = "ScoreTypeName", Title = "资金项目" },
                    new ExcelTitle { Property = "ScoreValue", Title = "金额" },                 
                    new ExcelTitle { Property = "Remark", Title = "备注" },                 
                    new ExcelTitle { Property = "RestAmount1", Title = "操作前金额" },                 
                    new ExcelTitle { Property = "RestAmount2", Title = "操作后金额" }                 
                };
            var fileBytes = ExcelHelper.ExportListToExcel(data, title);

            var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}资金明细.xlsx";
            Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
            return File(fileBytes, "application/octet-stream", fileName);

        }


        [HttpGet]
        public async Task<IActionResult> Export()
        {
            var ret = await _userService.GetAll(true);
          
            var data = new ExcelData<User>
            {
                SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
                Data = ret
            };

            var title = new List<ExcelTitle>(){
                    // new ExcelTitle { Property = "LoginCode", Title = "手机号" },
                    new ExcelTitle { Property = "CreateTime", Title = "注册时间",Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd hh:mm:ss") },
                    new ExcelTitle { Property = "CreateType", Title = "注册方式", Format=(val)=>((UserCreateType)val).GetEnumDisplayName() },
                    new ExcelTitle { Property = "RestAmount", Title = "余额"},
                    new ExcelTitle { Property = "TestCountLimit", Title = "测试限额",Format=(val)=>((int)val)==0?3:(int)val },
                    new ExcelTitle { Property = "UseTestCount", Title = "领用数",Format=(val)=>((int)val)==0?3:(int)val },
                    // new ExcelTitle { Property = "Wx", Title = "微信"},
                    // new ExcelTitle { Property = "QQ", Title = "QQ"},
                    // new ExcelTitle { Property = "Email", Title = "Email"},
                    // new ExcelTitle { Property = "TaoBao", Title = "淘宝"},
                    // new ExcelTitle { Property = "WangWang", Title = "旺旺"},
                };
            var fileBytes = ExcelHelper.ExportListToExcel(data, title);

            var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}用户明细.xlsx";
            Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
            return File(fileBytes, "application/octet-stream", fileName);

        }

        [HttpPost]
        public async Task<ApiResult> SetManager([FromBody] SetManagerRequest request)
        {
            if (request.ManagerId == 0 || request.ManagerName.NotHas())
            {
                return Error("请选择客户经理");
            }

            if (request.UserIds == null || request.UserIds.Count() == 0)
            {
                return Error("请选择用户");
            }

            var users = await _userService.Query(m => request.UserIds.Contains(m.Id)).ToListAsync();

            if (users != null)
            {
                users.ForEach(m =>
                {
                    m.ManagerId = request.ManagerId;
                    m.ManagerName = request.ManagerName;
                });
                await _userService.Update(users);
            }
            return Success();
        }

        [HttpPost]
        public async Task<ApiResult> UpdateProfile([FromBody] UpdateProfileRequest request)
        {
            var userInfo = await _userService.GetById(request.UserId);
            userInfo.Profile = request.Profile;
            await _userService.Update(userInfo);
            return Success();
        }
    }
}