using System;
using System.Linq;
using System.Threading.Tasks;

using FMSAdmin.Data;
using FMSAdmin.Models;
using FMSAdmin.Entities;
using FMSAdmin.Services;

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authorization;
using FMSAdmin.Helpers;
using System.Data;
using System.IO;
using OfficeOpenXml;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using FMSAdmin.Models.Formula;
using FMSAdmin.Helpers.Formula;

namespace FMSAdmin.Controllers {
    [Authorize]
    [ApiController]
    [ApiVersion("1")]
    [Route("api/[controller]")]
    public class FormulaController : Controller {

        private static Regex regexParameter = new Regex(@"\b[A-Z]\b", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase);
        private static Regex regexFunction = new Regex(@"\$([\w]+).+\$", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase);
        private static FormulaTableManager tableManager;
        private readonly ILogger<FormulaController> _logger;
        private readonly FormulaService _service;
        private readonly FMSContext _context;
        public FormulaController(
            ILogger<FormulaController> logger,
            FormulaService service,
            FMSContext context
            ) {
            _logger = logger;
            _service = service;
            _context = context;
            tableManager = new FormulaTableManager(context);
        }



        /// <summary>
        /// 자식 노드 리스트
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        [HttpGet("childs/{siteId}")]
        public IActionResult Childs(int siteId) {



            var normalFacility = from x in _context.BemsFacilityType
                                 where x.FacilityTypeId < 99
                                 orderby x.FacilityTypeId ascending
                                 select new {
                                     key = x.FacilityTypeId.ToString() + 0.ToString() + "n",
                                     title = x.Name,
                                     depth = 0,
                                     FacilityTypeId = x.FacilityTypeId,
                                     type = "n",
                                     children = _context.CmFacility.Where(item => item.FacilityTypeId == x.FacilityTypeId && item.SiteId == siteId && !item.IsVirtualFacility && item.IsUse == true).Select(c => new {
                                         key = c.FacilityCode.ToString() + 1.ToString() + "n",
                                         title = c.Name,
                                         FacilityTypeId = c.FacilityTypeId,
                                         depth = 1,
                                         type = "n",
                                         children = _context.BemsFormulaBase.Where(item => item.FacilityTypeId == x.FacilityTypeId).Select(d => new {
                                             key = x.FacilityTypeId.ToString() + d.FormulaId.ToString() + 2.ToString() + "n",
                                             FacilityCode = c.FacilityCode,
                                             FacilityTypeId = x.FacilityTypeId,
                                             FormulaId = d.FormulaId,
                                             Formula = d.Formulas.Where(item => item.SiteId == siteId && item.FacilityTypeId == x.FacilityTypeId && item.FacilityCode == c.FacilityCode && item.FormulaId == d.FormulaId).Select(x => x.Formula).FirstOrDefault(),
                                             title = d.Name,
                                             depth = 2,
                                             type = "n",

                                         }).ToList()

                                     }).ToList()
                                 };

            var systemFacility = from x in _context.BemsFacilityType
                                 where x.FacilityTypeId > 99
                                 orderby x.FacilityTypeId ascending
                                 select new {
                                     key = x.FacilityTypeId.ToString() + 0.ToString() + "s",
                                     title = x.Name,
                                     depth = 0,
                                     FacilityTypeId = x.FacilityTypeId,
                                     type = "s",
                                     children = _context.CmFacility.Where(item => item.FacilityTypeId == x.FacilityTypeId && item.SiteId == siteId && item.IsVirtualFacility && item.IsUse == true).Select(c => new {
                                         key = c.FacilityCode.ToString() + 1.ToString() + "s",
                                         title = c.Name,
                                         FacilityTypeId = c.FacilityTypeId,
                                         depth = 1,
                                         type = "s",
                                         children = _context.BemsFormulaBase.Where(item => item.FacilityTypeId == x.FacilityTypeId).Select(d => new {
                                             key = x.FacilityTypeId.ToString() + d.FormulaId.ToString() + 2.ToString() + "s",
                                             FacilityCode = c.FacilityCode,
                                             FacilityTypeId = x.FacilityTypeId,
                                             FormulaId = d.FormulaId,
                                             Formula = d.Formulas.Where(item => item.SiteId == siteId && item.FacilityTypeId == x.FacilityTypeId && item.FormulaId == d.FormulaId).Select(x => x.Formula).FirstOrDefault(),
                                             title = d.Name,
                                             depth = 2,
                                             type = "s",

                                         }).ToList()
                                     }).ToList()
                                 };

            // var systemFacility = from x in _context.BemsFacilityType
            //                      where x.FacilityTypeId > 99
            //                      orderby x.FacilityTypeId ascending
            //                      select new {
            //                          key = x.FacilityTypeId.ToString() + 0.ToString() + "s",
            //                          title = x.Name,
            //                          depth = 0,
            //                          FacilityTypeId = x.FacilityTypeId,
            //                          type = "s",
            //                          children = _context.BemsFormulaBase.Where(item => item.FacilityTypeId == x.FacilityTypeId).Select(d => new {
            //                              key = x.FacilityTypeId.ToString() + d.FormulaId.ToString() + 2.ToString() + "s",
            //                              //FacilityCode = c.FacilityCode,
            //                              FacilityTypeId = x.FacilityTypeId,
            //                              FormulaId = d.FormulaId,
            //                              Formula = d.Formulas.Where(item => item.SiteId == siteId && item.FacilityTypeId == x.FacilityTypeId && item.FormulaId == d.FormulaId).Select(x => x.Formula).FirstOrDefault(),
            //                              title = d.Name,
            //                              depth = 2,
            //                              type = "s",

            //                          }).ToList()
            //                      };

            var result = new {
                normalFacility,
                systemFacility
            };

            return Ok(result);
        }


        [HttpGet("[action]")]
        public IActionResult GetFormula(int siteId, int facilityTypeId, int facilityCode, int formulaId) {

            var item = (from x in _context.BemsFormula
                        where x.SiteId == siteId && x.FacilityTypeId == facilityTypeId && x.FacilityCode == facilityCode && x.FormulaId == formulaId
                        select new {
                            x.SiteId,
                            x.FacilityTypeId,
                            x.FacilityCode,
                            x.FormulaId,
                            x.Formula,
                        }).ToList().FirstOrDefault();

            return Ok(item);
        }

        [HttpGet("[action]")]
        public IActionResult GetFormulaTable() {

            var funcList = from x in _context.BemsFormulaTable
                           orderby x.TableId ascending
                           select new {
                               FunctionName = x.FunctionName,
                               Description = x.Description
                           };



            return Ok(funcList);
        }


        [HttpGet("[action]")]
        public IActionResult GetFormulaFacility(int siteId, int facilityTypeId, int facilityCode, int formulaId) {

            if (facilityCode != 0) {
                var noarmalFacilityList = from x in _context.BemsFormulaParameter
                                          where x.SiteId == siteId && x.FacilityTypeId == facilityTypeId && x.FacilityCode == facilityCode && x.FormulaId == formulaId
                                          orderby x.ParameterId ascending
                                          select new {
                                              SiteId = x.SiteId,
                                              ParameterId = x.ParameterId,
                                              //CmFacilityName = x.CmFacility.Name,
                                              CmFacilityName = _context.CmFacility.Where(item => item.SiteId == x.SiteId && item.FacilityCode == x.ParameterFacilityCode).Select(x => x.Name).FirstOrDefault(),
                                              FacilityTypeId = x.FacilityTypeId,
                                              FacilityCode = x.CmFacility.FacilityCode,
                                              FormulaId = x.FormulaId,
                                              ParameterFacilityCode = x.ParameterFacilityCode,
                                              ParameterPropertyId = x.ParameterPropertyId,

                                              Name = _context.BemsMonitoringPoint.Where(item => item.SiteId == x.SiteId && item.FacilityCode == x.ParameterFacilityCode && item.PropertyId == x.ParameterPropertyId).Select(x => x.Name).FirstOrDefault()
                                          };
                return Ok(noarmalFacilityList);
            } else {
                var systemFacilityList = from x in _context.BemsFormulaParameter
                                         where x.SiteId == siteId && x.FacilityTypeId == facilityTypeId && x.FormulaId == formulaId
                                         orderby x.ParameterId ascending
                                         select new {
                                             SiteId = x.SiteId,
                                             ParameterId = x.ParameterId,
                                             FacilityTypeId = x.FacilityTypeId,
                                             //CmFacilityName = x.CmFacility.Name,
                                             CmFacilityName = _context.CmFacility.Where(item => item.SiteId == x.SiteId && item.FacilityCode == x.ParameterFacilityCode).Select(x => x.Name).FirstOrDefault(),
                                             FacilityCode = x.CmFacility.FacilityCode,
                                             FormulaId = x.FormulaId,
                                             ParameterFacilityCode = x.ParameterFacilityCode,
                                             ParameterPropertyId = x.ParameterPropertyId,
                                             Name = _context.BemsMonitoringPoint.Where(item => item.SiteId == x.SiteId && item.FacilityCode == x.ParameterFacilityCode && item.PropertyId == x.ParameterPropertyId).Select(x => x.Name).FirstOrDefault()
                                         };
                return Ok(systemFacilityList);
            }

        }


        /// <summary>
        /// 저장
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost("[action]")]
        public IActionResult Save([FromBody] BemsFormula data) {
            _logger.LogInformation("Save");
            //_logger.LogInformation(data.Dump());

            if (ModelState.IsValid) {
                _service.Save(data);
            } else {
                return BadRequest(ModelState);
            }
            return Ok();
        }



    }

}
