using System;
using System.Collections.Generic;
using System.Common;
using System.Common.Helpers;
using System.Data;
using System.IRepositories;
using System.IRepositories.Call;
using System.IRepositories.Sys;
using System.Linq;
using System.Model;
using System.Model.Call;
using System.Model.Sys;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Utility;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using SqlSugar;
using TVShoppingCallCenter_ZLJ.Models.Inputs.System;

namespace TVShoppingCallCenter_ZLJ.Controllers.AutoDial
{
    [Produces("application/json")]
    [Route("api/[controller]")]
    public class OutboundTaskController : BaseController
    {
        private readonly IConfiguration config;
        private readonly ISys_MobileDataRepository busMobileDataRepository;
        private readonly ISys_OutboundTaskReposity _sys_outboundTaskrepository;
        private readonly ItaskRepository _taskrepository;
        private readonly ISys_AutoDialRepository _sys_autodialrepository;
        public OutboundTaskController(ISys_OutboundTaskReposity sys_outboundTaskrepository
            , ISys_AutoDialRepository sys_autodialrepository, ItaskRepository taskrepository
            , IConfiguration _configuration, ISys_MobileDataRepository _busMobileDataRepository)
        {
            _sys_outboundTaskrepository = sys_outboundTaskrepository;
            _sys_autodialrepository = sys_autodialrepository;
            _taskrepository = taskrepository;
            config = _configuration;
            busMobileDataRepository = _busMobileDataRepository;
        }
       
       
        /// <summary>
        /// 添加外呼任务
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task<IActionResult> AddAsync(T_Sys_OutboundTask input)
        {
            if (string.IsNullOrEmpty (input.F_Name))
                return Error("请输入任务名称");
            string user = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            input.F_AddTime = DateTime.Now;
            input.F_AddUser = user;
            input.F_TaskUser = input .F_TaskUser ;
            input.F_IsDelete = 0;
            var res = await _sys_outboundTaskrepository.Add(input);
            if (res > 0)
            {
                return Success("添加成功");
            }
            else
            {
                return Error("添加失败");
            }
        }
        /// <summary>
        /// 修改外呼任务
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("update")]
        public async Task<IActionResult> UpdateAsync(T_Sys_OutboundTask input)
        {
            if (input.F_ID <= 0)
                return Error("参数错误");
            if (string.IsNullOrEmpty(input.F_Name))
                return Error("请输入任务名称");
            var model = await _sys_outboundTaskrepository.GetSingle(x => x.F_ID == input.F_ID);
            if (model == null)
                return Error("操作失败");
            string user = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            input.F_AddTime = model.F_AddTime ;
            model.F_AddUser = user;
            model.F_TaskUser = input.F_TaskUser;
            model.F_IsDelete = 0;
            model.F_Type  = input.F_Type ;
            model.F_Content  = input.F_Content; ;
            model.F_State = input.F_State;
            model.F_StartTime = input.F_StartTime;
            model.F_EndTime = input.F_EndTime;
            var res = await _sys_outboundTaskrepository.Update (model);
            if (res )
            {
                return Success("修改成功");
            }
            else
            {
                return Error("添加失败");
            }
        }
        /// <summary>
        /// 修改外呼号码
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("updatecall")]
        public async Task<IActionResult> Updatecall(T_Sys_AutoDial input)
        {
            if (input.F_ID <= 0)
                return Error("参数错误");
            if (input.F_Parentid <= 0)
                return Error("请选择外呼任务");
         
            var model = await _sys_autodialrepository.GetSingle(x => x.F_ID == input.F_ID);
            if (model == null)
                return Error("操作失败,此外呼不存在");
            var call = _sys_autodialrepository.GetListALL(x => x.F_Tel == input.F_Tel && x.F_ISOutbound == 0 &&
                   x.F_IsDelete == 0&&x .F_Tel != model.F_Tel ).Result;
            if (call.Count > 0)
            {
                return Error("操作失败,该外呼号码已存在");
            }
            string user = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            model.F_Parentid = input.F_Parentid;
            model.F_ISOutbound = model.F_ISOutbound;
           // model.F_CallUser = input.F_CallUser;
            model.F_LastCallid = input.F_LastCallid;
            model.F_Tel = input.F_Tel;
            model.F_IsDelete = 0;
            var res = await _sys_autodialrepository.Update(model);
            if (res)
            {
                var task = await _taskrepository.GetListALL(x => x.outbound_id == model.F_ID);
                if (task!=null&& task.Count >0)
                {
                    foreach (var it in task)
                    {
                        if (input.F_Tel.Length >= 11)
                        {
                            it.number = await CallOutprefix(input.F_Tel);
                        }
                        else
                            it.number = input.F_Tel;

                        var taskres = await _taskrepository.Update(it);
                    }
                }

                return Success("修改成功");
            }
            else
            {
                return Error("添加失败");
            }
        }
        /// <summary>
        /// 添加中间件外呼任务
        /// </summary>
        /// <returns></returns>
        [HttpPost("addmiddleware")]
        public async Task<IActionResult> Addmiddleware()
        {
            string user = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            List<IConditionalModel> conModels = new List<IConditionalModel>();
            conModels.Add(new ConditionalModel() { FieldName = "F_IsDelete", ConditionalType = ConditionalType.Equal, FieldValue = ((int)EnumUserCountState.Enabled).ToString() });
             conModels.Add(new ConditionalCollections()
                {
                    ConditionalList = new List<KeyValuePair<WhereType, ConditionalModel>>()
                    {
                        new  KeyValuePair<WhereType, ConditionalModel>(WhereType.And, new ConditionalModel() { FieldName = "F_TaskUser", ConditionalType = ConditionalType.Equal , FieldValue = user }),
                        new  KeyValuePair<WhereType, ConditionalModel>( WhereType.Or , new ConditionalModel() { FieldName = "F_Type", ConditionalType = ConditionalType.Equal , FieldValue = "1" })
                    }
                });
            conModels.Add(new ConditionalModel() { FieldName = "F_StartTime", ConditionalType = ConditionalType.LessThanOrEqual, FieldValue = DateTime .Now .ToString() });
            conModels.Add(new ConditionalModel() { FieldName = "F_EndTime", ConditionalType = ConditionalType.GreaterThan, FieldValue = DateTime.Now.ToString() });
            conModels.Add(new ConditionalModel() { FieldName = "F_State", ConditionalType = ConditionalType.Equal , FieldValue = "1" });
            var list = await _sys_outboundTaskrepository.GetListALL (conModels,  "  F_AddTime  desc");
            int n = 0;
            if (list != null)
            {
                if (list.Count > 0)
                {
                    foreach (var it in list)
                    {
                        List<IConditionalModel> conModel = new List<IConditionalModel>();
                        #region 条件筛选
                        conModel.Add(new ConditionalModel() { FieldName = "F_IsDelete", ConditionalType = ConditionalType.Equal, FieldValue = ((int)EnumUserCountState.Enabled).ToString() });
                        conModel.Add(new ConditionalModel() { FieldName = "F_Parentid", ConditionalType = ConditionalType.Equal, FieldValue = it.F_ID .ToString() });
                        conModel.Add(new ConditionalModel() { FieldName = "F_ISOutbound", ConditionalType = ConditionalType.Equal, FieldValue = "0" });
                        #endregion
                        var modellist = await _sys_autodialrepository.GetListALL (conModel, "  F_ID  asc");
                        if (modellist!=null )
                        {
                            foreach (var iv in modellist)
                            {
                                var model = await _taskrepository.GetListALL(x => x.outbound_id == iv.F_ID);
                                if (model==null || model.Count <=0)
                                {
                                    task tasks = new task();
                                    tasks.agent = user;
                                   
                                    if (iv.F_Tel.Length >=11)
                                    {
                                        tasks.number = await CallOutprefix(   iv.F_Tel);
                                    }
                                    else 
                                    tasks.number = iv.F_Tel;
                                    tasks.state = 0;
                                    tasks.type = it.F_Type;
                                    tasks.content = it.F_Content;
                                    tasks.outbound_id = iv.F_ID;
                                    tasks.status = 0;
                                    var res = await _taskrepository.Add(tasks);
                                   
                                }
                            }
                            n = modellist.Count ();
                        }
                    }
                    if (n >0)
                    return Success("任务启动", list.Count);
                    else
                     return Success("暂无任务", 0);
                }
                else
                    return Success("暂无任务", 0);
            }
            else
                return Success("暂无任务",0);

            
        }
      
        /// <summary>
        /// 添加自动外呼
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("addcall")]
        public async Task<IActionResult> AddAsync([FromBody]OutboundTaskInputcs input)
        {
            if (string.IsNullOrEmpty(input.F_Name))
                return Error("请输入任务名称");
            string user = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            var outboundTask = new T_Sys_OutboundTask();
            if (input .F_ID >0)
            {
                 outboundTask =  _sys_outboundTaskrepository.GetSingle(x => x.F_ID == input.F_ID).Result ;
                if (outboundTask == null)
                    return Error("操作失败,此任务不存在");
                outboundTask.F_AddTime = DateTime.Now;
                outboundTask.F_AddUser = user;
                outboundTask.F_TaskUser = input.F_TaskUser;
                outboundTask.F_Remarks = input.F_Remarks;
                outboundTask.F_StartTime = input.F_StartTime;
                outboundTask.F_EndTime = input.F_EndTime;
                outboundTask.F_State = input.F_State;
                outboundTask.F_Name = input.F_Name;
                outboundTask.F_Type = input.F_Type;
                outboundTask.F_Content = input.F_Content;
                outboundTask.F_IsDelete = 0;
                var task = _sys_outboundTaskrepository.Update (outboundTask).Result;
            }
            else
            {
                outboundTask.F_AddTime = DateTime.Now;
                outboundTask.F_AddUser = user;
                outboundTask.F_TaskUser = input.F_TaskUser;
                outboundTask.F_Remarks = input.F_Remarks;
                outboundTask.F_StartTime = input.F_StartTime;
                outboundTask.F_EndTime = input.F_EndTime;
                outboundTask.F_State = input.F_State;
                outboundTask.F_Name = input.F_Name;
                outboundTask.F_Type = input.F_Type;
                outboundTask.F_Content = input.F_Content;
                outboundTask.F_IsDelete = 0;
                var task = _sys_outboundTaskrepository.Add(outboundTask).Result ;
                if (task <=0)
                {
                    return Error("任务添加失败");
                }
                else
                {
                    outboundTask.F_ID = task;
                }
            }
            string msg = "";
            if (input.AutoDials != null )
            {
                foreach (var it in input.AutoDials)
                {
                    T_Sys_AutoDial model = new T_Sys_AutoDial ();
                    var call = _sys_autodialrepository.GetListALL(x => x.F_Tel == it.F_Tel&&x .F_ISOutbound ==0&&
                    x .F_IsDelete ==0).Result ;
                    
                   if (string.IsNullOrEmpty(it.F_Tel))
                    {
                        msg += "号码为空，添加失败";
                    }
                   else  if (call.Count > 0)
                    {
                        msg += it.F_Tel + "已存在外呼任务中，该号码添加失败";
                    }
                    else
                    {
                        
                        model.F_Parentid = outboundTask.F_ID;
                        model.F_ISOutbound = it.F_ISOutbound;
                        model.F_CallUser = input.F_TaskUser;
                        model.F_LastCallid = it.F_LastCallid;
                        model.F_Tel = it.F_Tel;
                        model.F_IsDelete = 0;
                        var res = await _sys_autodialrepository.Add(model);
                        if (res <=0)
                        {
                            msg += it.F_Tel + "号码添加失败";
                        }
                    }
                }
            }
            if (msg == "")
            {
                return Success("添加成功");

            }
            else
                return Error(msg);
        }
        /// <summary>
        /// 删除外呼号码
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpPost("delete")]
        public async Task<IActionResult> Remove(int[] ids)
        {
            var res = 0;
            if (ids != null && ids.Length > 0)
            {
                foreach (var item in ids)
                {
                    var model = await _sys_autodialrepository.GetSingle(x => x.F_ID == item);
                    model.F_IsDelete = (int)EnumUserCountState.Delete;
                    if (_sys_autodialrepository.Update(model).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>
        /// 删除外呼任务
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpPost("deletetask")]
        public async Task<IActionResult> RemoveTask(int id)
        {
            var model = _sys_outboundTaskrepository.GetSingle(x => x.F_ID   == id).Result;
            if (model == null)
                return Error("该任务不存在");
            var dt = _sys_autodialrepository.GetListALL(x => x.F_Parentid  == id && x.F_IsDelete  == 0).Result;
            if (dt != null)
            {
                if (dt.Count > 0)
                    return Error("请先删除此任务下的外呼号码");
            }
            model.F_IsDelete = (int)EnumUserCountState.Delete;
            bool n = _sys_outboundTaskrepository.Update(model).Result;
            if (n)
                return Success("删除成功");
            else
                return Error("删除失败");
        }
        /// <summary>
        /// 获取任务
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="pageindex"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet("getlist")]
        public async Task<IActionResult> GetListMark(string keyword,int pageindex = 1, int pagesize = 20)
        {
            List<IConditionalModel> conModels = new List<IConditionalModel>();
            #region 条件筛选
            conModels.Add(new ConditionalModel() { FieldName = "F_IsDelete", ConditionalType = ConditionalType.Equal, FieldValue = ((int)EnumUserCountState.Enabled).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_Name", ConditionalType = ConditionalType.Like, FieldValue = keyword }),
                        new  KeyValuePair<WhereType, ConditionalModel>( WhereType.Or , new ConditionalModel() { FieldName = "F_TaskUser", ConditionalType = ConditionalType.Like, FieldValue = keyword }),
                    }
                });

            }
            #endregion
            int recordCount = 0;
            var list = await _sys_outboundTaskrepository.GetListByPage(conModels, new MyPageModel() { PageIndex = pageindex, PageSize = pagesize, PageCount = recordCount }, "  F_AddTime  desc");
            var obj = new
            {
                state = "success",
                message = "成功",
                rows = list,
                total = list.Totals,
            };

            return Content(obj.ToJson());
        }
        /// <summary>
        /// 获取外呼计划列表
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="pageindex"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet("getcalllist")]
        public async Task<IActionResult> GetList(int pid,string keyword,int pageindex = 1, int pagesize = 20)
        {
            List<IConditionalModel> conModels = new List<IConditionalModel>();
            #region 条件筛选
            conModels.Add(new ConditionalModel() { FieldName = "F_IsDelete", ConditionalType = ConditionalType.Equal, FieldValue = ((int)EnumUserCountState.Enabled).ToString() });
            conModels.Add(new ConditionalModel() { FieldName = "F_Parentid", ConditionalType = ConditionalType.Equal, FieldValue = pid.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_Tel", ConditionalType = ConditionalType.Like, FieldValue = keyword }),
                        new  KeyValuePair<WhereType, ConditionalModel>( WhereType.Or , new ConditionalModel() { FieldName = "F_CallUser", ConditionalType = ConditionalType.Like, FieldValue = keyword }),
                    }
                });
            }
            #endregion
            int recordCount = 0;
            var list = await _sys_autodialrepository.GetListByPage(conModels, new MyPageModel() { PageIndex = pageindex, PageSize = pagesize, PageCount = recordCount }, "  F_ID  asc");
            var obj = new
            {
                state = "success",
                message = "成功",
                rows = list,
                total = list.Totals,
            };

            return Content(obj.ToJson());
        }
        /// <summary>
        /// 获取任务详情
        /// </summary>
        /// <param name="id">id</param>
        /// <returns></returns>
        [HttpGet("getdetails")]
        public async Task<IActionResult> GetDetailsAsync(int id)
        {
            if (id <= 0)
                return Error("参数错误");

            var model = await _sys_outboundTaskrepository.GetSingle(x => x.F_ID == id);
            if (model == null)
            {
                return Error("获取失败");
            }
            return Success("获取成功！", model);
        }
        /// <summary>
        /// 获取外呼号码
        /// </summary>
        /// <param name="id">id</param>
        /// <returns></returns>
        [HttpGet("getdetailscall")]
        public async Task<IActionResult> GetDetails(int id)
        {
            if (id <= 0)
                return Error("参数错误");

            var model = await _sys_autodialrepository.GetSingle(x => x.F_ID == id);
            if (model == null)
            {
                return Error("获取失败");
            }
            return Success("获取成功！", model);
        }
        /// <summary>
        /// 上传文件并导入数据库
        /// </summary>
        /// <returns></returns>
        [HttpPost("importexcel")]
        public async Task<IActionResult> ImportExcel(int headrow = 0,int pid=0)
        {
            if (pid <= 0)
                return Error("请选择外呼任务");
            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 errmsg = string.Empty;
            if (num > 0)
            {
                int index = 1;
                foreach (DataRow dr in dtExcel.Rows)
                {
                    var model = new T_Sys_AutoDial();
                    string user = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;

                    model.F_Parentid = pid;
                    if (dr.Table.Columns.Contains("是否完成外呼"))
                    {
                        if (dr["是否完成外呼"].ToString() == "是")
                        {
                            model.F_ISOutbound = 1;
                        }
                        else
                            model.F_ISOutbound = 0;
                    }
                    else
                    {
                        return Error("模板错误，请选择正确的模板");
                    }

                    // model.F_LastCallid = it.F_LastCallid;
                    if (dr.Table.Columns.Contains("外呼号码"))
                    {
                        model.F_Tel = dr["外呼号码"].ToString();
                    }
                    else
                    {
                        return Error("模板错误，请选择正确的模板");
                    }
                    var call = _sys_autodialrepository.GetListALL(x => x.F_Tel == dr["外呼号码"].ToString() && x.F_ISOutbound == 0 &&
                   x.F_IsDelete == 0).Result;
                    if (call!=null && call.Count ()>0)
                    {
                        errmsg = errmsg + "\r\n第" + index + "行导入失败！该已存在外呼任务中";
                    }
                    else
                    {
                        model.F_IsDelete = 0;
                        int b = await _sys_autodialrepository.Add(model);
                        if (b <= 0)
                        {
                            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("导入成功");
        }
        #region 
        [NonAction]
        public async Task<string> CallOutprefix(string phone)
        {
            string phone1 = StringHelper.ToDBC(StringHelper.RemoveNotNumber(StringHelper.NoHtml(phone)));
            string tophone = phone1;
            string fix = ""; string bfix = ""; string wfix = "";
            string zipcode = config["appSettings:CallOutZipCode"];
            bfix = config["appSettings:CallOutBPre"];
            wfix = config["appSettings:CallOutWPre"];
            int zip = await GetZipCodeByPhone(phone1, zipcode);
            if (zip == 1)
            {
                fix = bfix;
            }
            else if (zip == 2)
            {
                fix = wfix;
            }
            else
            {
                tophone = phone1.TrimStart('0');
                if (zip == 3)
                {//本地固话去0加9 比如：988888517，937188888517
                    fix = bfix;
                }
                else if (zip == 4)
                {//外地固话前加9 比如：9037188888517
                    fix = wfix;
                }
            }
            phone = fix + tophone;

            return phone;
        }

        /// <summary>
        /// 根据号码和区号判断号码是否为归属地号码
        /// 返回0为分机号或特殊号码
        /// 返回1为本地号码
        /// 返回2为外地号码
        /// </summary>
        /// <param name="phone"></param>
        /// <param name="zipcode"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<int> GetZipCodeByPhone(string phone, string zipcode)
        {
            int res = 0;
            if (phone.Trim().Length >= 7)
            {
                //7位及7位以上是固定电话或手机
                //判断是否手机
                if (phone.Trim().Length == 11 && phone[0] == '1')
                {//号码为11位，首位是1，为手机号
                    string p7 = phone.Substring(0, 7);
                    T_Sys_MobileData mobileModel = await busMobileDataRepository.GetFirst(q => q.F_MobileNum == p7);
                    if (mobileModel != null)
                    {
                        if (mobileModel.F_ZipCode.Equals(zipcode))
                        {
                            res = 1;
                        }
                        else
                        {
                            res = 2;
                        }
                    }
                }
                else
                {
                    if (phone.Trim().Length == 11 && phone.Substring(0, 3).Equals(zipcode))
                    {//号码为11位
                        //截取前三位区号判断是否本地
                        bool resbd3 = phone.Substring(0, 3).Equals(zipcode);
                        //截取前四位区号判断是否本地
                        bool resbd4 = phone.Substring(0, 4).Equals(zipcode);
                        if (resbd3 || resbd4)
                        {
                            res = 3;
                        }
                        else
                        {
                            res = 4;
                        }
                    }
                    else if (phone.Trim().Length < 11)
                    {//号码小于11位，为本地
                        res = 1;
                    }
                    else if (phone.Trim().Length < 11)
                    {//号码小于11位，为本地
                        res = 3;
                    }
                    else if (phone.Trim().Length > 11 && phone.Substring(0, 4).Equals(zipcode))
                    {//号码大于11位，截取前四位区号判断是否本地
                        res = 3;
                    }
                    else
                    {
                        res = 4;
                    }
                }
            }
            return res;
        }
        #endregion
    }
}