using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Exceptions;
using Siger.ApiCommon.Result;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.AppSettings;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Request;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.TpmRepository.Entities;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiTPM.Controllers
{
    public class SparepartTypeController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISparepartTypeRepository _projectSparepartTypeRepository;
        public SparepartTypeController(IUnitOfWork unitOfWork, ISparepartTypeRepository projectSparepartTypeRepository)
        {
            _unitOfWork = unitOfWork;
            _projectSparepartTypeRepository = projectSparepartTypeRepository;
        }

        /// <summary>
        /// 备件类型分页数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="typename"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSparepartTypeItem(string id, string typename, int page = 1, int pagesize = PageSize)
        {
            var response = new List<ResponseGetSparepartType>();
            var list = _projectSparepartTypeRepository.GetPagedList(id.ToInt(), typename, ProjectId, page, pagesize);
            foreach (var sigerProjectSparepartType in list.Data)
            {
                var type = Mapper<ResponseGetSparepartType, ResponseGetSparepartType>.Map(sigerProjectSparepartType);

                var sonTypes = _projectSparepartTypeRepository.GetSonSparepartTypes(type.id, ProjectId);
                if (sonTypes.Any())
                {
                    var typeIds = sonTypes.Select(m => m.id);
                    type.total = _projectSparepartTypeRepository.GetList(q => typeIds.Contains(q.id)
                                                                              && q.projectid == ProjectId
                                                                              && q.status == (int) RowState.Valid)
                        .ToList().Count;
                }

                response.Add(type);
            }

            return new PagedObjectResult(response, list.Total, page, pagesize);
        }

        [HttpGet]
        public IActionResult GetScategory()
        {
            var response = new List<siger_project_sparepart_type>();

            var list = _projectSparepartTypeRepository.GetList(q => q.status == (int) RowState.Valid && q.projectid == ProjectId);
            foreach (var sigerProjectSparepartType in list)
            {
                response.Add(Mapper<siger_project_sparepart_type, siger_project_sparepart_type>.Map(sigerProjectSparepartType));
            }

            return new ObjectResult(response);
        }

        /// <summary>
        /// 获取备件类型的结构树
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult SparepartListType()
        {
            var types = _projectSparepartTypeRepository.GetLevelSparepartTypes(ProjectId);

            return new ObjectResult(ConvertToTree(types));
        }

        private SparepartTypeTree ConvertToTree(IEnumerable<SparepartTypeTree> models)
        {
            var section = new Dictionary<int, SparepartTypeTree>();
            foreach (var item in models)
            {
                section.Add(item.id, item);
            }
            var result = new SparepartTypeTree
            {
                id = 0,
                value=0,
                pid = 0,
                name = "200220", //备件类型
                label = "200220", //备件类型
                title = "200220", //备件类型
            };
            var response = new List<SparepartTypeTree>();
            foreach (var item in section.Values)
            {
                if (item.pid == 0)
                {
                    response.Add(item);
                }
                else
                {
                    if (section.ContainsKey(item.pid))
                    {
                        section[item.pid].AddChilrden(item);
                    }
                }
            }

            result.children = response;
            return result;
        }

        [HttpPost]
        public IActionResult AddSparepartType([FromBody] RequestAddSparepartType request)
        {
            var entity = new siger_project_sparepart_type
            {
                title = request.title,
                description = request.description,
                parentid = request.parentid,
                userId = request.userId,
                projectid = ProjectId,
            };
            _projectSparepartTypeRepository.Insert(entity);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult EditSparepartType([FromBody] RequestUpdateSparepartType request)
        {
            var isExist = _projectSparepartTypeRepository.Get(q => q.id != request.id && q.title == request.title && q.status == (int)RowState.Valid);
            if (isExist != null)
            {
                throw new BadRequestException(RequestEnum.TitleHasExist);
            }
            var entity = _projectSparepartTypeRepository.Get(request.id);
            if (entity == null || entity.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.SparepartTypeNotFound);
            }

            entity.title = request.title;
            entity.description = request.description;
            entity.userId = request.userId;
            _projectSparepartTypeRepository.Update(entity);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult DeleteScategory(int id)
        {
            var entity = _projectSparepartTypeRepository.Get(id);
            if (entity == null || entity.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.SparepartTypeNotFound);
            }

            entity.status = (int) RowState.Invalid;
            _projectSparepartTypeRepository.Update(entity);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult DeleteScategorys([FromBody] RequestDeleteEntities request)
        {
            if (request.ids == null || !request.ids.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            var entitys = _projectSparepartTypeRepository.GetList(q =>
                request.ids.Contains(q.id) && q.projectid == ProjectId && q.status == (int) RowState.Valid).ToList();
            foreach (var entity in entitys)
            {
                entity.status = (int)RowState.Invalid;
                _projectSparepartTypeRepository.Update(entity);
            }

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult ExportSparepartType(string id, string typename)
        {
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            var response = new List<ResponseGetSparepartType>();
            var list = _projectSparepartTypeRepository.GetPagedList(id.ToInt(), typename, ProjectId, 1, 10, false);
            if (!list.Data.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            foreach (var sigerProjectSparepartType in list.Data)
            {
                var type = Mapper<ResponseGetSparepartType, ResponseGetSparepartType>.Map(sigerProjectSparepartType);

                var sonTypes = _projectSparepartTypeRepository.GetSonSparepartTypes(type.id, ProjectId);
                if (sonTypes.Any())
                {
                    var typeIds = sonTypes.Select(m => m.id);
                    type.total = _projectSparepartTypeRepository.GetList(q => typeIds.Contains(q.id)
                                                                              && q.projectid == ProjectId
                                                                              && q.status == (int)RowState.Valid)
                        .ToList().Count;
                }

                response.Add(type);
            }
            var temporaryFileName = $"sparepart_type_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);

            var helper = new EpPlusExcelHelper<SparepartTypeListForExport>();
            try
            {
                var repairList = new List<SparepartTypeListForExport>();
                foreach (var record in response)
                {
                    var entity = new SparepartTypeListForExport
                    {
                        ParentType = record.pretitle,
                        ChildType = record.title,
                        Description = record.description,
                        Num = record.total.ToString()
                    };
                    repairList.Add(entity);
                }

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