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

namespace Siger.ApiConfig.Controller
{
    public class MachineAttributionController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerProjectMachineAttributionRepository _sigerProjectMachineAttribution;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerProjectMachineNodeRepository _machineNodeRepository;
        private readonly ISigerProjectLevelSectionRepository _sectionRepository;
        private readonly ISigerProjectLevelRepository _levelRepository;

        public MachineAttributionController(IUnitOfWork unitOfWork, ISigerProjectMachineAttributionRepository sigerProjectMachineAttribution, ISigerProjectMachineRepository machineRepository
            , ISigerProjectMachineNodeRepository machineNodeRepository, ISigerProjectLevelSectionRepository sectionRepository, ISigerProjectLevelRepository levelRepository)
        {
            _unitOfWork = unitOfWork;
            _sigerProjectMachineAttribution = sigerProjectMachineAttribution;
            _machineRepository = machineRepository;
            _machineNodeRepository = machineNodeRepository;
            _sectionRepository = sectionRepository;
            _levelRepository = levelRepository;
        }
        [HttpPost]
        public IActionResult AddAttribution([FromBody]RequestAddMachineAttribution req)
        {
            //回填工站信息
            var station = req.station;
            if (station == 0)
            {
                station = _sigerProjectMachineAttribution.GetParentLevelAttribution(req.parent, ProjectId).FirstOrDefault(f => f.parent == 0)?.station ?? 0;
            }
            if (station == 0)//绑定工站不能为空
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            //备件情况
            if (req.attribution == 4)
            {
                var mid = _sigerProjectMachineAttribution.Get(f => f.id.Equals(req.parent))?.machine ?? 0;
                var isExist = _sigerProjectMachineAttribution.GetList(f => f.projectid.Equals(ProjectId)
                && f.status == (int)RowState.Valid && f.parent.Equals(req.parent) && f.sparepart_id.Equals(req.machine));
                if (isExist.Any())
                {
                    throw new BadRequestException(CommonEnum.RecordExits);
                }
                var spareData = _sigerProjectMachineAttribution.Getsparepart(ProjectId).FirstOrDefault(f => f.id.Equals(req.machine));
                if (spareData == null)
                {
                    throw new BadRequestException(CommonEnum.Fail);
                }
                var att4 = new siger_project_machine_attribution
                {
                    projectid = ProjectId,
                    attribution = req.attribution,
                    parent = req.parent,
                    name = spareData.title,
                    sparepart_id = req.machine,
                    station = station,
                    creator = UserId,
                    machine = mid
                };
                _sigerProjectMachineAttribution.Insert(att4);
                if (_unitOfWork.Commit() > 0)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
            }
            //子系统、部件唯一绑定
            var attrData = _sigerProjectMachineAttribution.GetList(f => f.projectid.Equals(ProjectId)
            && f.status == (int)RowState.Valid && f.machine.Equals(req.machine) && f.attribution.Equals(req.attribution));
            if (attrData.Any())
            {
                throw new BadRequestException(ConfigEnum.MachineAlreadyBind);
            }
            var machine = _machineRepository.Get(f => f.id.Equals(req.machine));
            if (machine == null)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            var model = new siger_project_machine_attribution
            {
                projectid = ProjectId,
                attribution = req.attribution,
                machine = req.machine,
                parent = req.parent,
                name = machine.title,
                station = station,
                creator = UserId
            };
            _sigerProjectMachineAttribution.Insert(model);
            var des = string.Empty;
            var lastdata = _sigerProjectMachineAttribution.GetList(f => f.projectid.Equals(ProjectId) && f.status == 0 && f.machine.Equals(req.machine), "id").FirstOrDefault();
            if (lastdata != null)
            {
                var from = _sectionRepository.GetSectionString(ProjectId, lastdata.station).TrimStart(new char[] { '-', '>' });
                var to = _sectionRepository.GetSectionString(ProjectId, station).TrimStart(new char[] { '-', '>' });
                des = $"{from}移动至{to}";
            }
            else
            {
                var to = _sectionRepository.GetSectionString(ProjectId, station).TrimStart(new char[] { '-', '>' });
                des = $"移动至{to}";
            }
            _machineNodeRepository.Insert(new siger_project_machine_node
            {
                machine = req.machine,
                projectid = ProjectId,
                node_info = des,
                node_operator = UserId,
                node_time = UnixTimeHelper.GetNow(),
                node_name = (int)MachineNodeName.Move,
            });

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        [HttpGet]
        public IActionResult DeleteAttribution(int id)
        {
            var attributions = _sigerProjectMachineAttribution.GetSonLevelMachineAttribution(id, ProjectId);
            if (attributions.Any())
            {
                foreach (var item in attributions)
                {
                    item.status = (int)RowState.Invalid;
                }
            }
            else
            {
                var attribution = _sigerProjectMachineAttribution.Get(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.id.Equals(id));
                if (attribution != null)
                {
                    attribution.status = (int)RowState.Invalid;
                }
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 通过设备属性获取对应设备信息
        /// </summary>
        /// <param name="attribution"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetMachineByAttribution(int attribution)
        {
            var ret = new List<siger_project_machine>();
            if (attribution < 4)
            {
                ret = _machineRepository.GetList(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.attribution.Equals(attribution)).ToList();
            }
            else
            {
                var data = _sigerProjectMachineAttribution.Getsparepart(ProjectId);
                foreach (var item in data)
                {
                    ret.Add(new siger_project_machine
                    {
                        id = item.id,
                        title = item.title
                    });
                }
            }
            return new ObjectResult(ret);
        }
        [HttpGet]
        public IActionResult GetAttributionData(int attribution = 0)
        {
            var allSections = _sectionRepository.GetList(q => q.projectid == ProjectId && q.status == (int)RowState.Valid).ToList();
            if (!allSections.Any())
            {
                return new ObjectResult(new List<ResponseGetSectionTree>());
            }
            var lastLevel = _levelRepository.GetList(f => f.projectid == ProjectId && f.status == (int)RowState.Valid).Max(m => m.id);

            var atts = _sigerProjectMachineAttribution.GetList(f => f.projectid == ProjectId && f.status == (int)RowState.Valid).ToList();
            var resp = _sigerProjectMachineAttribution.GetSectionChildren(ProjectId, 0, allSections, lastLevel, atts, attribution);
            return new ObjectResult(resp);
        }

        [HttpGet]
        public IActionResult GetAttributionDataBySection(int section, bool isShow = false)
        {
            var stations = _sigerProjectMachineAttribution.GetSonLevelSections(section, ProjectId).Select(s => s.id).ToList();
            if (!stations.Any())
            {
                stations.Add(section);
            }
            var resp = _sigerProjectMachineAttribution.GetAttributionTreeDataBySection(ProjectId, 0, stations, isShow);
            return new ObjectResult(resp);
        }

        [HttpGet]
        public IActionResult GetSectionMachineTreeData(int attribution = 0)
        {
            var resp = _sigerProjectMachineAttribution.GetSectionTreeChildrens(ProjectId, 0, attribution);
            return new ObjectResult(resp);
        }
        /// <summary>
        /// 设备重要度结构树
        /// </summary>
        /// <param name="machineLevel"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSectionMachineLevelData(string machineLevel)
        {
            var resp = _sigerProjectMachineAttribution.GetSectionTreeChildrens(ProjectId, 0, 0, machineLevel);
            return new ObjectResult(resp);
        }
        /// <summary>
        /// 设备重要度结构树（Ex）
        /// </summary>
        /// <param name="machineLevel"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSectionMachineLevelDataEx(string machineLevel)
        {
            var machineLevelList = string.Join(',', _machineRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && f.machinelevel != machineLevel.ToInt()).Select(s => s.machinelevel));
            var resp = _sigerProjectMachineAttribution.GetSectionTreeChildrens(ProjectId, 0, 0, machineLevelList);
            return new ObjectResult(resp);
        }

        [HttpPost]
        public IActionResult EditMachineLevelData([FromBody] RequestEditMachineLevel request)
        {
            if (string.IsNullOrEmpty(request.ids))
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var ids = request.ids.Split(',');
            var machines = _machineRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && ids.Contains(f.id.ToStr())).ToList();
            if (!machines.Any())
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            foreach (var machine in machines)
            {
                machine.machinelevel = request.machineLevel;
                _machineRepository.Update(machine);
            }
            if (_unitOfWork.Commit() <= 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        [HttpGet]
        public IActionResult GetTemplate()
        {
            var fileSetting = Config<FileSettings>.Get();
            if (fileSetting == null)
            {
                throw new BadRequestException(CommonEnum.GetCommCfgFailed);
            }
            var rootDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileSetting.FileSetting.PhysicalFolder);
            if (!Directory.Exists(rootDir))
            {
                throw new BadRequestException(ConfigEnum.DirectoryNotFound);
            }

            return new ObjectResult(CreateMachineTemplate());
        }

        private string CreateMachineTemplate()
        {
            var fileSetting = Config<FileSettings>.Get();
            if (fileSetting == null)
            {
                throw new BadRequestException(CommonEnum.GetCommCfgFailed);
            }
            var columnNames = new List<string>();
            var titles = _levelRepository.GetLevelTitles(0, ProjectId);
            columnNames.AddRange(titles);
            columnNames.Add("固定资产编号");
            var helper = new EpPlusForSectionHelper();
            var rootDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileSetting.FileSetting.PhysicalFolder, "ExportFiles");
            if (!Directory.Exists(rootDir))
            {
                Directory.CreateDirectory(rootDir);
            }
            var temporaryFileName = $"西格云平台-设备结构树导入模板_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);
            helper.GenerateExcel(columnNames, fileName);

            return $"{fileSetting.FileSetting.RequestPath}/ExportFiles/{temporaryFileName}";
        }
    }
}