using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ExcelDataReader;
using GxPress.Auth;
using GxPress.Common.Exceptions;
using GxPress.Common.Page;
using GxPress.Entity;
using GxPress.Repository.Interface;
using GxPress.Request.User;
using GxPress.Result.User;
using GxPress.Service.Interface;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace GxPress.Api.AdminControllers
{
    /// <summary>
    /// 用户
    /// </summary>
    [Route("/api/admin/user")]
    [ApiController]
    [Authorize]
    public class AdminUserController : ControllerBase
    {
        private readonly JwtOptions _jwtOptions;
        private readonly ILogger<AdminUserController> _logger;
        private readonly IUserRepository _userRepository;
        private readonly IDepartmentRepository _departmentRepository;
        private readonly IUserService _userService;

        public AdminUserController(IUserRepository userRepository, IOptions<JwtOptions> jwtOptions,
            ILogger<AdminUserController> logger, IDepartmentRepository departmentRepository, IUserService userService)
        {
            _userRepository = userRepository;
            _departmentRepository = departmentRepository;
            _jwtOptions = jwtOptions.Value;
            _logger = logger;
            _userService = userService;
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task<User> Add([FromBody] User request)
        {
            if (!string.IsNullOrEmpty(request.Description) && request.Description.Length > 500)
            {
                throw new Exception("保存失败,字符数不能超出500");
            }
            request.Id = await _userRepository.InsertAsync(request);
            if (request.Id > 0)
            {
                //添加环信
                await _userRepository.CreateMiUserAsync(request);
            }
            return request;
        }



        /// <summary>
        /// 用户详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<User> GetDetail(int id)
        {
            return await _userRepository.GetAsync(id);
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task<bool> Delete(int id)
        {
            return await _userRepository.DeleteAsync(id);
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="userIds"></param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<bool> Delete([FromBody] IEnumerable<int> userIds)
        {
            return await _userService.DeleteUsersAsync(userIds);
        }

        /// <summary>
        /// 更新用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task<bool> Update(int id, [FromBody] UserInfoRequest request)
        {
            if (!string.IsNullOrEmpty(request.Description) && request.Description.Length > 500)
            {
                throw new Exception("保存失败,字符数不能超出500");
            }
            return await _userRepository.UpdateAsync(id, request);
        }

        /// <summary>
        /// 分页列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("page")]
        public async Task<PagedList<UserResult>> GetPagedList([FromBody] UserPageSearchRequest request)
        {
            var result = await _userService.GetPagedListAsync(request);
            return result;
        }
        [HttpPost("list")]
        public async Task<PagedList<User>> GetListAsync([FromBody] UserPageSearchRequest request)
        {

            var result = await _userService.GetPageListAsync(request);
            foreach (var item in result.Items)
            {

                if (item.IsRenewal)
                    item.Remark = "自动续费";
                else if (item.EndTime < DateTime.Now)
                    item.Remark = "已过期";
                else
                    item.Remark = "在费";
            }
            return result;
        }

        /// <summary>
        /// 分页列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("all")]
        public async Task<List<UserResult>> GetList([FromBody] ArticleSearchRequest request)
        {
            var result = await _userRepository.GetListAsync(request);
            return result;
        }

        /// <summary>
        /// 修改用户角色
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("actions/change_role")]
        public async Task<bool> ChangeRole([FromBody] UserChangeRoleRequest request)
        {
            return await _userRepository.ChangeRoleAsync(request.UserIds, request.RoleId);
        }

        /// <summary>
        /// 修改用户角色
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("actions/change_department")]
        public async Task<bool> ChangeDepartment([FromBody] UserChangeDepartmentRequest request)
        {
            return await _userRepository.ChangeDepartmentAsync(request.UserIds, request.DepartmentId);
        }

        /// <summary>
        /// 分析Excel数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("upload_user")]
        public async Task<bool> UserExcelUpload([FromBody] UserExcelUploadRequest request)
        {
            if (request.DepartmentId == 0)
                throw new BusinessException("请选择部门");
            var relativePath = request.ExcelUrl;
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            //获取excel分析
            var stream = System.IO.File.Open("wwwroot/" + relativePath, FileMode.Open, FileAccess.Read);
            IExcelDataReader reader = ExcelReaderFactory.CreateReader(stream);
            var result = reader.AsDataSet();
            var sheet = result.Tables["Sheet1"];
            var error = string.Empty;
            var listUser = new List<User>();
            for (int i = 1; i < sheet.Rows.Count; i++) //行
            {
                var user = new User();
                if (i == 1)
                    continue;
                var name = sheet.Rows[i][1].ToString().Trim(); //姓名
                if (string.IsNullOrEmpty(name))
                    error = "姓名必填";
                user.Name = name;
                var phone = sheet.Rows[i][2].ToString().Trim(); //手机号码
                if (phone.Length != 11)
                    error = "手机号码有误";
                user.Phone = phone;
                var email = sheet.Rows[i][3].ToString().Trim(); //邮箱
                if (!string.IsNullOrWhiteSpace(email))
                {
                    if (email.Contains("@"))
                        email = email.Replace("@", "@");
                    if (!GxPress.Common.Tools.VerifyHelper.IsEmailValid(email))
                        error = "邮箱有误";
                }
                user.Email = email;
                user.DepartmentId = request.DepartmentId;
                var sex = sheet.Rows[i][4].ToString().Trim(); //性别
                user.Gender = sex == "男" ? "Male" : "Female";
                var city = sheet.Rows[i][5].ToString().Trim(); //城市
                user.City = city;
                var isLeader = sheet.Rows[i][6].ToString().Trim(); //是否部门负责人
                var entryDataTime = sheet.Rows[i][7].ToString().Trim(); //入职时间
                user.IsLeader = isLeader == "是" ? true : false;
                if (!string.IsNullOrEmpty(entryDataTime))
                    user.EntryDataTime = DateTime.Parse(entryDataTime);
                if (!string.IsNullOrEmpty(error))
                    break;
                listUser.Add(user);
            }
            //判断重复
            foreach (var user in listUser)
                if (listUser.Count(n => n.Email == user.Phone) > 1)
                    throw new BusinessException("手机有重复请检查");
            if (!string.IsNullOrEmpty(error)) throw new BusinessException(error);
            //计算
            await _userRepository.UpdateUserExcelAsync(listUser);
            return true;
        }
        /// <summary>
        /// 筛选用户导出
        /// </summary>
        /// <param name="userIds"></param>
        /// <returns></returns>
        [HttpPost("excel")]
        public async Task<FileStreamResult> ExcelUser(List<int> userIds)
        {
            if (userIds.Count == 0)
                throw new BusinessException("请选择用户");
            var fileName = await _userService.ExcelUserAsync(userIds);
            return File(new FileStream(fileName, FileMode.Open), "application/octet-stream", "员工数据.xls");
        }

        /// <summary>
        /// vip管理
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("vip")]
        public async Task<PagedList<UserDetail>> GetUserVipDetail(UserSearchVipRequest request)
        {
            var result = await _userRepository.GetUserVipDetail(request);
            foreach (var item in result.Items)
            {
                if (item.IsRenewal)
                    item.VipStatus = 1;
                if (item.EndTime < DateTime.Now)
                    item.VipStatus = 3;
                else
                    item.VipStatus = 2;
            }
            return result;
        }
        /// <summary>
        /// 修改用户黑名单
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPut("update-disable")]
        public async Task<bool> UpdateUserAsync(UserUpdateDisableRequest request)
        {
            return await _userRepository.UpdateDisableAsync(request);
        }
    }
}