using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Fab2ApprovalSystem.DMO;
using Fab2ApprovalSystem.Misc;
using Fab2ApprovalSystem.ViewModels;

namespace Fab2ApprovalSystem.Controllers
{
    [Authorize]
    [SessionExpireFilter]
    public class ReportsController : Controller
    {
        public const String specialNullString = "~NULL~";

        // GET: Export
        public ActionResult Index()
        {
            UserAccountDMO userDMO = new UserAccountDMO();
            ViewBag.HasITARAccess = userDMO.GetITARAccess((int)Session[GlobalVars.SESSION_USERID]);

            return View();
        }

        public ActionResult Report(String id, String docType = "")
        {
            if (String.IsNullOrEmpty(id))
                return RedirectToAction("Index");

            UserAccountDMO userDMO = new UserAccountDMO();
            if (!userDMO.GetITARAccess((int)Session[GlobalVars.SESSION_USERID]))
                return View("UnAuthorizedAccess");

            var m = new ReportViewModel();
            var reports = GetReportList(docType);
            foreach (var report in reports)
            {
                if (String.Equals(report.ReportID, id, StringComparison.OrdinalIgnoreCase))
                {
                    m.ReportID = report.ReportID;
                    m.ReportName = report.Name;
                    m.Description = report.Description;
                    m.DocType = docType;

                    var c = SetupSSRSHelperClient();

                    m.Parameters = c.GetReportParameters(report.FullPath).Select(parm =>
                    {
                        var r = new ReportParameterViewModel();
                        r.Visible = (parm.PromptUser.HasValue == false || parm.PromptUser == true) && !String.IsNullOrEmpty(parm.Prompt);
                        r.Prompt = parm.Prompt;
                        r.Name = parm.Name;
                        r.HtmlID = "parm_" + parm.Name;

                        if (parm.MultiValue.HasValue && parm.MultiValue.Value)
                            r.ControlType = ParameterControlTypes.Multiselect;
                        else if ((parm.ValidValues != null) && (parm.ValidValues.Length > 0))
                            r.ControlType = ParameterControlTypes.Dropdown;
                        else if (parm.DataType.Equals("DateTime", StringComparison.OrdinalIgnoreCase))
                            r.ControlType = ParameterControlTypes.DatePicker;
                        else
                            r.ControlType = ParameterControlTypes.Textbox;

                        r.SelectList = null;
                        if (parm.ValidValues != null)
                        {
                            r.SelectList = parm.ValidValues.Select(vv => {
                                return new SelectListItem()
                                {
                                    Text = vv.Value,
                                    Value = (vv.Key == null ? specialNullString : vv.Key),
                                    Selected = (parm.DefaultValues != null && parm.DefaultValues.Contains(vv.Key))
                                };
                            }).ToList();
                        }

                        r.DefaultValue = "";
                        if (parm.DefaultValues != null && parm.DefaultValues.Length > 0)
                            r.DefaultValue = parm.DefaultValues[0];

                        return r;

                    }).ToArray();
                }
            }

            return View(m);
        }

        public SSRSHelper.SSRSClient SetupSSRSHelperClient()
        {
            var useCfgForBindings = false;
            if (String.Equals(System.Configuration.ConfigurationManager.AppSettings["SSRSBindingsByConfiguration"], "true", StringComparison.OrdinalIgnoreCase))
                useCfgForBindings = true;

            var c = new SSRSHelper.SSRSClient(
                Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["SSRSBaseURL"]),
                Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["SSRSDomain"]),
                Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["SSRSUsername"]),
                Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["SSRSPassword"]),
                useCfgForBindings);
            c.Initialize();

            return c;
        }

        private IEnumerable<SSRSHelper.ReportInfo> GetReportList(String docType)
        {
            String folderName = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["SSRSFolder"]);
                    if (folderName.EndsWith("/"))
                        folderName = folderName.TrimEnd('/');
                    if (!String.IsNullOrWhiteSpace(docType))
                        folderName = folderName + "/" + docType;

                    var c = SetupSSRSHelperClient();
            return c.ListReports(folderName);
        }

        public ActionResult GetReports(String docType)
        {
            var reports = GetReportList(docType);

            return Json(new { Data = 
                    reports.Select(r => new ReportViewModel()
                    {
                        ReportName = r.Name ?? "",
                        Description = r.Description ?? "",
                        ReportID = r.ReportID ?? "",
                        DocType = docType
                    })
                }, 
                JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult ExportReport(String DocType, String ReportID)
        {
            var c = SetupSSRSHelperClient();
            var reports = GetReportList(DocType);

            var report = reports.Where(r => String.Equals(r.ReportID, ReportID, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
            if (report == null)
                return Content("Invalid report ID");

            var reportParms = c.GetReportParameters(report.FullPath);

            var parms = new SSRSHelper.ReportParameterCollection();
            parms.Add("DocType", DocType);
            parms.Add("UserID", Convert.ToString(Session[GlobalVars.SESSION_USERID]));
            parms.Add("BaseURL", GlobalVars.hostURL);

            foreach (var rp in reportParms)
            {
                if (rp.MultiValue.HasValue && rp.MultiValue.Value)
                {
                    foreach (String v in Request.Params.GetValues("parm_" + rp.Name))
                    {
                        parms.Add(rp.Name, v);
                    }
                }
                else
                {
                    String value = null;

                    if (Request.Params.AllKeys.Contains("parm_" + rp.Name))
                        value = Request.Params.GetValues("parm_" + rp.Name).FirstOrDefault();

                    if (value == specialNullString)
                        value = null;

                    if ((rp.AllowBlank.HasValue == false || rp.AllowBlank.Value == false) && value == "")
                        value = null;

                    if (value == null)
                    {
                        if (rp.Nullable.HasValue == false || rp.Nullable.Value == false)
                        {
                            if (rp.DefaultValues != null && rp.DefaultValues.Length > 0)
                                value = rp.DefaultValues[0];
                            if (value == null)
                                continue;
                        }
                    }                    

                    parms.Add(rp.Name, value);
                }
            }

            var b = c.ExportReport(report.FullPath, @User.Identity.Name, parms, "EXCELOPENXML");
            try
            {
                var b2 = c.FreezeExcelHeaders(b);
                return File(b2, "application/octet-stream", MakeFilename(report.Name) + ".xlsx");
            }
            catch
            {

            }
            return File(b, "application/octet-stream", MakeFilename(report.Name) + ".xlsx");

        }

        protected String MakeFilename(String reportName)
        {
            String r = "";
            var invalidChars = System.IO.Path.GetInvalidFileNameChars();
            foreach (char c in reportName)
            {
                if (invalidChars.Contains(c))
                    r += '_';
                else 
                    r += c;
            }
            return r;
        }
        
    }
}