using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EquipmentApi.IRepositories;
using MadRunFabric.Model;
using MadRunFabric.Common;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using EquipmentApi.Model.Input;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Configuration;
using System.Security.Claims;
using System.Reflection;
using Api.SignToken;
using AutoMapper;

namespace EquipmentApi.Controllers
{
    /// <summary>
    /// 项目通讯录控制器，对项目信息的操作
    /// </summary>
    [Authorize]
    [ApiVersion("6.0")]
    [Produces("application/json")]
    [Route("api/[controller]")]
    public class ProjectUserController : BaseController
    {
        private readonly ILogger<ProjectUserController> _logger;
        private readonly IConfiguration _configuration;
        private readonly ISys_User_AccountRepository _sys_user_accountRepository;
        private readonly IPro_Project_UserRepository _pro_project_userRepository;
        private readonly ISignTokenService _signTokenService;
        private readonly IMapper _mapper;

        public ProjectUserController(
            ILogger<ProjectUserController> logger,
            IConfiguration configuration,
            ISys_User_AccountRepository sys_user_accountRepository,
            IPro_Project_UserRepository project_infoRepository,
            ISignTokenService signTokenService, IMapper mapper)
        {
            _logger = logger;
            _configuration = configuration;
            _sys_user_accountRepository = sys_user_accountRepository;
            _pro_project_userRepository = project_infoRepository;
            _signTokenService = signTokenService;
            _mapper = mapper;
        }

        /// <summary>
        /// 项目通讯录列表 by page
        /// </summary>
        /// <param name="apptype">应用分类（0android 1ios）</param>
        /// <param name="keyword">版本编号</param>
        /// <param name="createtime">添加开始时间</param>
        /// <param name="createtime">添加结束时间</param>
        /// <param name="pageindex">当前页</param>
        /// <param name="pagesize">每页条数</param>
        /// <returns></returns>
        [HttpGet("getlistbypage")]
        public async Task<IActionResult> GetListsByPageAsync(string keyword, string stime, string etime, int type = 0, int pageindex = 1, int pagesize = 10)
        {
            #region 条件信息
            ////排序字段
            var sort = Builders<Pro_Project_User>.Sort.Descending("createtime");

            //根据条件查询集合
            var listApp = new List<FilterDefinition<Pro_Project_User>>();
            listApp.Add(Builders<Pro_Project_User>.Filter.Eq("isdelete", 0));
            if (!string.IsNullOrEmpty(stime))
                listApp.Add(Builders<Pro_Project_User>.Filter.Gt("createtime", stime));
            if (!string.IsNullOrEmpty(etime))
                listApp.Add(Builders<Pro_Project_User>.Filter.Lt("createtime", etime));
            if (type > 0)
                listApp.Add(Builders<Pro_Project_User>.Filter.Eq("type", type));
            //模糊查询(项目名称，项目属性，项目负责人)
            if (!string.IsNullOrEmpty(keyword))
                listApp.Add(Builders<Pro_Project_User>.Filter.Where(s => s.name.Contains(keyword) || s.mobilephone.Contains(keyword) || s.telephone.Contains(keyword)));
            #endregion

            string nowusercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            //var userstr = _signTokenService.GetUserInfoAsync(nowusercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();

            
            var userinfos = _sys_user_accountRepository.GetUserInfo(nowusercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());
            if (userinfo.isallproject == 0)
                listApp.Add(Builders<Pro_Project_User>.Filter.Where(s => userinfo.projectlist.Contains(s.projectid)));

            int recordCount = 0;

            var filter = Builders<Pro_Project_User>.Filter.And(listApp);
            var list = await _pro_project_userRepository.GetByPage(filter, pageindex, pagesize, sort);
            var redCount = await _pro_project_userRepository.CountAsync(filter);   //获取总数

            recordCount = int.Parse(redCount.ToString());

            var obj = new
            {
                rows = list,
                total = recordCount,
            };
            return Success("获取成功", obj);
        }

        /// <summary>
        /// 项目通讯录列表 - 关联查询
        /// </summary>
        /// <returns></returns>
        [HttpGet("getlistsbypage")]
        public IActionResult GetListsByPage(string keyword, string projectid, string stime, string etime, int type = 0, int pageIndex = 1, int pageSize = 10)
        {
            string nowusercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            //var userstr = _signTokenService.GetUserInfoAsync(nowusercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();

            
            var userinfos = _sys_user_accountRepository.GetUserInfo(nowusercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            int recordCount = 0;
            var result = _pro_project_userRepository.GetListsByPage(keyword,projectid, stime, etime, type, userinfo, pageIndex, pageSize, out recordCount);
            var obj = new
            {
                rows = result,
                total = recordCount,
            };
            return Success("获取成功", obj);
        }

        /// <summary>
        /// 项目通讯录列表 - app关联查询
        /// </summary>
        /// <returns></returns>
        [HttpGet("getapplists")]
        public IActionResult GetAppLists(string keyword, int type = 0)
        {
            string nowusercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            //var userstr = _signTokenService.GetUserInfoAsync(nowusercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();

            
            var userinfos = _sys_user_accountRepository.GetUserInfo(nowusercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            var result = _pro_project_userRepository.GetAppLists(keyword, type, userinfo);
            return Success("获取成功", result);
        }

        /// <summary>
        /// 项目通讯录详情 by id
        /// </summary>
        /// <param name="id">项目id</param>
        /// <returns></returns>
        [HttpGet("getdetailes")]
        public async Task<IActionResult> GetDetailsAsync(string id)
        {
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");

            var model = await _pro_project_userRepository.GetSingle(id);

            return Success("获取成功！", model);
        }

        /// <summary>
        /// 获取项目通讯录详情 by id - 关联查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("getdetails")]
        public IActionResult GetDetails(string id)
        {
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = _pro_project_userRepository.GetDetails(id);
            if (model != null)
            {
                return Success("获取成功！", model);
            }
            return Error("获取失败");
        }

        /// <summary>
        /// 添加项目信息
        /// </summary>
        /// <param name="input">项目参数</param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task<IActionResult> AddAsync(ProjectUserInput input)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            #region 验证判断
            if (string.IsNullOrEmpty(input.name))
                return Error("名称不能为空");
            if (string.IsNullOrEmpty(input.projectid))
                return Error("项目不能为空");
            #endregion
            var model = new Pro_Project_User();
            model.name = input.name;
            model.projectid = input.projectid;
            model.type = input.type;
            model.sex = input.sex;
            model.mobilephone = input.mobilephone;
            model.telephone = input.telephone;
            model.imgurl = input.imgurl;
            model.imgsmallurl = input.imgsmallurl;
            model.department = input.department;
            model.position = input.position;
            model.remark = input.remark;
            model.createby = usercode;
            model.createtime = DateTime.Now.ToLocalTime();
            model.isdelete = 0;

            bool b = await _pro_project_userRepository.Add(model);
            if (b)
                return Success("添加成功");
            return Error("添加失败");
        }

        /// <summary>
        /// 修改项目信息
        /// </summary>
        [HttpPost("update")]
        public async Task<IActionResult> UpdateAsync(ProjectUserInput input)
        {
            #region 验证判断
            if (string.IsNullOrEmpty(input.name))
                return Error("名称不能为空");
            if (string.IsNullOrEmpty(input.projectid))
                return Error("项目不能为空");
            #endregion
            var model = new Pro_Project_User();
            model = await _pro_project_userRepository.GetSingle(input.id);
            if (model == null)
                return Error("操作失败");
            model.name = input.name;
            model.projectid = input.projectid;
            model.type = input.type;
            model.sex = input.sex;
            model.mobilephone = input.mobilephone;
            model.telephone = input.telephone;
            model.imgurl = input.imgurl;
            model.imgsmallurl = input.imgsmallurl;
            model.department = input.department;
            model.position = input.position;
            model.remark = input.remark;

            bool b = await _pro_project_userRepository.Update(model);
            if (b)
                return Success("保存成功");
            return Error("保存失败");
        }

        /// <summary>
        /// 删除通讯录信息 by ids
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpPost("delete")]
        public async Task<IActionResult> Remove(string[] ids)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            var res = 0;
            if (ids != null && ids.Length > 0)
            {
                foreach (var item in ids)
                {
                    var ml = await _pro_project_userRepository.GetSingle(item);
                    ml.isdelete = 1;
                    ml.deleteby = usercode;
                    ml.deletetime = DateTime.Now.ToLocalTime();
                    if (_pro_project_userRepository.Update(ml).Result)
                        res += 1;
                }
                if (res == ids.Length)
                    return Success("删除成功");
                else if (res > 0 && res < ids.Length)
                    return Error("部分删除失败，请查看后重新操作");
                else
                    return Error("删除失败，请查看后重新操作");
            }
            else
                return Error("请选择要删除的记录");
        }

        /// <summary>
        /// 删除项目通讯录信息 by 项目id
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpPost("deletebypid")]
        public async Task<IActionResult> RemoveByPID(string id, int type = -1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;

            var list = await _pro_project_userRepository.Get(p => p.projectid == id && (p.type == type || type == -1));
            foreach (var l in list)
            {
                l.isdelete = 1;
                l.deleteby = usercode;
                l.deletetime = DateTime.Now.ToLocalTime();
                await _pro_project_userRepository.Update(l);
            }

            return Success("删除成功");
        }

        /// <summary>
        /// 导出模板
        /// </summary>
        /// <returns></returns>
        [HttpGet("downtemplate")]
        [AllowAnonymous]
        public IActionResult DownTemplateAsync()
        {
            string mbname = _configuration["upload:txlmbname"].ToString();
            string mbkeys = _configuration["upload:txlmbkeys"].ToString();

            NPOIHelper npoi = new NPOIHelper();
            byte[] sm = npoi.ExportToExcelTemplate(mbkeys.Split(","));
            if (sm != null)
            {
                return File(sm, "application/vnd.ms-excel", mbname);
            }
            else
            {
                return Error("下载失败");
            }
        }

        /// <summary>
        /// 上传文件并将设备信息导入数据库
        /// </summary>
        /// <returns></returns>
        [HttpPost("importexcel")]
        public async Task<IActionResult> ImportExcel(string projectid,int type, int headrow = 0)
        {
            if (string.IsNullOrEmpty(projectid))
                return Error("项目不能为空");

            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;

            Microsoft.AspNetCore.Http.IFormFile _upfile = Request.Form.Files[0];
            if (!_upfile.ContentType.Equals("application/vnd.ms-excel") && !_upfile.ContentType.Equals("application/x-xls") && !_upfile.ContentType.Equals("application/x-xlsx") && !_upfile.ContentType.Equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") && !_upfile.ContentType.Equals("application/octet-stream"))
                return Error($"请正确上传Excel文件：file.ContentType={_upfile.ContentType}");

            NPOIHelper npoi = new NPOIHelper();
            var dtExcel = npoi.ExcelToTable1(_upfile, headrow);
            int num = dtExcel.Rows.Count;
            var cols = dtExcel.Columns;
            int colnum = cols.Count;

            string dbkeys = _configuration["upload:dbkeys"].ToString();
            string[] dbcols = dbkeys.Split(",");
            string errmsg = string.Empty;

            if (num > 0)
            {
                int index = 1;
                foreach (System.Data.DataRow dr in dtExcel.Rows)
                {
                    var model = new Pro_Project_User();

                    model.projectid = projectid;
                    model.type = type;
                    model.isdelete = 0;
                    model.createby = usercode;

                    var dbcolslist = dbcols.ToList();

                    Type t = model.GetType();
                    PropertyInfo[] PropertyList = t.GetProperties();

                    foreach (PropertyInfo item in PropertyList)
                    {
                        if (dbcolslist.Contains(item.Name))
                        {
                            object v = Convert.ChangeType(dr[dbcolslist.IndexOf(item.Name)].ToString(), item.PropertyType);
                            item.SetValue(model, v, null);
                        }
                    }

                    bool b = await _pro_project_userRepository.Add(model);
                    if (!b)
                    {
                        if (!string.IsNullOrEmpty(errmsg))
                        {
                            errmsg = errmsg + "\r\n第" + index + "行导入失败！";
                        }
                        else
                        {
                            errmsg = "第" + index + "行导入失败！";
                        }
                    }
                    index++;
                }
            }
            else
            {
                return Error("文件中无数据");
            }

            if (!string.IsNullOrEmpty(errmsg))
            {
                //删除已导入的部分
                return Error(errmsg);
            }

            return Success("导入成功");
        }
    }
}