using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
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.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.TlmRepository.Entities;
using Siger.Middlelayer.TlmRepository.Repositories.Interface;
using Siger.Middlelayer.TlmRepository.Request;
using Siger.Middlelayer.TlmRepository.Response;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiTLM.Controllers
{
    /// <inheritdoc />
    /// 刀具工艺
    public class TechnologyController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IToolLifeTechnologyRepository _technologyRepository;
        private readonly IToolLifeToolTechRepository _toolTechRepository;
        private readonly ISigerProjectMachineRepository _machineRepository;

        public TechnologyController(IUnitOfWork unitOfWork, IToolLifeTechnologyRepository technologyRepository, IToolLifeToolTechRepository toolTechRepository
            ,ISigerProjectMachineRepository machineRepository)
        {
            _unitOfWork = unitOfWork;
            _technologyRepository = technologyRepository;
            _toolTechRepository = toolTechRepository;
            _machineRepository = machineRepository;
        }

        [HttpPost]
        public IActionResult GetPagedList([FromBody]RequestGetTechnology request)
        {
            var data = _technologyRepository.GetPagedList(request.product_id.ToInt(), request.draw_code, request.machine_type.ToInt(),
                request.page, request.pagesize, request.toexcel.ToInt(), request.route, ProjectId);

            if (request.toexcel.ToInt() == 0)
            {
                return new PagedObjectResult(data.Data, data.Total, request.page, request.pagesize);
            }

            return ExportTechnology(data.Data);
        }

        [HttpGet]
        public IActionResult GetTechMachine(int product_id,int route)
        {
            var machineIds = _technologyRepository.GetList(f => f.product_id == product_id && f.project_id == ProjectId && f.status != 0 && f.route_id == route).Select(s => s.machine_type).Distinct().ToList();
            return new ObjectResult(_machineRepository.GetList(f => machineIds.Contains(f.id) && f.status != 0 && f.projectid == ProjectId).ToList());
        }

        [HttpPost]
        public IActionResult GetConditions([FromBody]RequestGetTechnology request)
        {
            var productId = request.product_id.ToInt();
            var machineType = request.machine_type.ToInt();

            var response = new List<ResponseGetTechCondition>();
            if (productId == 0)
            {
                return new ObjectResult(response);
            }

            var datas = _technologyRepository.GetTechConditions(request.product_id.ToInt(), request.draw_code,
                request.machine_type.ToInt(), ProjectId);
            if (productId > 0 && machineType == 0)
            {
                foreach (var data in datas.Where(q => q.product_id == productId))
                {
                    if (!response.Select(m => m.machine_type).Contains(data.machine_type))
                    {
                        response.Add(data);
                    }
                }
            }
            else if (machineType > 0)
            {
                foreach (var data in datas.Where(q => q.product_id == productId && q.machine_type == machineType))
                {
                    if (!response.Select(m => m.drawcode).Contains(data.drawcode))
                    {
                        response.Add(data);
                    }
                }
            }
            return new ObjectResult(response);
        }

        [HttpPost]
        public IActionResult Add([FromBody]RequestAddTechnology request)
        {
            var isExist = _technologyRepository.IsExist(q =>
                q.product_id == request.product_id && q.route_id == request.route.ToInt() && q.machine_type == request.machine_type && q.status == (int)RowState.Valid
                                                   && q.project_id == ProjectId);
            if (isExist)
            {
                throw new BadRequestException(RequestEnum.TechnologyIsExist);
            }

            var entity = new siger_project_toollife_technology
            {
                create_time = DateTime.Now,
                create_id = UserId,
                drawcode = request.drawcode,
                machine_type = request.machine_type,
                product_id = request.product_id,
                program = request.program,
                remark = request.remark,
                route_id = request.route.ToInt(),
                project_id = ProjectId
            };
            _technologyRepository.Insert(entity);

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

        [HttpPost]
        public IActionResult Edit([FromBody]RequestEditTechnology request)
        {
            var isExist = _technologyRepository.IsExist(q =>
                q.product_id == request.product_id && q.route_id == request.route.ToInt() && q.status == (int)RowState.Valid
                                                   && q.project_id == ProjectId && q.id != request.id);
            if (isExist)
            {
                throw new BadRequestException(RequestEnum.TechnologyIsExist);
            }
            var programExist = _technologyRepository.IsExist(q =>
                q.product_id == request.product_id && q.route_id == request.route.ToInt() && q.program == request.program && q.status == (int)RowState.Valid
                                                   && q.project_id == ProjectId && q.id != request.id);
            if (programExist)
            {
                throw new BadRequestException(RequestEnum.TechnologyProgramIsExist);
            }

            var entity = _technologyRepository.Get(q =>
                q.id == request.id && q.project_id == ProjectId && q.status == (int) RowState.Valid);
            if (entity == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            entity.drawcode = request.drawcode;
            entity.machine_type = request.machine_type;
            entity.product_id = request.product_id;
            entity.program = request.program;
            entity.remark = request.remark;
            entity.route_id = request.route.ToInt();
            _technologyRepository.Update(entity);

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

        [HttpPost]
        public IActionResult Delete(int id)
        {
            var entity = _technologyRepository.Get(q =>
                q.id == id && q.project_id == ProjectId && q.status == (int)RowState.Valid);
            if (entity == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            entity.status = (int) RowState.Invalid;
            _technologyRepository.Update(entity);

            var techs = _toolTechRepository.GetList(t => t.technology_id == entity.id && t.project_id == ProjectId && t.status == (int)RowState.Valid).ToList();
            foreach(var tech in techs)
            {
                tech.status = (int)RowState.Invalid;
                _toolTechRepository.Update(tech);
            }

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

        private IActionResult ExportTechnology(IEnumerable<ResponseGetTechnologys> responses)
        {
            if (!responses.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

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

            var helper = new EpPlusExcelHelper<TechnologyList>();
            try
            {
                var list = new List<TechnologyList>();
                var index = 1;
                foreach (var tech in responses)
                {
                    var entity = new TechnologyList
                    {
                        ProductName = tech.product_name,
                        DrawCode = tech.drawcode,
                        MachineType = tech.machineType_name,
                        Program = tech.program,
                        Remark = tech.remark,
                        Route = tech.route,
                        Creator = tech.create_name,
                        Create_Time = tech.create_time
                    };
                    list.Add(entity);
                    index++;
                }

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

        /// <summary>
        /// 获取工序
        /// </summary>
        /// <param name="productid"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetRoutes(string productid)
        {
            var res = _technologyRepository.GetRouteList(productid.ToInt(), ProjectId);
            return new ObjectResult(res.ToList());
        }
    }
}