using BBM.ChatGLM.Dtos;
using BBM.ChatGLM.User;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using OfficeOpenXml;
using System;
using System.IO;
using System.Text.RegularExpressions;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Identity;


namespace BBM.ChatGLM.Controllers
{
    [Route("User")]
    public class UserController : ChatGLMController, IUsersAppService
    {
        private readonly IUsersAppService _usersAppService;
        private readonly IConfiguration _configuration;
        public UserController(IUsersAppService usersAppService, IConfiguration configuration)
        {
            _usersAppService = usersAppService;
            _configuration = configuration;
        }

        [HttpPost("create")]
        public async Task<IdentityUserDto> CreateAsync([FromBody] UserCreateInput input)
        {
            return await _usersAppService.CreateAsync(input);
        }

        [HttpPost("delete")]
        public async Task<bool> DeleteAsync([FromBody] GuidIdInput input)
        {
            return await _usersAppService.DeleteAsync(input);
        }

        [HttpPost("update")]
        public async Task<IdentityUserDto> UpdateAsync([FromBody] UserUpdateInput input)
        {
            return await _usersAppService.UpdateAsync(input);
        }

        [HttpPost("reset")]
        public async Task<bool> ResetPasswordAsync([FromBody] UserResetPasswordInput input)
        {
            return await _usersAppService.ResetPasswordAsync(input);
        }

        [HttpPost("page")]
        public async Task<PagedResultDto<UserDto>> PageAsync([FromBody] UserPageInput input)
        {
            return await _usersAppService.PageAsync(input);
        }

        [HttpPost("roles")]
        public async Task<List<string>> GetRolesAsync()
        {
            return await _usersAppService.GetRolesAsync();
        }

        [HttpPost("token")]
        public async Task<string> GetTokenAsync()
        {
            return await _usersAppService.GetTokenAsync();
        }

        [HttpPost("excelFile")]
        public async Task<IActionResult> UploadExcel([FromForm] IFormFile file)
        {
            /**
             * [FromForm] 
             *  操作步骤
             *      1、React中，使用antd的Upload组件来上传Excel表格数据，并且在上传之前需要将表格数据转换成FormData。
             *      2、在ASP.NET中，建立一个Controller用于接收上传的文件，并且使用[HttpPost]属性来指定使用POST方法接收请求。
             *      3、在Controller中，使用IFormFile接口来接收上传的Excel文件，然后使用EPPlus等工具来读取Excel文件数据
             *      4、将读取到的Excel数据进行处理，例如存储到数据库中或者进行数据分析等操作
             */

            Dtos.Results xiangying = new Dtos.Results();
            var failNum = 0;
            
            if (file == null)
                return BadRequest("Excel文件为空");

            string directoryPath = Environment.CurrentDirectory + @"\Excels";
            if (!Directory.Exists(directoryPath))
                Directory.CreateDirectory(directoryPath);
            
            var filePath = Path.Combine(directoryPath, file.FileName);

            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }

            using (var package = new ExcelPackage(new FileInfo(filePath)))
            {
                var worksheet = package.Workbook.Worksheets["sheet1"];                                                         
                var totalRows = worksheet.Dimension.Rows;
                var row = 2;

                
                var userName    = "";
                var phoneNumber = "";
                var userRole    = "";

                while (row <= totalRows)
                {
                    try
                    {
                        userName = worksheet.Cells[row, 1].Value?.ToString() ?? "";
                        phoneNumber = worksheet.Cells[row, 2].Value?.ToString() ?? "";
                        userRole = worksheet.Cells[row, 3].Value?.ToString() ?? "";

                        if (userName == "" || phoneNumber == "" || userName.Length>50 || userRole == "" || (userRole != "普通用户" && userRole != "管理员"))         
                        {
                            failNum++;
                        }
                        else
                        {
                            if (!Regex.IsMatch(phoneNumber, @"^(133|153|189|180|181|177|173|199|174|141
                                                           |139|138|137|136|135|134|159|158|157|150|151|152|147|188|187|182|183|184|178|198
                                                           |130|131|132|146|156|155|166|186|185|145|175|176
                                                           |170|171
                                                           |123)\d{8}$"))
                            {
                                failNum++;
                            }
                            else
                            {
                                var password = "Zs" + phoneNumber.Substring(phoneNumber.Length - 6);                              

                                if (userRole == "管理员")
                                {
                                    userRole = "admin";
                                }

                                UserCreateInput userInput = new UserCreateInput();
                                userInput.Name = userName;
                                userInput.UserName = userName;
                                userInput.Password = password;
                                userInput.Role = userRole;
                                userInput.IsActive = true;
                                
                                await _usersAppService.CreateAsync(userInput);
                                continue;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        failNum++;
                    }
                    finally
                    {
                        row++;
                    }
                }


                xiangying.SuccessNum = (totalRows-1) - failNum;
                xiangying.FailNum    = failNum;
                package.Dispose();
            }

            return Ok(xiangying);
        }

    }
}
