//using Microsoft.Reporting.WebForms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

using VRH.Common;
using VRH.Log4Pro.MultiLanguageManager;
using Vrh.Web.Common.Lib;
//using Vrh.XmlProcessing;
//using System.Web.UI.WebControls;

using Vrh.OneReport;

namespace Vrh.Web.OneReport.Areas.OneReport.Controllers
{

    /// <summary>
    /// A OneReport által szolgáltatott akciókat tartalmazó osztály.
    /// </summary>
    public class OneReportController : BaseController
    {
        #region Constants

        #region QPCheck static class
        /// <summary>
        /// A OneReport.List akcióiban lehetséges paraméterek neveit tartalmazza ez az osztály.
        /// </summary>
        private static class QPCheck
        {
            /// <summary>
            /// XmlParser kapcsolati sztring.
            /// </summary>
            public const string XML = Constants.QParamNames.XML;

            /// <summary>
            /// A riport ezen a nyelven készüljön el.
            /// </summary>
            public const string LCID = Constants.QParamNames.LCID;

            /// <summary>
            /// Az ellenőrzendő riportok azonosítói.
            /// </summary>
            public const string REPORTNAMES = Constants.QParamNames.REPORTNAMES;
        }
        #endregion QPCheck static class

        #region QPDisplay static class
        /// <summary>
        /// A OneReport.Display akcióiban lehetséges paraméterek neveit tartalmazza ez az osztály.
        /// </summary>
        private static class QPDisplay
        {
            /// <summary>
            /// XmlParser kapcsolati sztring.
            /// A Preset és Id beállítással együtt
            /// </summary>
            public const string XML = Constants.QParamNames.XML;

            /// <summary>
            /// A riport ezen a nyelven készüljön el.
            /// </summary>
            public const string LCID = Constants.QParamNames.LCID;
        }
        #endregion QPDisplay static class

        #region QPFile static class
        /// <summary>
        /// A OneReport.Display akcióiban lehetséges paraméterek neveit tartalmazza ez az osztály.
        /// </summary>
        private static class QPFile
        {
            /// <summary>
            /// XmlParser kapcsolati sztring.
            /// A Preset és Id beállítással együtt
            /// </summary>
            public const string XML = Constants.QParamNames.XML;

            /// <summary>
            /// A riport ezen a nyelven készüljön el.
            /// </summary>
            public const string LCID = Constants.QParamNames.LCID;

            /// <summary>
            /// A riport ebben a formátumban készüljön el.
            /// Ha üres, akkor: PDF
            /// </summary>
            public const string FORMAT = Constants.QParamNames.FORMAT;

            /// <summary>
            /// A riport ebbe a fájlba készüljön el.
            /// </summary>
            public const string FILE = Constants.QParamNames.FILE;
        }
        #endregion QPFile static class

        #region QPList static class
        /// <summary>
        /// A OneReport.List akcióiban lehetséges paraméterek neveit tartalmazza ez az osztály.
        /// </summary>
        private static class QPList
        {
            /// <summary>
            /// XmlParser kapcsolati sztring.
            /// </summary>
            public const string XML = Constants.QParamNames.XML;

            /// <summary>
            /// A riport ezen a nyelven készüljön el.
            /// </summary>
            public const string LCID = Constants.QParamNames.LCID;

            /// <summary>
            /// némelyik listához fontos a riport azonosítója.
            /// </summary>
            public const string REPORTID = Constants.QParamNames.REPORTID;

            /// <summary>
            /// Listázási módok
            /// </summary>
            public const string LISTMODE = Constants.QParamNames.LISTMODE;
        }
        #endregion QPList static class

        #endregion Constants

        #region Private variables

        private readonly ReportService m_ReportService;

        #endregion Private variables

        #region Constructor
        /// <summary>
        /// Alapértelmezett konstruktor.
        /// </summary>
        public OneReportController()
        {
            m_ReportService = new ReportService(System.Web.HttpContext.Current.Server.MapPath(WebCommon.SIGN_RELATIVE));
        }
		#endregion Constructor

		#region Actions

		#region ListExportFormats action
		/// <summary>
		/// Visszaadja a OneReport-ban lehetséges export formátumokat.
		/// </summary>
		/// <returns></returns>
		public JsonResult ListExportFormats()
		{
			List<SelectListJSON> result;

			try { result = m_ReportService.ListExportFormats(); }
			catch (Exception ex)
			{
				result = new List<SelectListJSON>();
				int ix = 0;
				foreach (var item in WebCommon.ErrorListBuilder(ex))
				{
					result.Add(new SelectListJSON { Value = ix.ToString(), Text = item });
				}
			}
			return Json(result, JsonRequestBehavior.AllowGet);
		}

		#endregion ListExportFormats action

		#region ListFormats action
		/// <summary>
		/// Visszaadja azokat a formátumokat, amelyeket a File akció tud.
		/// </summary>
		/// <returns></returns>
		public JsonResult ListFormats()
		{
			List<SelectListJSON> result;

			try { result = m_ReportService.ListFormats(); }
			catch (Exception ex)
			{
				result = new List<SelectListJSON>();
				int ix = 0;
				foreach (var item in WebCommon.ErrorListBuilder(ex))
				{
					result.Add(new SelectListJSON { Value = ix.ToString(), Text = item });
				}
			}

			return Json(result, JsonRequestBehavior.AllowGet);
		}

		#endregion ListFormats action

		#region ListAllFormats action
		/// <summary>
		/// Visszaadja azokat a formátumokat, amelyeket a File vagy az Export akció tud.
		/// </summary>
		/// <returns></returns>
		public JsonResult ListAllFormats()
		{
			List<SelectListJSON> result;

			try { result = m_ReportService.ListAllFormats(); }
			catch (Exception ex)
			{
				result = new List<SelectListJSON>();
				int ix = 0;
				foreach (var item in WebCommon.ErrorListBuilder(ex))
				{
					result.Add(new SelectListJSON { Value = ix.ToString(), Text = item });
				}
			}

			return Json(result, JsonRequestBehavior.AllowGet);
		}

		#endregion ListAllFormats action

		#region List action
		/// <summary>
		/// Visszaadja egy SelectistJSON-ban a megadott XML-ben lévő riportok listáját.
		/// </summary>
		/// <returns></returns>
		public JsonResult List()
		{
			List<SelectListJSON> result;

			try
			{
				#region DEBUG
#if DEBUG
				string thisfn = $"{nameof(OneReportController)}.{nameof(List)} action: ";
				System.Diagnostics.Debug.WriteLine($"{thisfn} START");
#endif
				#endregion DEBUG

				#region QueryString paraméterek begyűjtése
				base.ParameterSeparating(Request.QueryString, typeof(QPList));
				#endregion QueryString paraméterek begyűjtése

				result = m_ReportService.List(
					base.RequestedParameters[QPList.XML],
					base.ForcedLanguageCode,
					base.RequestedParameters[QPList.LISTMODE],
					base.RequestedParameters[QPList.LCID],
					base.RequestedParameters[QPList.REPORTID]);
			}
			catch (Exception ex)
			{
				result = new List<SelectListJSON>();
				int ix = 0;
				foreach (var item in WebCommon.ErrorListBuilder(ex))
				{
					result.Add(new SelectListJSON { Value = ix++.ToString(), Text = item });
				}
			}

			return Json(result, JsonRequestBehavior.AllowGet);
		}
		#endregion List action

		#region Check action
		/// <summary>
		/// Visszaadja, hogy a kérdezett riportok léteznek-e még.
		/// </summary>
		/// <returns></returns>
		public JsonResult Check()
        {
            List<CheckListJSON> result = null;

            try
            {
                #region DEBUG
#if DEBUG
                string thisfn = $"{nameof(OneReportController)}.{nameof(Check)} action: ";
                System.Diagnostics.Debug.WriteLine($"{thisfn} START");
#endif
                #endregion DEBUG

                #region QueryString paraméterek begyűjtése
                base.ParameterSeparating(Request.QueryString, typeof(QPCheck));
                #endregion QueryString paraméterek begyűjtése

                if (!string.IsNullOrWhiteSpace(base.RequestedParameters[QPCheck.REPORTNAMES]))
                {
                    result = m_ReportService.Check(
                        base.RequestedParameters[QPCheck.XML],
                        base.ForcedLanguageCode,
                        base.RequestedParameters[QPCheck.LCID],
                        base.RequestedParameters[QPCheck.REPORTNAMES],
                        base.OtherParameters);
                }
            }
            catch (Exception ex)
            {
                result = new List<CheckListJSON>();
                int ix = 0;
                foreach (var item in WebCommon.ErrorListBuilder(ex))
                {
                    result.Add(new CheckListJSON { Value = ix.ToString(), Text = item });
                }
            }

            return Json(result, JsonRequestBehavior.AllowGet);
        }

        #endregion Check action

		#region Display action
        /// <summary>
        /// A paraméterek alapján a riport elkészítése, és megmutatása a felületen.
        /// </summary>
        /// <param name="paramlist">A paraméterek listája.</param>
        /// <returns></returns>
		public ActionResult Display(string[][] paramlist) { return _Display(displaypartial: false, paramlist); }
		public ActionResult DisplayPartial(string[][] paramlist) { return _Display(displaypartial: true, paramlist); }
		private ActionResult _Display(bool displaypartial, string[][] paramlist)
		{
			try
			{
				#region DEBUG
#if DEBUG
				string thisfn = $"{nameof(OneReportController)}.{nameof(Display)} action: ";
				System.Diagnostics.Debug.WriteLine($"{thisfn} START");
#endif
				#endregion DEBUG

				#region QueryString paraméterek begyűjtése, ellenőrzése
				base.ParameterSeparating(Request.QueryString, typeof(QPDisplay));
				string lcid = base.RequestedParameters[QPDisplay.LCID];
				lcid = string.IsNullOrWhiteSpace(lcid) ? base.ForcedLanguageCode : lcid.Trim();
				if (lcid == "*") throw new ApplicationException(ReportService.ERR_LCIDSTAR);
				#endregion QueryString paraméterek begyűjtése, ellenőrzése

				#region paramlist hozzáadása a base.OtherParameters-hez
				if (paramlist != null)
				{
					foreach (var parameterFromWebForm in paramlist)
					{
						if (base.OtherParameters.ContainsKey(parameterFromWebForm[0]))
						{
							base.OtherParameters[parameterFromWebForm[0]] = parameterFromWebForm[1];
						}
						else
						{
							base.OtherParameters.Add(parameterFromWebForm[0], parameterFromWebForm[1]);
						}
					}
				}
				#endregion paramlist hozzáadása a base.OtherParameters-hez

				m_ReportService.ReadReport(base.RequestedParameters[QPDisplay.XML], lcid, base.OtherParameters);
				if (m_ReportService.Report == null || m_ReportService.Report.ErrorMessages.Any())
				{
					ViewBag.Title = base.Mlmgt(typeof(GeneralWordCodes.MLM.General.Words.Error));
					ViewBag.Head = base.Mlmgt(typeof(GeneralWordCodes.MLM.General.Messages.ErrorHeadXML));
					return View(Constants.Views.ERRORLIST, m_ReportService.Report.ErrorMessages);
				}
				else
				{
					HttpContext.Server.ScriptTimeout = m_ReportService.Report.Timeout.Execution;
					#region DEBUG
#if DEBUG
					System.Diagnostics.Debug.WriteLine($"{thisfn}HttpContext.Server.ScriptTimeout={HttpContext.Server.ScriptTimeout}");
#endif
					#endregion DEBUG

					ViewBag.ReportViewer = m_ReportService.ReportToReportViewer();
					if (displaypartial) return PartialView(Constants.Views.DISPLAYPARTIAL, m_ReportService.Report);
					else return View(Constants.Views.DISPLAY, m_ReportService.Report);
				}
			}
			catch (Exception ex)
			{
				ViewBag.Title = base.Mlmgt(typeof(GeneralWordCodes.MLM.General.Words.Error));
				ViewBag.Head = base.Mlmgt(typeof(GeneralWordCodes.MLM.General.Messages.ErrorHeadAction), nameof(Display));
				return View(Constants.Views.ERRORLIST, WebCommon.ErrorListBuilder(ex));
			}
		}
		#endregion Display action

		#region FileOrExport action
		/// <summary>
		/// A paraméterek alapján a riport adatainak exportálása egy fájlba a megadott formátumban.
		/// </summary>
		/// <param name="paramlist">A paraméterek listája.</param>
		/// <returns></returns>
		public JsonResult FileOrExport(string[][] paramlist)
		{
			ReturnInfoJSON rij;
			try
			{
				#region DEBUG
#if DEBUG
				string thisfn = $"{nameof(OneReportController)}.{nameof(FileOrExport)} action: ";
				System.Diagnostics.Debug.WriteLine($"{thisfn} START");
#endif
				#endregion DEBUG

				#region QueryString paraméterek begyűjtése, ellenőrzése
				base.ParameterSeparating(Request.QueryString, typeof(QPFile));
				string lcid = base.RequestedParameters[QPFile.LCID];
				lcid = string.IsNullOrWhiteSpace(lcid) ? base.ForcedLanguageCode : lcid.Trim();
				if (lcid == "*") throw new ApplicationException(ReportService.ERR_LCIDSTAR);
				#endregion QueryString paraméterek begyűjtése, ellenőrzése

				#region paramlist hozzáadása a base.OtherParameters-hez
				if (paramlist != null)
				{
					foreach (var parameterFromWebForm in paramlist)
					{
						if (base.OtherParameters.ContainsKey(parameterFromWebForm[0]))
						{
							base.OtherParameters[parameterFromWebForm[0]] = parameterFromWebForm[1];
						}
						else
						{
							base.OtherParameters.Add(parameterFromWebForm[0], parameterFromWebForm[1]);
						}
					}
				}
				#endregion paramlist hozzáadása a base.OtherParameters-hez

				rij = m_ReportService.FileOrExport(
					base.RequestedParameters[QPFile.XML],
					base.RequestedParameters[QPFile.FORMAT],
					base.RequestedParameters[QPFile.FILE],
					lcid,
					base.OtherParameters
				);
				rij.ReturnMessage.Replace("\n", WebCommon.HTML_NEWLINE);
			}
			catch (Exception ex)
			{
				rij = new ReturnInfoJSON
				{
					ReturnValue = -1,
					ReturnMessage = string.Join(WebCommon.HTML_NEWLINE, WebCommon.ErrorListBuilder(ex))
				};
			}
			return Json(rij, JsonRequestBehavior.AllowGet);
		}
		#endregion FileOrExport action

		#region Export action
		/// <summary>
		/// A paraméterek alapján a riport adatainak exportálása egy fájlba a megadott formátumban.
		/// </summary>
		/// <param name="paramlist">A paraméterek listája.</param>
		/// <returns></returns>
		public JsonResult Export(string[][] paramlist)
		{
			ReturnInfoJSON rij = null;
			try
			{
#region DEBUG
#if DEBUG
                string thisfn = $"{nameof(OneReportController)}.{nameof(Export)} action: ";
                System.Diagnostics.Debug.WriteLine($"{thisfn} START");
#endif
#endregion DEBUG

				#region QueryString paraméterek begyűjtése, ellenőrzése
				base.ParameterSeparating(Request.QueryString, typeof(QPFile));
				string lcid = base.RequestedParameters[QPFile.LCID];
				lcid = string.IsNullOrWhiteSpace(lcid) ? base.ForcedLanguageCode : lcid.Trim();
				if (lcid == "*") throw new ApplicationException(ReportService.ERR_LCIDSTAR);
				#endregion QueryString paraméterek begyűjtése, ellenőrzése

				#region paramlist hozzáadása a base.OtherParameters-hez
				if (paramlist != null)
				{
					foreach (var parameterFromWebForm in paramlist)
					{
						if (base.OtherParameters.ContainsKey(parameterFromWebForm[0]))
						{
							base.OtherParameters[parameterFromWebForm[0]] = parameterFromWebForm[1];
						}
						else
						{
							base.OtherParameters.Add(parameterFromWebForm[0], parameterFromWebForm[1]);
						}
					}
				}
				#endregion paramlist hozzáadása a base.OtherParameters-hez

				m_ReportService.Export(
					base.RequestedParameters[QPFile.XML],
					base.RequestedParameters[QPFile.FORMAT],
					base.RequestedParameters[QPFile.FILE],
					lcid,
					base.OtherParameters
				);

				#region ReturnMessage megszerkesztése
				rij = new ReturnInfoJSON
				{
					ReturnMessage = String.Concat(
					"OneReport.Export action is successful.", WebCommon.HTML_NEWLINE,
					"Id: ", m_ReportService.Report.Id)
				};
				foreach (var dset in m_ReportService.Report.Datasets)
				{
					rij.ReturnMessage = String.Concat( rij.ReturnMessage, WebCommon.HTML_NEWLINE, "File: ", dset.ExportFile);
				}
				#endregion ReturnMessage megszerkesztése
			}
			catch (Exception ex)
			{
				rij = new ReturnInfoJSON
				{
					ReturnValue = -1,
					ReturnMessage = string.Join(WebCommon.HTML_NEWLINE, WebCommon.ErrorListBuilder(ex))
				};
			}
			return Json(rij, JsonRequestBehavior.AllowGet);
		}

        #endregion Export action

        #region File action
        /// <summary>
        /// A paraméterek alapján a riport elkészítése, és a formázott riport mentése fájlba.
        /// </summary>
        /// <param name="paramlist">A paraméterek listája.</param>
        /// <returns></returns>
        public JsonResult File(string[][] paramlist)
        {
			ReturnInfoJSON rij = null;
			try
            {
#region DEBUG
#if DEBUG
                string thisfn = $"{nameof(OneReportController)}.{nameof(File)} action: ";
                System.Diagnostics.Debug.WriteLine($"{thisfn} START");
#endif
#endregion DEBUG

                #region QueryString paraméterek begyűjtése, ellenőrzése
                base.ParameterSeparating(Request.QueryString, typeof(QPFile));
                string lcid = base.RequestedParameters[QPFile.LCID];
                lcid = string.IsNullOrWhiteSpace(lcid) ? base.ForcedLanguageCode : lcid.Trim();
                if (lcid == "*") throw new ApplicationException(ReportService.ERR_LCIDSTAR);
                #endregion QueryString paraméterek begyűjtése, ellenőrzése

                #region paramlist hozzáadása a base.OtherParameters-hez
                if (paramlist != null)
                {
                    foreach (var parameterFromWebForm in paramlist)
                    {
                        if (base.OtherParameters.ContainsKey(parameterFromWebForm[0]))
                        {
                            base.OtherParameters[parameterFromWebForm[0]] = parameterFromWebForm[1];
                        }
                        else
                        {
                            base.OtherParameters.Add(parameterFromWebForm[0], parameterFromWebForm[1]);
                        }
                    }
                }
                #endregion paramlist hozzáadása a base.OtherParameters-hez

                m_ReportService.ToFile(
                    base.RequestedParameters[QPFile.XML],
                    base.RequestedParameters[QPFile.FORMAT],
                    base.RequestedParameters[QPFile.FILE],
                    lcid,
                    base.OtherParameters
                );

				#region ReturnMessage megszerkesztése
				rij = new ReturnInfoJSON
				{
					ReturnMessage = String.Concat(
					"OneReport.File action is successful.", WebCommon.HTML_NEWLINE,
					"Id: ", m_ReportService.Report.Id, WebCommon.HTML_NEWLINE,
					"File: ", m_ReportService.Report.TargetFile)
				};
				#endregion ReturnMessage megszerkesztése
			}
			catch (Exception ex)
            {
                rij = new ReturnInfoJSON
                {
                    ReturnValue = -1,
                    ReturnMessage = string.Join(WebCommon.HTML_NEWLINE, WebCommon.ErrorListBuilder(ex))
                };
            }
			return Json(rij, JsonRequestBehavior.AllowGet);
		}
		#endregion File action

		#endregion Actions

		#region Private methods


		#endregion Private methods
	}
}
