using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Filters;
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.ExcelImport;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiConfig.Controller
{
    public class DownloadController : BaseController
    {
        private readonly ISigerProjectMachineRepository _machineRepository;
        public DownloadController(ISigerProjectMachineRepository machineRepository)
        {
            _machineRepository = machineRepository;
        }

        [HttpGet]
        public IActionResult GetTemplate(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new BadRequestException(ConfigEnum.FileNameIsEmpty);
            }
            var fileSetting = Config<FileSettings>.Get();
            if (fileSetting == null)
            {
                throw new BadRequestException(CommonEnum.GetCommCfgFailed);
            }
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            Logger.WriteLineInfo(rootDir);
            var result = Enum.TryParse(typeof(TemplateNameEnums), name, true, out var template);
            if (!result)
            {
                throw new BadRequestException(ConfigEnum.TemplateFileNotFound);
            }
            var temporaryFileName = $"{name}_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);
            Logger.WriteLineInfo(fileName);
            var helper = new EpPlusExcelTemplateHelper();
            var type = GetType((TemplateNameEnums)template);
            if (type == null)
            {
                throw new BadRequestException(ConfigEnum.TemplateFileNotFound);
            }
            try
            {
                helper.GenerateTemplate(type, fileName, _machineRepository.GetProjectLanguage(ProjectId));
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch (Exception e)
            {
                Logger.WriteLineError("create template file failed, error: " + e.Message);
                throw new BadRequestException(RequestEnum.ExportFailed);
            }
            finally
            {
                helper.Dispose();
            }
        }

        private Type GetType(TemplateNameEnums template)
        {
            Type type = null;
            switch (template)
            {
                case TemplateNameEnums.UserList:
                    type = typeof(UserList);
                    break;
                case TemplateNameEnums.ProductList:
                    type = typeof(ProductList);
                    break;
                case TemplateNameEnums.MachineList:
                    type = typeof(MachineList);
                    break;
                case TemplateNameEnums.MachineTypeList:
                    type = typeof(MachineTypeList);
                    break;
                case TemplateNameEnums.RouteList:
                    type = typeof(RouteList);
                    break;
                //Tools
                case TemplateNameEnums.ToolsChange:
                    type = typeof(ToolChangeList);
                    break;
                case TemplateNameEnums.ToolsInfo:
                    type = typeof(ToolSupplierList);
                    break;
                case TemplateNameEnums.ToolsLocationInfo:
                    type = typeof(ToolLocationList);
                    break;
                //CNC
                case TemplateNameEnums.ProductionPlan:
                    type = typeof(ProductionPlanList);
                    break;
                //ACC
                case TemplateNameEnums.MaterialsInfo:
                    type = typeof(MaterialTemplate);
                    break;
                case TemplateNameEnums.ProductStructureInfo:
                    type = typeof(ProductStructureTemplate);
                    break;
                case TemplateNameEnums.AssemblyMaintenanceInfo:
                    type = typeof(AssemblyMaintenanceTemplate);
                    break;
                case TemplateNameEnums.EquipmentInfo:
                    type = typeof(EquipmentTemplate);
                    break;
                case TemplateNameEnums.EquipmentPositionInfo:
                    type = typeof(EquipmentPositionTemplate);
                    break;
                case TemplateNameEnums.RoutingEventNoInfo:
                    type = typeof(RoutingEventNoTemplate);
                    break;
                case TemplateNameEnums.RoutingOutStationInfo:
                    type = typeof(RoutingOutStationTemplate);
                    break;
                case TemplateNameEnums.RoutingInStationInfo:
                    type = typeof(RoutingInStationTemplate);
                    break;
                case TemplateNameEnums.PackingFullQtyInfo:
                    type = typeof(PackingFullQtyTemplate);
                    break;
                case TemplateNameEnums.OQCCheckItemInfo:
                    type = typeof(OQCCheckItemTemplate);
                    break;
                case TemplateNameEnums.WOBookingItemInfo:
                    type = typeof(WOBookingItemTemplate);
                    break;
                case TemplateNameEnums.AccCategory:
                    type = typeof(CategoryTemplate);
                    break;
                case TemplateNameEnums.DictInfo:
                    type = typeof(DictTemplate);
                    break;
                case TemplateNameEnums.Basketf:
                    type = typeof(BasketTemplate);
                    break;
                case TemplateNameEnums.TrParameterConfig:
                    type = typeof(TrParameterConfigTemplate);
                    break;
                case TemplateNameEnums.SnRule:
                    
                    type = typeof(SerinCfgConfigTemplate);
                    break;
                //wms
                case TemplateNameEnums.wmscustomerinfo:
                    type = typeof(wmscustomerinfo);
                    break;
                case TemplateNameEnums.wmsbusinessinfo:
                    type = typeof(wmsbusinessinfo);
                    break;
                case TemplateNameEnums.StorageList:
                    type = typeof(StorageList);
                    break;
                //Tpm    
                case TemplateNameEnums.SparepartList:
                    type = typeof(SparepartListForImport);
                    break;
                case TemplateNameEnums.SparepartTypeList:
                    type = typeof(SparepartTypeList);
                    break;
                case TemplateNameEnums.FaultType:
                    type = typeof(FaultTypeList);
                    break;
                case TemplateNameEnums.LevelPlanList:
                    type = typeof(LevelPlanList);
                    break;
                //tlm
                case TemplateNameEnums.TechnologyList:
                    type = typeof(TechnologyList);
                    break;
                case TemplateNameEnums.TechToolList:
                    type = typeof(TechToolList);
                    break;
                case TemplateNameEnums.ToolInfoList:
                    type = typeof(ToolInfoList);
                    break;
                case TemplateNameEnums.RoutingstationInfo:
                    type = typeof(RoutingData);
                    break;
                case TemplateNameEnums.SensorParameter:
                    type = typeof(SensorParameter);
                    break;
                case TemplateNameEnums.MachineListSkf:
                    type = typeof(MachineEntityList);
                    break;
                case TemplateNameEnums.KpiItem:
                    type = typeof(ImportKpiItem);
                    break;
                case TemplateNameEnums.KpiTaskAct:
                    type = typeof(ImportKpiTaskAct);
                    break;
                case TemplateNameEnums.KpiTask:
                    type = typeof(ImportKpiTasklist);
                    break;
                case TemplateNameEnums.InspectUnhealthyTemplate:
                    type = typeof(InspectUnhealthyTemplate);
                    break;
                case TemplateNameEnums.InspectionStandardList:
                    type = typeof(InspectionStandardTemplate);
                    break;
                case TemplateNameEnums.MachineAttribution:
                    type = typeof(MachineAttribution);
                    break;
                case TemplateNameEnums.ReworkSetting:
                    type = typeof(ReworkSetting);
                    break;
                case TemplateNameEnums.ProductStructure:
                    type = typeof(ProductStructureBom);
                    break;
                case TemplateNameEnums.ReworkPositionSetting:
                    type = typeof(ReworkPositionReworkSetting);
                    break;
                case TemplateNameEnums.AndonExpectionType:
                    type = typeof(ImportAndonExpection);
                    break;
                case TemplateNameEnums.InspectStandardCategoryTemplate:
                    type = typeof(InspectStandardCategoryTemplate);
                    break;
                case TemplateNameEnums.ReworkReason:
                    type = typeof(ImportReworkReason);
                    break;
                case TemplateNameEnums.WorkCellStation:
                    type = typeof(ImportWorkCellStation);
                    break;
                case TemplateNameEnums.Structure:
                    type = typeof(ImportManufacturingMaterial);
                    break;
                case TemplateNameEnums.WorkCell:
                    type = typeof(ImportWorkCell);
                    break;
                case TemplateNameEnums.InspectCategoryTemplate:
                    type = typeof(InspectCategoryTemplate);
                    break;
                case TemplateNameEnums.InspectStandardItemTemplate:
                    type = typeof(InspectStandardItemTemplate);
                    break;
                case TemplateNameEnums.ProductAddtion:
                    type = typeof(ImportProductAddtion);
                    break;
                case TemplateNameEnums.ProductWarehouse:
                    type = typeof(ImportProductWarehouse);
                    break;
                case TemplateNameEnums.ToollifeToolConfig:
                    type = typeof(ProjectToollifeToolConfigReportEntity);
                    break;
                case TemplateNameEnums.ToollifeDetectionAttachment:
                    type = typeof(ProjectToollifeDetectionReportEntity);
                    break;
                case TemplateNameEnums.ToollifeDetectionCutter:
                    type = typeof(ProjectToollifeDetectionReportEntity);
                    break;
                case TemplateNameEnums.ToollifeDetectionHandler:
                    type = typeof(ProjectToollifeDetectionReportEntity);
                    break;
                case TemplateNameEnums.ToollifeDetectionTool:
                    type = typeof(ProjectToollifeDetectionReportEntity);
                    break;
                case TemplateNameEnums.StorageLocation:
                    type = typeof(ImportStorageLocation);
                    break;
                case TemplateNameEnums.Mould:
                    type = typeof(IMSInfoList);
                    break;
                //case TemplateNameEnums.MouldCore:
                //    type = typeof(ToolInfoList);
                //    break;
                case TemplateNameEnums.MouldDetection:
                    type = typeof(ProjectIMSDetectionReportEntity);
                    break;
                case TemplateNameEnums.MouldCoreDetection:
                    type = typeof(ProjectIMSDetectionReportEntity);
                    break;
                case TemplateNameEnums.TechMouldList:
                    type = typeof(TechMouldList);
                    break;
                //自动化加工
                case TemplateNameEnums.FixtureToolsCategoryTemplate:
                    type = typeof(FixtureToolsCategoryTemplate);
                    break;
                case TemplateNameEnums.FixtureToolsTemplate:
                    type = typeof(FixtureToolsTemplate);
                    break;
                case TemplateNameEnums.FixtureToolsProductTemplate:
                    type = typeof(FixtureToolsProductTemplate);
                    break;
                case TemplateNameEnums.FixtureToolsAssmeblyTemplate:
                    type = typeof(FixtureToolsAssmeblyTemplate);
                    break;
                case TemplateNameEnums.AutomationLocationTemplate:
                    type = typeof(AutomationLocationTemplate);
                    break;
            }

            return type;
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DownloadFile(string file_url)
        {
            var fileSetting = Config<FileSettings>.Get();
            if (fileSetting == null)
            {
                throw new BadRequestException(CommonEnum.GetCommCfgFailed);
            }
            var truePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, file_url).Replace("Files", "TemporaryFiles");
            if (!System.IO.File.Exists(truePath))
            {
                Logger.WriteLineError($"program getContent from:{truePath} failed");
                throw new BadRequestException(RequestEnum.ErrorFilePath);
            }

            return new ObjectResult(new { content = FileUtility.GetText(truePath) });
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [NoResultFilter]
        public IActionResult DownloadFileByUrl(string url, string name)
        {
            if (!string.IsNullOrEmpty(url))
            {
                var file_url = url.Split("Files");
                if (url.Length == 2)
                {
                    url = "Files" + file_url[1];
                }
            }
            var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, url).Replace("Files", "TemporaryFiles");
            if (!System.IO.File.Exists(path))
            {
                return new NoContentResult();
            }

            try
            {
                var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
                var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(stream) };
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                {
                    FileName = name
                };
                return File(stream, "application/octet-stream");
            }
            catch (Exception e)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
        }
    }
}