using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Filters;
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.Log;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.Share.Models;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiConfig.Controller
{
    [Route("config/[controller]/[action]")]
    [ApiController]
    [NoTokenValidateFilter]
    public class LogController : ControllerBase
    {
        [HttpGet]
        public IActionResult GetLogs(string module, string childmodule, string level, string content, string timerange, int page = 1,
            int pagesize = 10, int toexcel = 0)
        {
            if (string.IsNullOrWhiteSpace(module))
            {
                throw new BadRequestException(RequestEnum.ModuleIsEmpty);
            }

            var result = Enum.TryParse(module, out LogModule logModule);
            if (!result)
            {
                throw new BadRequestException(RequestEnum.ModuleIsInvalid);
            }
            var times = timerange.Split(" - ");
            var success = DateTime.TryParse(times[0], out var dtStart);
            if (!success)
            {
                throw new ServerException(500146);
            }
            success = DateTime.TryParse(times[1], out var dtEnd);
            if (!success)
            {
                throw new ServerException(500146);
            }

            dtEnd = dtEnd.AddDays(1).AddMilliseconds(-1);

            var entities = MongoDbClient.Instance.GetLogs(logModule, childmodule, level, content, dtStart, dtEnd,
                out var total, page, pagesize, toexcel);
            if (toexcel == 0)
            {
                return new PagedObjectResult(entities, total, page, pagesize);
            }

            return ExportLogs(entities);
        }

        [HttpGet]
        private IActionResult ExportLogs(IEnumerable<ResponseLog> responses)
        {
            if (!responses.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            var temporaryFileName = $"log_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);

            var helper = new EpPlusExcelHelper<LogList>();
            try
            {
                var logs = new List<LogList>();
                var index = 1;
                foreach (var log in responses)
                {
                    var entity = new LogList
                    {
                        Index = index,
                        Module = log.Module,
                        Level = log.LevelName,
                        Message = log.Message,
                        Time = log.Time
                    };
                    logs.Add(entity);
                    index++;
                }

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

        [HttpGet]
        public IActionResult GetChildModules(int module = 0)
        {
            var result = Enum.TryParse(module.ToString(), out LogModule logModule);
            if (!result)
            {
                throw new BadRequestException(RequestEnum.ModuleIsInvalid);
            }
            var responses = new List<ResponseIdName>();
            var list = new List<EnumberEntity>();
            switch (logModule)
            {
                case LogModule.BigData:
                    list = EnumHelper.EnumToList(typeof(BigDataModule));
                    break;
                case LogModule.MiddleLayer:
                    list = EnumHelper.EnumToList(typeof(Module));
                    break;
                case LogModule.DataAnalysis:
                    list = EnumHelper.EnumToList(typeof(BigDataModule));
                    break;
                case LogModule.IoT:
                    list = EnumHelper.EnumToList(typeof(IoTModule));
                    break;
            }
            foreach (var entity in list)
            {
                responses.Add(new ResponseIdName
                {
                    id = entity.EnumValue,
                    name = entity.EnumName
                });
            }
            return new ObjectResult(responses);
        }
    }
}