using System;
using System.Collections.Generic;
using System.Common;
using System.Common.Helpers;
using System.IRepositories;
using System.Linq;
using System.Linq.Expressions;
using System.Model;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using TVShoppingCallCenter_ZLJ.Models.Inputs.Traffic;

namespace TVShoppingCallCenter_ZLJ.Controllers.Traffic
{
    [Authorize]
    [Produces("application/json")]
    [Route("api/[controller]")]
    public class SetAreaController : BaseController
    {
        private readonly ISys_AreaRepository _sys_areaRepository;
        public SetAreaController(ISys_AreaRepository sys_areaRepository)
        {
            _sys_areaRepository = sys_areaRepository;
        }

        /// <summary>
        /// 返回树形下拉框 菜单数据 
        /// </summary>
        /// <returns></returns>
        [HttpGet("getall")]
        public async Task<IActionResult> GetALL(string code,int level = 0)
        {
            #region 筛选
            List<IConditionalModel> conModels = new List<IConditionalModel>();
            conModels.Add(new ConditionalModel() { FieldName = "F_State", ConditionalType = ConditionalType.Equal, FieldValue = ((int)EnumDelState.Enabled).ToString() });

            if (level > 0)
               conModels.Add(new ConditionalModel() { FieldName = "F_Level", ConditionalType = ConditionalType.LessThanOrEqual, FieldValue = level.ToString() });
            if (!string.IsNullOrWhiteSpace(code))
               conModels.Add(new ConditionalModel() { FieldName = "F_Code", ConditionalType = ConditionalType.LikeLeft, FieldValue = code });
            #endregion
            var list_ModuleInfo = await _sys_areaRepository.GetListALL(conModels, "F_Code asc");
            var treeList = new List<TreeModel>();
            foreach (var item in list_ModuleInfo)
            {
                TreeModel treeModel = new TreeModel();
                treeModel.id = item.F_Id;
                treeModel.code = item.F_Code;
                treeModel.iconcls = "";
                treeModel.text = item.F_AreaName;
                treeModel.parentid = item.F_ParentId.Value;
                treeList.Add(treeModel);
            }
            return Success("获取地区树成功", treeList.TreeRecursion(1));
        }
        [HttpGet("getallbypid")]
        public async Task<IActionResult> GetALLByPid(int pid = 1)
        {
            #region 筛选
            List<IConditionalModel> conModels = new List<IConditionalModel>();
            conModels.Add(new ConditionalModel() { FieldName = "F_State", ConditionalType = ConditionalType.Equal, FieldValue = ((int)EnumDelState.Enabled).ToString() });
                        
            conModels.Add(new ConditionalModel() { FieldName = "F_ParentId", ConditionalType = ConditionalType.Equal, FieldValue = pid.ToString() });
            #endregion
            var list_ModuleInfo = await _sys_areaRepository.GetListALL(conModels, "F_Code asc");
            var treeList = new List<TreeModel>();
            foreach (var item in list_ModuleInfo)
            {
                TreeModel treeModel = new TreeModel();
                treeModel.id = item.F_Id;
                treeModel.code = item.F_Code;
                treeModel.iconcls = "";
                treeModel.text = item.F_AreaName;
                treeModel.parentid = item.F_ParentId.Value;
                treeList.Add(treeModel);
            }
            return Success("获取地区树子节点成功", treeList);
        }


        /// <summary>
        /// 依据关键字获取相关菜单数据
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        [HttpGet("gettreegridjson")]
        public async Task<ActionResult> GetTreeGridJson(string keyword, int level = 0)
        {
            #region 筛选
            List<IConditionalModel> conModels = new List<IConditionalModel>();
            conModels.Add(new ConditionalModel() { FieldName = "F_State", ConditionalType = ConditionalType.Equal, FieldValue = ((int)EnumDelState.Enabled).ToString() });

            if (level > 0)
                conModels.Add(new ConditionalModel() { FieldName = "F_Level", ConditionalType = ConditionalType.LessThanOrEqual, FieldValue = level.ToString() });

            if (!string.IsNullOrEmpty(keyword))
            {
                conModels.Add(new ConditionalCollections()
                {
                    ConditionalList = new List<KeyValuePair<WhereType, ConditionalModel>>()
                    {
                        new  KeyValuePair<WhereType, ConditionalModel>(WhereType.And, new ConditionalModel() { FieldName = "F_Code", ConditionalType = ConditionalType.LikeLeft, FieldValue = keyword }),
                        new  KeyValuePair<WhereType, ConditionalModel>( WhereType.Or , new ConditionalModel() { FieldName = "F_Code", ConditionalType = ConditionalType.Equal, FieldValue = "0" })
                    }
                });
            }
            #endregion

            var list_ModuleInfo = await _sys_areaRepository.GetListALL(conModels, "F_Code asc");
            
            var treeList = new List<TreeGridModel>();
            foreach (var item in list_ModuleInfo)
            {
                TreeGridModel treeModel = new TreeGridModel();
                bool hasChildren = list_ModuleInfo.Count(t => t.F_ParentId == item.F_Id) == 0 ? false : true;
                treeModel.id = item.F_Id.ToString();
                treeModel.isLeaf = hasChildren;
                treeModel.parentId = item.F_ParentId.ToString();
                treeModel.expanded = hasChildren;
                treeModel.entityJson = item.ToJson();
                treeList.Add(treeModel);
            }
            return Content(treeList.TreeGridJson());
        }

        /// <summary>
        /// 获取实体
        /// </summary>
        [HttpGet("getdetails")]
        public async Task<IActionResult> GetDetails(int id)
        {
            if (id > 0)
            {
                var dModel = await _sys_areaRepository.GetSingle(x => x.F_Id == id && x.F_State == (int)EnumDelState.Enabled);

                if (dModel != null)
                {
                    return Success("获取成功", dModel);
                }
                else
                {
                    return Error("获取失败");
                }
            }
            else
            {
                return Error("获取参数失败");
            }
        }
        [HttpGet("getareasingle")]
        public async Task<IActionResult> GetAreasingle(int id)
        {
            var entity = await _sys_areaRepository.GetSingle(x => x.F_Id == id && x.F_State == (int)EnumDelState.Enabled);
            if (entity == null)
                return Error("加载失败");

            #region 转换数据格式
            var ids = await GetTypeIDAsync(entity.F_Id);
            List<int> idds = new List<int>();
            foreach (var item in ids.Split(','))
            {
                idds.Add(int.Parse(item));
            }
            #endregion
            var obj = new
            {
                model = entity,
                levelid = idds.ToArray(),
                levelname = (await GetTypeNameAsync(entity.F_Id)).Split(',')
            };

            return Success("加载成功", obj);
        }

        /// <summary>
        /// 添加
        /// </summary>
        [HttpPost("add")]
        public async Task<IActionResult> Add(AreaInput input)
        {
            #region 验证
            if (string.IsNullOrWhiteSpace(input.areaname))
            {
                return Error("地区名称不能为空");
            }
            if (input.areaname.Length > 40)
            {
                return Error("地区名称不能超过40");
            }
            if (input.code.Length > 20)
            {
                return Error("地区编号不能超过20");
            }
            #endregion
            T_Sys_Area clmodel = new T_Sys_Area();
            clmodel.F_AreaName = input.areaname;
            clmodel.F_Code = input.code;
            clmodel.F_ParentId = input.parentid;
            #region
            var pmodel = new T_Sys_Area();
            if (input.parentid <= 0)
            {
                clmodel.F_ParentCode = "0";
                clmodel.F_Level = 1;
            }
            else
            {
                pmodel = await _sys_areaRepository.GetSingle(x => x.F_Id == input.parentid && x.F_State == (int)EnumDelState.Enabled);
                if (pmodel != null)
                {
                    clmodel.F_ParentCode = pmodel.F_Code;
                    clmodel.F_Level = pmodel.F_Level + 1;
                }
                else
                    return Error("父级区域有误，请重新选择");
            }
            #endregion
            clmodel.F_Sort = input.sort;
            clmodel.F_Remark = input.remark;

            clmodel.F_CreateBy = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value; //"8000";
            clmodel.F_CreateOn = DateTime.Now;
            clmodel.F_State = (int)EnumDelState.Enabled;

            var res = await _sys_areaRepository.Add(clmodel);
            if (res > 0)
                return Success("保存成功");
            else
            {
                return Error("保存失败");
            }
        }

        /// <summary>
        /// 修改
        /// </summary>
        [HttpPost("update")]
        public async Task<IActionResult> Edit(AreaInput input)
        {
            #region
            if (input.id <= 0)
                return Error("请选择要编辑的数据");
            if (string.IsNullOrWhiteSpace(input.areaname))
            {
                return Error("地区名称不能为空");
            }
            #endregion

            var clmodel = await _sys_areaRepository.GetSingle(x => x.F_Id == input.id && x.F_State == (int)EnumDelState.Enabled);
            if (clmodel == null)
                return Error("信息获取失败");

            clmodel.F_AreaName = input.areaname;
            clmodel.F_Code = input.code;
            clmodel.F_ParentId = input.parentid;

            #region
            var pmodel= new T_Sys_Area();
            if (input.parentid <= 0)
            {
                clmodel.F_ParentCode = "0";
                clmodel.F_Level = 1;
            }
            else
            {
                pmodel = await _sys_areaRepository.GetSingle(x => x.F_Id == input.parentid && x.F_State == (int)EnumDelState.Enabled);
                if (pmodel != null)
                {
                    clmodel.F_ParentCode = pmodel.F_Code;
                    clmodel.F_Level = pmodel.F_Level + 1;
                }
                else
                    return Error("父级区域有误，请重新选择");
            }
            #endregion
            clmodel.F_Sort = input.sort;
            clmodel.F_Remark = input.remark;

            clmodel.F_LastModifyBy = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            clmodel.F_LastModifyOn = DateTime.Now;

            var res = await _sys_areaRepository.Update(clmodel);

            if (res)
                return Success("保存成功");
            else
            {
                return Error("保存失败");
            }
        }

        [HttpPost("delete")]
        public async Task<IActionResult> Remove(int[] ids)
        {
            //使用逻辑删除
            //物理删除的数据无法恢复
            var res = 0;
            if (ids != null && ids.Length > 0)
            {
                //获取选中的下所有级联子集id
                List<int> _ids = await GetTreeModuleId(new List<int>(ids));
                foreach (var item in _ids)
                {
                    var ml = await _sys_areaRepository.GetSingle(x => x.F_Id == item);
                    ml.F_State = (int)EnumDelState.Delete;
                    ml.F_DeleteOn = DateTime.Now.ToLocalTime();
                    ml.F_DeleteBy = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
                    if (_sys_areaRepository.Update(ml).Result)
                        res += 1;
                }
                if (res == _ids.Count ())
                    return Success("删除成功");
                else if (res > 0 && res < ids.Length)
                    return Error("部分删除失败，请查看后重新操作");
                else
                    return Error("删除失败，请查看后重新操作");
            }
            else
                return Error("请选择要删除的记录");
        }

        /// <summary>
        /// 导入地区
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("importarea")]
        public async Task<IActionResult> ImportArea()
        {
            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}");

            //将数据导入数据库
            int headrow = 0;
            NPOIHelper npoi = new NPOIHelper();
            var dtExcel = npoi.ExcelToTable1(_upfile, headrow);
            if (dtExcel.Rows.Count <= 0)
                return Error("请选择要导入的文件");

            IList<AreaInput> IDatas = ModelConvertHelper<AreaInput>.ConvertToModel(dtExcel);
            List<AreaInput> Datas = ModelConvertHelper<AreaInput>.ConvertIListToList(IDatas);
            int num = Datas.Count;
            List<AreaInput> inputlist = new List<AreaInput>();

            foreach (AreaInput input in Datas)
            {
                Expression<Func<T_Sys_Area, bool>> eq = a => a.F_Code == input.code;
                eq = eq.And(b => b.F_AreaName == input.areaname);
                if (await _sys_areaRepository.GetCount(eq) > 0)
                {
                    return Error("地区 有重复:" + input.areaname);
                }
                inputlist.Add(input);
            }
            if (await AddForInput(inputlist))
            {
                return Success("已导入数据");
            }
            else
            {
                return Error("导入失败");
            }

        }

        #region 私有方法
        /// <summary>
        /// 获取分类
        /// </summary>
        /// <param name="typeid"></param>
        /// <returns></returns>
        public async Task<string> GetTypeIDAsync(int id)
        {
            var typeinfo = await _sys_areaRepository.GetSingle(x => x.F_Id == id && x.F_State == (int)EnumDelState.Enabled);
            string type = string.Empty;
            if (typeinfo != null)
            {
                if (typeinfo.F_ParentId != null)
                {
                    type = await GetTypeIDAsync(typeinfo.F_ParentId.Value);
                }
                if (string.IsNullOrEmpty(type))
                {
                    type = typeinfo.F_Id.ToString();
                }
                else
                {
                    type += "," + typeinfo.F_Id.ToString();
                }
            }
            return type;
        }
        public async Task<string> GetTypeNameAsync(int id)
        {
            var typeinfo = await _sys_areaRepository.GetSingle(x => x.F_Id == id && x.F_State == (int)EnumDelState.Enabled);
            string type = string.Empty;
            if (typeinfo != null)
            {
                if (typeinfo.F_ParentId != null)
                {
                    type = await GetTypeNameAsync(typeinfo.F_ParentId.Value);
                }
                if (string.IsNullOrEmpty(type))
                {
                    type = typeinfo.F_AreaName;
                }
                else
                {
                    type += "," + typeinfo.F_AreaName;
                }
            }
            return type;
        }
        /// <summary>
        /// 获取所有子节点的Id
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        private async Task<List<int>> GetTreeModuleId(List<int> ids)
        {
            List<int> _moduleIdlist = null;
            List<int> _list = new List<int>(ids);
            var list_ModuleInfo = await _sys_areaRepository.GetListALL(x => x.F_State == (int)EnumDelState.Enabled);//DataSet  不在此处添加搜素条件，是因为计划改为缓存
            for (int i = 0; i < ids.Count; i++)
            {
                _moduleIdlist = list_ModuleInfo.Where(x => x.F_ParentId == ids[i]).Select(x => x.F_Id).ToList();
                if (_moduleIdlist.Count > 0)
                {
                    _list.AddRange(_moduleIdlist);
                    _list.AddRange(await GetTreeModuleId(_moduleIdlist));
                    _list = _list.Distinct().ToList();
                }
            }
            return _list;
        }
        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="inputs"></param>
        /// <returns></returns>
        private async Task<bool> AddForInput(List<AreaInput> inputs)
        {
            List<T_Sys_Area> inputlist = new List<T_Sys_Area>();
            foreach (var input in inputs)
            {
                T_Sys_Area clmodel = new T_Sys_Area();
                clmodel.F_AreaName = input.areaname;
                clmodel.F_Code = input.code;
                clmodel.F_ParentCode = input.parentcode;
                clmodel.F_ParentId = input.parentid;
                clmodel.F_Level = input.level;
                clmodel.F_Sort = input.sort;
                clmodel.F_Remark = input.remark;

                clmodel.F_CreateBy = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value; //"8000";
                clmodel.F_CreateOn = DateTime.Now;
                clmodel.F_State = (int)EnumDelState.Enabled;
                inputlist.Add(clmodel);
            }
            if (await _sys_areaRepository.AddMany(inputlist))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion
    }
}