using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.AppSettings;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Utility.ExcelImport;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;
using Siger.Middlelayer.Repository.Request;

namespace Siger.ApiConfig.Controller
{
    /// <summary>
    /// 供应商
    /// </summary>
    public class BusinessController : BaseController
    {
        private readonly Isiger_wms_bussinese_contactsRepository business;
        private readonly Isiger_wms_areaRepository area;
        private readonly IUnitOfWork _unitOfWork;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="business"></param>
        /// <param name="area"></param>
        /// <param name="unitOfWork"></param>
        public BusinessController(Isiger_wms_bussinese_contactsRepository business, Isiger_wms_areaRepository area, IUnitOfWork unitOfWork)
        {
            this.business = business;
            this.area = area;
            _unitOfWork = unitOfWork;
        }

        /// <summary>
        /// 获取供应商列表、获取客户列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetBusinessList(int materialID, string name, WMSEnum type, int typenameid, int page = 1, int pageSize = 10)
        {
            var data = business.GetBusinessList(materialID, ProjectId, name, type, typenameid, out int count, page, pageSize);
            return new PagedObjectResult(data, count, page, pageSize);
        }

        /// <summary>
        /// 供应商名称列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSupplierNameList(WMSEnum type)
        {
            switch (type)
            {
                case WMSEnum.Business:
                    break;
                case WMSEnum.Customer:
                    break;
                default:
                    throw new BadRequestException(RequestEnum.BusinessTypeError);
            }
            var result = business.GetList(f => f.supply_type == (int)type && f.status == (int)RowState.Valid && f.projectid == ProjectId).Select(f => new
            {
                f.id,
                f.name,
            }).ToList();
            return new ObjectResult(result);
        }


        /// <summary>
        /// 供应商Duns
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetDunsList()
        {
            var result = business.GetList(f => f.status == (int)RowState.Valid && f.projectid == ProjectId && f.duns != "").Select(f => new
            {
                f.id,
                name = f.duns
            }).ToList();
            return new ObjectResult(result);
        }

        /// <summary>
        /// 获取所有客户类型列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAreaType(WMSEnum type)
        {
            var list = area.GetAreaType(type);
            var response = new ResponseLevelSectionChildren(ConvertToTree(list));

            return new ObjectResult(response);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="models"></param>
        /// <returns></returns>
        private IList<LevelSectionTree> ConvertToTree(IEnumerable<LevelSectionTree> models)
        {
            var section = new Dictionary<int, LevelSectionTree>();
            foreach (var item in models)
            {
                section.Add(item.id, item);
            }
            var result = new List<LevelSectionTree>();
            foreach (var item in section.Values)
            {
                if (item.pid == 0)
                {
                    result.Add(item);
                }
                else
                {
                    if (section.ContainsKey(item.pid))
                    {
                        section[item.pid].AddChilrden(item);
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 获取最后一级客户类型列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetLastAreaType()
        {
            var list = area.GetLastArea().Select(f => new
            {
                f.id,
                f.name
            });

            return new ObjectResult(list);
        }

        [HttpGet]
        public IActionResult GetParentAreas(int typeid)
        {
            return new ObjectResult(area.GetParentAreaIds(typeid));
        }

        /// <summary>
        /// 新增供应商、客户记录
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddBusiness([FromBody]RequestAddBusiness req)
        {
            int type;
            switch (req.type)
            {
                case WMSEnum.Business:
                    type = (int)WMSEnum.Business;
                    break;
                case WMSEnum.Customer:
                    type = (int)WMSEnum.Customer;
                    break;
                default:
                    throw new BadRequestException(RequestEnum.BusinessTypeError);
            }
            //选择的不是最后一级
            if (area.IsExist(f => f.pid == req.typeNameID))
                throw new BadRequestException(RequestEnum.CityError);
            //选择的id不存在
            if (!area.IsExist(f => f.id == req.typeNameID))
                throw new BadRequestException(RequestEnum.CityError);
            var entity = new siger_wms_bussinese_contacts
            {
                cityid = req.typeNameID,
                name = req.name,
                serial_number = string.IsNullOrWhiteSpace(req.serial_number) ? GenSerialNumber() : req.serial_number,
                enterprise_name = req.enterprise_name,
                address = req.address,
                linkman = req.linkman,
                phone = req.phone,
                mobile = req.mobile,
                fax = req.fax,
                email = req.email,
                homepage = req.homepage,
                description = req.description,
                supply_type = type,
                projectid = ProjectId,
                create_time = DateTime.Now,
                creator = UserId,
                update_time = DateTime.Now,
                updator = UserId,
                status = (int)RowState.Valid,
                duns = req.duns
            };
            if (business.IsExist(f => f.name == req.name && f.projectid == ProjectId && f.supply_type == type))
                throw new BadRequestException(CommonEnum.RecordExits);
            business.Insert(entity);
            if (_unitOfWork.Commit() > 0)
                return Ok();
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 删除供应商、客户记录,禁用
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult DelBusiness([FromBody]RequestDelBusiness req)
        {
            if (!business.IsExist(f => f.id == req.id && f.status == (int)RowState.Valid && f.projectid == ProjectId))
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var entity = business.Get(req.id);
            entity.status = (int)RowState.Invalid;
            entity.update_time = DateTime.Now;
            entity.updator = UserId;
            business.Update(entity);
            if (_unitOfWork.Commit() > 0)
                return Ok();
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult DeleteBusiness([FromBody] RequestDeleteEntities request)
        {
            if (request.ids == null || !request.ids.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            foreach (var id in request.ids)
            {
                var entity = business.Get(q => q.id == id && q.status == (int)RowState.Valid && q.projectid == ProjectId);
                if (entity != null)
                {
                    entity.status = (int)RowState.Invalid;
                    entity.update_time = DateTime.Now;
                    entity.updator = UserId;
                    business.Update(entity);
                }
            }

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 更新供应商、客户记录
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UpdateBusiness([FromBody]RequestUpdateBusiness req)
        {
            var entity = business.GetList(f => f.id == req.id && f.projectid == ProjectId).FirstOrDefault();
            if (entity == null)
                throw new BadRequestException(CommonEnum.NoData);

            //选择的不是最后一级
            if (area.IsExist(f => f.pid == req.typeNameID))
                throw new BadRequestException(RequestEnum.CityError);
            //选择的id不存在
            if (!area.IsExist(f => f.id == req.typeNameID))
                throw new BadRequestException(RequestEnum.CityError);
            if (business.IsExist(f => f.name == req.name && f.id != req.id && f.projectid == ProjectId && f.supply_type == entity.supply_type))
                throw new BadRequestException(CommonEnum.RecordExits);
            //update start
            entity.cityid = req.typeNameID;
            entity.name = req.name;
            entity.enterprise_name = req.enterprise_name;
            entity.address = req.address;
            entity.linkman = req.linkman;
            entity.phone = req.phone;
            entity.mobile = req.mobile;
            entity.fax = req.fax;
            entity.email = req.email;
            entity.homepage = req.homepage;
            entity.description = req.description;
            entity.update_time = DateTime.Now;
            entity.updator = UserId;
            entity.status = req.statu ? (int)RowState.Valid : (int)RowState.Invalid;
            entity.duns = req.duns;
            entity.serial_number = req.serial_number;
            //update end

            business.Update(entity);
            if (_unitOfWork.Commit() > 0)
                return Ok();
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 导入客户记录
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> ImportBusiness()
        {
            var type = WMSEnum.Customer;
            switch (type)
            {
                case WMSEnum.Business:
                    break;
                case WMSEnum.Customer:
                    break;
                default:
                    throw new Exception(EnumHelper.GetEnumDesc(RequestEnum.BusinessTypeError));
            }

            var files = Request.Form.Files;
            if (files == null)
            {
                throw new BadRequestException(ConfigEnum.UploadFileNotFound);
            }

            var file = files[0];
            if (!FileHelper.IsExcelFile(file.FileName))
            {
                throw new BadRequestException(ConfigEnum.IsNotExcelFile);
            }

            //获取文件路径并保存
            var temporaryFileName = $"{DateTime.Now:yyyyMMddHHmmss}tmpImport.{Path.GetExtension(file.FileName)}";
            var fileName = GetPath(temporaryFileName);
            using (var stream = new FileStream(fileName, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }

            IEnumerable<ImportBase> list;
            if (type == WMSEnum.Business)
            {
                var helper = new EpPlusExcelHelper<wmsbusinessinfo>(fileName);
                try
                {
                    helper.CheckExcel();
                    list = helper.ConvertSheetToList().ToList();
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("ExportMaterials failed, error: " + e.Message);
                    throw new BadRequestException(RequestEnum.ImportFailed);

                }
                finally
                {
                    helper.Dispose();
                }
            }
            else
            {
                var helper = new EpPlusExcelHelper<wmscustomerinfo>(fileName);
                try
                {
                    helper.CheckExcel();
                    list = helper.ConvertSheetToList().ToList();
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("ExportMaterials failed, error: " + e.Message);
                    throw new BadRequestException(RequestEnum.ImportFailed);
                }
                finally
                {
                    helper.Dispose();
                }
            }

            foreach (var item in list)
            {
                if (type == WMSEnum.Business)
                {
                    if (!(item is wmsbusinessinfo temp))
                    {
                        throw new Exception(EnumHelper.GetEnumDesc(CommonEnum.Fail));
                    }

                    var cityid = area.Get(f => f.name == temp.city);
                    if (cityid == null)
                    {
                        throw new BadRequestException(RequestEnum.CityError);
                    }

                    //选择的不是最后一级
                    if (area.IsExist(f => f.pid == cityid.id))
                        throw new BadRequestException(RequestEnum.CityError);
                    //选择的id不存在
                    if (!area.IsExist(f => f.id == cityid.id))
                        throw new BadRequestException(RequestEnum.CityError);
                    if (business.IsExist(f =>
                        f.name == temp.name && f.projectid == ProjectId && f.supply_type == (int) type))
                        throw new BadRequestException(CommonEnum.RecordExits);

                    business.Insert(new siger_wms_bussinese_contacts
                    {
                        serial_number = temp.serial_number,
                        cityid = cityid.id,
                        name = temp.name,
                        enterprise_name = temp.enterprise_name,
                        address = temp.address,
                        linkman = temp.linkman,
                        phone = temp.phone,
                        mobile = temp.mobile,
                        fax = temp.fax,
                        email = temp.email,
                        homepage = temp.homepage,
                        description = temp.description,
                        supply_type = (int) type,
                        projectid = ProjectId,
                        create_time = DateTime.Now,
                        creator = UserId,
                        update_time = DateTime.Now,
                        updator = UserId,
                        status = (int) RowState.Valid,
                        duns = temp.duns
                    });
                }
                else
                {
                    var temp = (wmscustomerinfo) item;
                    var cityid = area.Get(f => f.name == temp.city);
                    if (cityid == null)
                    {
                        throw new BadRequestException(RequestEnum.CityError);
                    }

                    //选择的不是最后一级
                    if (area.IsExist(f => f.pid == cityid.id))
                        throw new BadRequestException(RequestEnum.CityError);
                    //选择的id不存在
                    if (!area.IsExist(f => f.id == cityid.id))
                        throw new BadRequestException(RequestEnum.CityError);
                    if (business.IsExist(f => f.name == temp.name && f.projectid == ProjectId))
                        throw new BadRequestException(CommonEnum.RecordExits);

                    business.Insert(new siger_wms_bussinese_contacts
                    {
                        serial_number = GenSerialNumber(),
                        cityid = cityid.id,
                        name = temp.name,
                        enterprise_name = temp.enterprise_name,
                        address = temp.address,
                        linkman = temp.linkman,
                        phone = temp.phone,
                        mobile = temp.mobile,
                        fax = temp.fax,
                        email = temp.email,
                        homepage = temp.homepage,
                        description = temp.description,
                        supply_type = (int) type,
                        projectid = ProjectId,
                        create_time = DateTime.Now,
                        creator = UserId,
                        update_time = DateTime.Now,
                        updator = UserId,
                        status = temp.status == "是" ? (int) RowState.Invalid : (int) RowState.Valid
                    });
                }
            }
            if (_unitOfWork.Commit() <= 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        /// <summary>
        /// 导出供应商、客户记录
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult ExportBusiness(string name, WMSEnum type, int typenameid)
        {
            switch (type)
            {
                case WMSEnum.Business:
                    break;
                case WMSEnum.Customer:
                    break;
                default:
                    throw new BadRequestException(RequestEnum.BusinessTypeError);
            }

            //查询数据
            var data = business.GetExportData(ProjectId, name, type, typenameid);

            //获取配置信息
            var fileSetting = Config<FileSettings>.Get();
            if (fileSetting == null)
            {
                throw new BadRequestException(CommonEnum.GetCommCfgFailed);
            }
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            string temporaryFileName = $"wmsbusinessinfo_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);

            //绑定数据并导出
            var index = 1;
            var wmsbusinessinfo = new List<wmsbusinessinfo>();
            var wmscustomerinfo = new List<wmscustomerinfo>();

            if (type == WMSEnum.Business)
            {
                foreach (var pro in data)
                {
                    var material = new wmsbusinessinfo
                    {
                        id = index,
                        city = pro.typeName,
                        name = pro.name,
                        serial_number = pro.serial_number,
                        enterprise_name = pro.enterprise_name,
                        address = pro.address,
                        linkman = pro.linkman,
                        phone = pro.phone,
                        mobile = pro.mobile,
                        fax = pro.fax,
                        email = pro.email,
                        homepage = pro.homepage,
                        status = pro.state == 0 ? "是" : "否",
                        description = pro.description,
                        duns = pro.duns
                    };
                    wmsbusinessinfo.Add(material);
                    index++;
                }
            }
            else
            {
                foreach (var pro in data)
                {
                    var material = new wmscustomerinfo
                    {
                        id = index,
                        city = pro.typeName,
                        name = pro.name,
                        serial_number = pro.serial_number,
                        enterprise_name = pro.enterprise_name,
                        address = pro.address,
                        linkman = pro.linkman,
                        phone = pro.phone,
                        mobile = pro.mobile,
                        fax = pro.fax,
                        email = pro.email,
                        homepage = pro.homepage,
                        status = pro.state == 0 ? "是" : "否",
                        description = pro.description
                    };
                    wmscustomerinfo.Add(material);
                    index++;
                }
            }
            if (type == WMSEnum.Business)
            {
                var helper = new EpPlusExcelHelper<wmsbusinessinfo>();
                try
                {
                    helper.GenerateExcel(wmsbusinessinfo, fileName);

                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("ExportMaterials failed, error: " + e.Message);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper.Dispose();
                }
            }
            else
            {
                var helper = new EpPlusExcelHelper<wmscustomerinfo>();
                try
                {
                    helper.GenerateExcel(wmscustomerinfo, fileName);

                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("ExportMaterials failed, error: " + e.Message);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper.Dispose();
                }
            }

        }
        private void CheckPage(int page, int pageSize)
        {
            if (page <= 0)
                throw new BadRequestException(RequestEnum.PageError);
            if (pageSize <= 0)
                throw new BadRequestException(RequestEnum.PageSizeError);
        }

        private string GenSerialNumber()
        {
            return $"{GenKey()}{UnixTimeHelper.GetNow()}";
        }
        private static string GenKey()
        {
            char value1 = (char)((new Random().Next() % 26) + 'A');
            char value2 = (char)((new Random().Next() % 26) + 'A');
            return $"{value1}{value2}";
        }
        private string GetPath(string temporaryFileName)
        {         

            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            return Path.Combine(rootDir, temporaryFileName);
        }

    }
}