using System;
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.FieldEnum;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.TlmRepository.Repositories.Interface;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiTLM.Controllers
{
    [Consumes("application/json", "multipart/form-data")]
    public class UploadController : BaseController
    {
        private readonly IToolLifeTechnologyRepository _technologyRepository;
        private readonly IToolLifeToolTechRepository _toolTechRepository;
        private readonly IToolLifeToolRepository _lifeToolRepository;
        private readonly IProjectToollifeDetectionRepository _toollifeDetectionRepository;
        private readonly IProjectToollifeToolConfigRepository _toollifeToolConfigRepository;

        public UploadController(IToolLifeTechnologyRepository technologyRepository, IToolLifeToolTechRepository techToolTechRepository,
            IToolLifeToolRepository lifeToolRepository, IProjectToollifeDetectionRepository toollifeDetectionRepository,
            IProjectToollifeToolConfigRepository toollifeToolConfigRepository)
        {
            _technologyRepository = technologyRepository;
            _toolTechRepository = techToolTechRepository;
            _lifeToolRepository = lifeToolRepository;
            _toollifeDetectionRepository = toollifeDetectionRepository;
            _toollifeToolConfigRepository = toollifeToolConfigRepository;
        }

        [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");
            if (!Directory.Exists(rootDir))
            {
                Directory.CreateDirectory(rootDir);
            }

            //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.TechnologyList:
                    result = ImportTechnology(temporaryFilePath);
                    break;
                case TemplateNameEnums.TechToolList:
                    result = ImportTechTool(temporaryFilePath);
                    break;
                case TemplateNameEnums.ToolInfoList:
                    result = ImportToolInfo(temporaryFilePath);
                    break;
                case TemplateNameEnums.ToollifeDetectionCutter:
                    result = ImportToollifeDetection(temporaryFilePath, TlmSettingCategory.Cutter);
                    break;
                case TemplateNameEnums.ToollifeDetectionHandler:
                    result = ImportToollifeDetection(temporaryFilePath, TlmSettingCategory.Handler);
                    break;
                case TemplateNameEnums.ToollifeDetectionAttachment:
                    result = ImportToollifeDetection(temporaryFilePath, TlmSettingCategory.Attachment);
                    break;
                case TemplateNameEnums.ToollifeDetectionTool:
                    result = ImportToollifeDetection(temporaryFilePath, TlmSettingCategory.Cut);
                    break;
                case TemplateNameEnums.ToollifeToolConfig:
                    result = ImportToollifeToolConfig(temporaryFilePath);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            return result;
        }

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

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

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

                var techTools = excelHelper.ConvertSheetToList();
                var result = _toolTechRepository.ImportTechnology(techTools, ProjectId, UserId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportTechTool failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }

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

                var techTools = excelHelper.ConvertSheetToList();
                var result = _lifeToolRepository.ImportToolInfos(techTools, ProjectId, UserId, TlmSettingCategory.Cutter);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportToolInfo failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }

        private CommonImportResult ImportToollifeDetection(string temporaryFilePath, TlmSettingCategory tlmSettingCategory)
        {
            EpPlusExcelHelper<ProjectToollifeDetectionReportEntity> excelHelper = null;
            try
            {
                excelHelper = new EpPlusExcelHelper<ProjectToollifeDetectionReportEntity>(temporaryFilePath);
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(';', messages));
                }
                var data = excelHelper.ConvertSheetToList();
                var result = _toollifeDetectionRepository.ImportProjectToollifeDetection(data, tlmSettingCategory, UserId, ProjectId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportToollifeDetection failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }


        private CommonImportResult ImportToollifeToolConfig(string temporaryFilePath)
        {
            EpPlusExcelHelper<ProjectToollifeToolConfigReportEntity> excelHelper = null;
            try
            {
                excelHelper = new EpPlusExcelHelper<ProjectToollifeToolConfigReportEntity>(temporaryFilePath);
                var messages = excelHelper.CheckExcel();
                if (messages.Any())
                {
                    return new CommonImportResult(0, string.Join(';', messages));
                }
                var data = excelHelper.ConvertSheetToList();
                var result = _toollifeToolConfigRepository.ImportProjectToollifeToolConfig(data, UserId, ProjectId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportToollifeDetection failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }
    }
}