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;
using Siger.Middlelayer.WmsRepository.Entities;
using Siger.Middlelayer.WmsRepository.Repositories.Interface;

namespace Siger.ApiWMS.Controllers
{
    [Consumes("application/json", "multipart/form-data")]
    public class UploadController : BaseController
    {
        private readonly Isiger_wms_storage_locationRepository _locationRepository;
        private readonly Isiger_wms_storage_location_typeRepository _location_TypeRepository;

        public UploadController(Isiger_wms_storage_locationRepository locationRepository,Isiger_wms_storage_location_typeRepository location_TypeRepository)
        {
            _locationRepository = locationRepository;
            _location_TypeRepository = location_TypeRepository;
        }

        [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, FileSystemHelper.ImportFileName);

            //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.StorageLocation:
                    result = ImportStorageLocation(temporaryFilePath);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            return result;
        }

        private CommonImportResult ImportStorageLocation(string temporaryFilePath)
        {
            EPPlusWmsExcelHelper<ImportStorageLocation> excelHelper = null;
            try
            {
                excelHelper = new EPPlusWmsExcelHelper<ImportStorageLocation>(temporaryFilePath);
                var locationTypes = _location_TypeRepository.GetList(q => q.projectid == ProjectId && q.status == (int)RowState.Valid).ToList();
                if (!locationTypes.Any())
                {
                    throw new BadRequestException(RequestEnum.LocationTypeNotFound);
                }
                var sonLocationTypes = GetSonTypes(0, locationTypes).Select(q => new Tuple<int, string>(q.id, q.name)).ToList();
                var data = excelHelper.ConvertSheetToList(sonLocationTypes);
                var result = _locationRepository.ImportStorageLocations(data, ProjectId, UserId);
                return result;
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ImportStorageLocation failed，error: " + e.Message);
                throw;
            }
            finally
            {
                excelHelper?.Dispose();
            }
        }

        private IEnumerable<siger_wms_storage_location_type> GetSonTypes(int id, List<siger_wms_storage_location_type> types)
        {
            var query = from c in types where c.parentid == id select c;

            return query.ToList().Concat(query.ToList().SelectMany(t => GetSonTypes(t.id, types)));
        }

    }
}