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

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

namespace Fab2ApprovalSystem.Controllers;

[Authorize]
[SessionExpireFilter]
public class ReportsController : Controller {

    public const String specialNullString = "~NULL~";
    private readonly AppSettings _AppSettings = GlobalVars.AppSettings;

    // 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<System.Web.Mvc.SelectListItem>();
        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<System.Web.Mvc.SelectListItem>();
                    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(_AppSettings.SSRSBindingsByConfiguration, "true", StringComparison.OrdinalIgnoreCase))
            useCfgForBindings = true;

        var c = new SSRSHelper.SSRSClient(
            Convert.ToString(_AppSettings.SSRSBaseURL),
            Convert.ToString(_AppSettings.SSRSDomain),
            Convert.ToString(_AppSettings.SSRSUsername),
            Convert.ToString(_AppSettings.SSRSPassword),
            useCfgForBindings);
        c.Initialize();

        return c;
    }

    private IEnumerable<SSRSHelper.ReportInfo> GetReportList(String docType) {
        String folderName = Convert.ToString(_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<System.Web.Mvc.SelectListItem>() {
                    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 = "";
        char[] invalidChars = System.IO.Path.GetInvalidFileNameChars();
        foreach (char c in reportName) {
            if (invalidChars.Contains(c))
                r += '_';
            else
                r += c;
        }
        return r;
    }

}