using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Http;
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.Repositories.Interface;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiConfig.Controller
{
    [Consumes("application/json", "multipart/form-data")]
    public class UploadController : BaseController
    {
        private readonly ISigerUserRepository _userRepository;
        private readonly ISigerProjectMachineRepository _projectMachineRepository;
        private readonly ISigerProjectMachineTypeRepository _projectMachineTypeRepository;
        private readonly ISigerProjectProductRepository _productRepository;
        private readonly ISigerProjectLevelRepository _projectLevelRepository;
        private readonly IProductRouteRepository _routeRepository;
        private readonly ISigerProjectMachineAttributionRepository _machineAttributionRepository;
        private readonly ISigerProjectProductStructure _sigerProjectProductStructure;
        private readonly Isiger_wms_bussinese_contactsRepository _bussineseContactsRepository;
        private readonly IWorkingGroupRepository _groupRepository;

        public UploadController(ISigerUserRepository userRepository, ISigerProjectMachineRepository machineRepository,
            ISigerProjectMachineTypeRepository machineTypeRepository, ISigerProjectProductRepository productRepository,
            ISigerProjectLevelRepository levelRepository, IProductRouteRepository routeRepository,
            ISigerProjectMachineAttributionRepository machineAttributionRepository, ISigerProjectProductStructure projectProductStructure,
            Isiger_wms_bussinese_contactsRepository bussineseContactsRepository, IWorkingGroupRepository groupRepository)
        {
            _userRepository = userRepository;
            _projectMachineRepository = machineRepository;
            _projectMachineTypeRepository = machineTypeRepository;
            _productRepository = productRepository;
            _projectLevelRepository = levelRepository;
            _routeRepository = routeRepository;
            _machineAttributionRepository = machineAttributionRepository;
            _sigerProjectProductStructure = projectProductStructure;
            _bussineseContactsRepository = bussineseContactsRepository;
            _groupRepository = groupRepository;
        }

        [HttpPost]
        public IActionResult UploadImage(IFormFile formFile)
        {
            if (Request.Form?.Files == null)
            {
                throw new BadRequestException(ConfigEnum.UploadFileNotFound);
            }
           
            var date = DateTime.Now.ToString("yyyy-MM-dd");
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, "image", date);
           
            if (!Directory.Exists(rootDir))
            {
                Directory.CreateDirectory(rootDir);
            }
            var files = Request.Form.Files;
            var file = files[0];
            var temporaryFileName = Guid.NewGuid().ToString("N") + FileHelper.GetExtension(file.FileName);
            var fileName = Path.Combine(rootDir, temporaryFileName);

            using (var stream = new FileStream(fileName, FileMode.Create))
            {
                file.CopyTo(stream);
            }

            return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/image/{date}/{temporaryFileName}");
        }

        [HttpPost]
        public IActionResult Submit(string templateName)
        {
            if (string.IsNullOrEmpty(templateName))
            {
                throw new BadRequestException(ConfigEnum.FileNameIsEmpty);
            }

            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 result = Enum.TryParse(typeof(TemplateNameEnums), templateName, true, out var template);
            if (!result)
            {
                throw new BadRequestException(ConfigEnum.TemplateFileNotFound);
            }
            var fileSetting = Config<FileSettings>.Get();
            if (fileSetting == null)
            {
                throw new BadRequestException(CommonEnum.GetCommCfgFailed);
            }
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, "import");
            

            //save file
            var temporaryFileName = $"{templateName}_{DateTime.Now:yyyyMMddHHmmss}{FileHelper.GetExtension(file.FileName)}";
            var fileName = Path.Combine(rootDir, temporaryFileName);
            try
            {
                using (var stream = new FileStream(fileName, FileMode.Create))
                {
                    file.CopyTo(stream);
                }

                if (!System.IO.File.Exists(fileName))
                {
                    throw new BadRequestException(RequestEnum.ImportFailed);
                }
                var res = UploadAction((TemplateNameEnums)template, fileName);
                if (res.ret == 1)
                {
                    FileHelper.DeleteFile(temporaryFileName);
                    return new ImportObjectResult(res.ret, "1");
                }

                return new ImportObjectResult(res.ret, res.msg);
            }
            catch (Exception e)
            {
                Logger.WriteLineError($"import {templateName} failed, error:" + e.Message);
                throw new BadRequestException(RequestEnum.ImportFailed);
            }
        }

        private CommonImportResult UploadAction(TemplateNameEnums template, string temporaryFilePath)
        {
            CommonImportResult result;
            switch (template)
            {
                case TemplateNameEnums.UserList:
                    result = ImportUser(temporaryFilePath);
                    break;
                case TemplateNameEnums.MachineList:
                    result = ImportMachine(temporaryFilePath);
                    break;
                case TemplateNameEnums.MachineTypeList:
                    result = ImportMachineType(temporaryFilePath);
                    break;
                case TemplateNameEnums.ProductList:
                    result = ImportProduct(temporaryFilePath);
                    break;
                case TemplateNameEnums.LevelSection:
                    result = ImportLevelSections(temporaryFilePath);
                    break;
                case TemplateNameEnums.RouteList:
                    result = ImportRouteList(temporaryFilePath);
                    break;
                case TemplateNameEnums.MachineListSkf:
                    result = ImportMachineSkf(temporaryFilePath);
                    break;
                case TemplateNameEnums.MachineAttribution:
                    result = ImportMachineAttribution(temporaryFilePath);
                    break;
                case TemplateNameEnums.ProductStructure:
                    result = ImportProductStructure(temporaryFilePath);
                    break;
                case TemplateNameEnums.wmsbusinessinfo:
                    result = ImportBusiness(temporaryFilePath);
                    break;
                case TemplateNameEnums.wmscustomerinfo:
                    result = ImportCustomer(temporaryFilePath);
                    break;
                case TemplateNameEnums.WorkingGroup:
                    result = ImportWorkingGroup(temporaryFilePath);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            return result;
        }
 
        private CommonImportResult ImportUser(string temporaryFilePath)
        {
            EpPlusExcelHelper<UserList> excelHelper = null;
            try
            {
                excelHelper = new EpPlusExcelHelper<UserList>(temporaryFilePath, _userRepository.GetProjectLanguage(ProjectId));
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(";", messages));
                }

                var users = excelHelper.ConvertSheetToList();
                var result = _userRepository.ImportUsers(users, ProjectId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportUser failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }

        private CommonImportResult ImportMachine(string temporaryFilePath)
        {
            EpPlusExcelHelper<MachineList> excelHelper = null;
            try
            {
                excelHelper = new EpPlusExcelHelper<MachineList>(temporaryFilePath, _userRepository.GetProjectLanguage(ProjectId));
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(";", messages));
                }

                var users = excelHelper.ConvertSheetToList();
                var result = _projectMachineRepository.ImportMachines(users, UserId, ProjectId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportMachine failed，error: " + e);
                throw;
            }
            finally
            {
                excelHelper.Dispose();
            }
        }

        private CommonImportResult ImportMachineSkf(string temporaryFilePath)
        {
            var excelHelper = new EpPlusForMachineHelper();
            try
            {
                var titles = _projectLevelRepository.GetLevelTitles(0, ProjectId).ToList();

                var messages = excelHelper.CheckExcel(temporaryFilePath, titles.Count);
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(";", messages));
                }

                var machines = excelHelper.ConvertSheetToListSkf(titles.Count);
                var result = _projectMachineRepository.ImportMachinesSkf(machines, UserId, ServerIpAddress, ProjectId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportMachine failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper.Dispose();
            }
        }

        private CommonImportResult ImportMachineType(string temporaryFilePath)
        {
            var excelHelper = new EpPlusExcelHelper<MachineTypeList>(temporaryFilePath, _userRepository.GetProjectLanguage(ProjectId));
            try
            {
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(";", messages));
                }

                var machineTypes = excelHelper.ConvertSheetToList();
                var result = _projectMachineTypeRepository.ImportMachineTypes(machineTypes, ProjectId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportMachineType failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper.Dispose();
            }
        }

        private CommonImportResult ImportProduct(string temporaryFilePath)
        {
            EpPlusExcelHelper<ProductList> excelHelper = null;
            try
            {
                excelHelper = new EpPlusExcelHelper<ProductList>(temporaryFilePath, _userRepository.GetProjectLanguage(ProjectId));
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(";", messages));
                }

                var products = excelHelper.ConvertSheetToList();
                var result = _productRepository.ImportProducts(products, ProjectId, UserId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportProduct failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }

        private CommonImportResult ImportLevelSections(string temporaryFilePath)
        {
            var excelHelper = new EpPlusForSectionHelper();
            try
            {
                var titles = _projectLevelRepository.GetLevelTitles(0, ProjectId).ToList();

                var messages = excelHelper.CheckExcel(temporaryFilePath, titles.Count);
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(";", messages));
                }

                var levels = excelHelper.ConvertSheetToList(titles.Count);
                var result = _projectLevelRepository.ImportSections(levels, ProjectId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportLevelSections failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper.Dispose();
            }
        }

        private CommonImportResult ImportRouteList(string temporaryFilePath)
        {
            EpPlusExcelHelper<RouteList> excelHelper = null;
            try
            {
                excelHelper = new EpPlusExcelHelper<RouteList>(temporaryFilePath, _userRepository.GetProjectLanguage(ProjectId));
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(";", messages));
                }

                var routes = excelHelper.ConvertSheetToList();
                var result = _routeRepository.ImportRoutes(routes, ProjectId, UserId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportRouteList failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }
        private CommonImportResult ImportKpiItem(string temporaryFilePath)
        {
            EpPlusExcelHelper<RouteList> excelHelper = null;
            try
            {
                excelHelper = new EpPlusExcelHelper<RouteList>(temporaryFilePath, _userRepository.GetProjectLanguage(ProjectId));
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(";", messages));
                }

                var routes = excelHelper.ConvertSheetToList();
                var result = _routeRepository.ImportRoutes(routes, ProjectId, UserId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportRouteList failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }

        private CommonImportResult ImportMachineAttribution(string temporaryFilePath)
        {
            //EpPlusExcelHelper<MachineAttribution> excelHelper = null;
            //try
            //{
            //    excelHelper = new EpPlusExcelHelper<MachineAttribution>(temporaryFilePath, _userRepository.GetProjectLanguage(ProjectId));
            //    var messages = excelHelper.CheckExcel();
            //    if (messages.Any())
            //    {
            //        return new CommonImportResult(0, string.Join(';', messages));
            //    }

            //    var data = excelHelper.ConvertSheetToList();
            //    var result = _machineAttributionRepository.ImportData(data, ProjectId, UserId);
            //    return result;
            //}
            //catch (Exception e)
            //{
            //    Logger.WriteLineError("ImportMachineAttribution failed，error: " + e.Message);
            //    throw;
            //}
            //finally
            //{
            //    excelHelper?.Dispose();
            //}
            var excelHelper = new EpPlusForSectionHelper();
            try
            {
                var titles = _projectLevelRepository.GetLevelTitles(0, ProjectId).ToList();
                titles.Add("固定资产编号");
                var messages = excelHelper.CheckExcel(temporaryFilePath, titles.Count);
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(";", messages));
                }

                var levels = excelHelper.ConvertSheetToList(titles.Count);
                var result = _machineAttributionRepository.ImportData(levels, ProjectId, UserId);
                return result;

            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportLevelSections failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper.Dispose();
            }

        }

        /// <summary>
        /// 产品物料结构清单 -BOM
        /// </summary>
        /// <param name="temporaryFilePath"></param>
        /// <returns></returns>
        private CommonImportResult ImportProductStructure(string temporaryFilePath)
        {
            EpPlusExcelHelper<ProductStructureBom> excelHelper = null;
            try
            {
                excelHelper = new EpPlusExcelHelper<ProductStructureBom>(temporaryFilePath, _userRepository.GetProjectLanguage(ProjectId));
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(';', messages));
                }

                var data = excelHelper.ConvertSheetToList();
                var result = _sigerProjectProductStructure.ImportData(data, ProjectId, UserId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportProductStructure failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }

        private CommonImportResult ImportBusiness(string temporaryFilePath)
        {
            EpPlusExcelHelper<wmsbusinessinfo> excelHelper = null;
            try
            {
                excelHelper = new EpPlusExcelHelper<wmsbusinessinfo>(temporaryFilePath, _userRepository.GetProjectLanguage(ProjectId));
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(';', messages));
                }

                var data = excelHelper.ConvertSheetToList();
                var result = _bussineseContactsRepository.ImportBusiness(data, WMSEnum.Business, ProjectId, UserId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportBusiness failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }
        private CommonImportResult ImportCustomer(string temporaryFilePath)
        {
            EpPlusExcelHelper<wmscustomerinfo> excelHelper = null;
            try
            {
                excelHelper = new EpPlusExcelHelper<wmscustomerinfo>(temporaryFilePath, _userRepository.GetProjectLanguage(ProjectId));
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(';', messages));
                }

                var data = excelHelper.ConvertSheetToList();
                var temp = Mapper<wmscustomerinfo, wmsbusinessinfo>.MapList(data);
                var result = _bussineseContactsRepository.ImportBusiness(temp, WMSEnum.Customer, ProjectId, UserId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportBusiness failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }
        /// <summary>
        /// 导入班组
        /// </summary>
        /// <param name="temporaryFilePath"></param>
        /// <returns></returns>
        private CommonImportResult ImportWorkingGroup(string temporaryFilePath)
        {
            EpPlusForWorkGroupHelper excelHelper = null;
            try
            {
                excelHelper = new EpPlusForWorkGroupHelper();
                var messages = excelHelper.CheckExcel(temporaryFilePath);
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(';', messages));
                }

                var data = excelHelper.ConvertSheetToList();
                var result = _groupRepository.ImportGroups(data, ProjectId, UserId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportWorkingGroup failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }
    }
}