
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using rockfishCore.Models;
using rockfishCore.Util;
using System.Linq;
using System;

//requried to inject configuration in constructor
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Authorization;

using Microsoft.EntityFrameworkCore;

namespace rockfishCore.Controllers
{
    [Produces("application/json")]
    [Route("api/search")]
    [Authorize]
    public class SearchController : Controller
    {
        private readonly rockfishContext _context;
        private readonly IConfiguration _configuration;
        public SearchController(rockfishContext context, IConfiguration configuration)//these two are injected, see startup.cs
        {
            _context = context;
            _configuration = configuration;
        }




        [HttpGet]
        public JsonResult GetSearchResults(string query) //get parameters from url not body
        {

            //default return value, emtpy suggestions
            var noResults = new resultItem[0];

            if (string.IsNullOrWhiteSpace(query))
            {
                return Json(noResults);
            }

            //CACHE CUSTOMER NAME LIST            
            var custData = _context.Customer.Select(p => new { p.Id, p.Name });
            Dictionary<long, string> customerDict = new Dictionary<long, string>();
            customerDict.Add(0, "TRIAL CUSTOMER");
            foreach (var cust in custData)
            {
                customerDict.Add(cust.Id, cust.Name);
            }


            // List<SearchItem> l = searchItems;
            List<resultItem> resultList = new List<resultItem>();
            using (var command = _context.Database.GetDbConnection().CreateCommand())
            {
                _context.Database.OpenConnection();

                foreach (SearchItem searchItem in searchItems)
                {
                    string getColumns = "id, " + searchItem.field;
                    if (searchItem.getCustomer_id)
                    {
                        //fuckery due to column name not consistent
                        if (searchItem.table == "license")
                            getColumns += ", customerid";
                        else
                            getColumns += ", customer_id";
                    }

                    if (searchItem.getSite_id)
                        getColumns += ", site_id";

                    command.CommandText = "select distinct " + getColumns + " from " + searchItem.table + " where " + searchItem.field + " like @q;";
                    command.Parameters.Clear();
                    var parameter = command.CreateParameter();
                    parameter.ParameterName = "@q";
                    parameter.Value = "%" + query + "%";
                    command.Parameters.Add(parameter);

                    using (var res = command.ExecuteReader())
                    {
                        if (res.HasRows)
                        {
                            while (res.Read())
                            {
                                var r = new resultItem();
                                r.obj = searchItem.table;
                                r.fld = searchItem.field;
                                r.id = Convert.ToInt64(res["id"]);
                                if (searchItem.getCustomer_id)
                                {
                                    //fucked up the scheme of customer_id as table name with license
                                    //which is customerid instead so have to workaround as don't want to bother 
                                    //with the considerable amount of rigamarole to rename the column in the db
                                    if (searchItem.table == "license")
                                    {
                                        r.customerId = Convert.ToInt64(res["customerid"]);
                                        r.name = customerDict[r.customerId];//get name from customer id
                                    }
                                    else
                                    {
                                        r.customerId = Convert.ToInt64(res["customer_id"]);
                                        r.name = customerDict[r.customerId];//get name from customer id
                                    }
                                }
                                else
                                {
                                    r.name = customerDict[r.id];//here id is the customer id
                                }
                                if (searchItem.getSite_id)
                                    r.site_id = Convert.ToInt64(res["site_id"]);

                                resultList.Add(r);
                            }
                        }
                    }
                }
                _context.Database.CloseConnection();
            }

            var filteredAndSorted = resultList.GroupBy(o => new { o.id, o.obj })
                                       .Select(o => o.FirstOrDefault())
                                       .OrderBy(o => o.name);
            return Json(filteredAndSorted);
        }
        //------------------------------------------------------



        //Full text searchable items   
        private static List<SearchItem> searchItems
        {
            get
            {
                List<SearchItem> l = new List<SearchItem>();

                l.Add(new SearchItem { table = "customer", field = "name", getCustomer_id = false, getSite_id = false });
                l.Add(new SearchItem { table = "customer", field = "notes", getCustomer_id = false, getSite_id = false });
                //case 3607
                l.Add(new SearchItem { table = "customer", field = "supportEmail", getCustomer_id = false, getSite_id = false });
                l.Add(new SearchItem { table = "customer", field = "adminEmail", getCustomer_id = false, getSite_id = false });
                l.Add(new SearchItem { table = "license", field = "code", getCustomer_id = true, getSite_id = false });
                l.Add(new SearchItem { table = "license", field = "key", getCustomer_id = true, getSite_id = false });
                l.Add(new SearchItem { table = "license", field = "regto", getCustomer_id = true, getSite_id = false });
                l.Add(new SearchItem { table = "license", field = "email", getCustomer_id = true, getSite_id = false });

                l.Add(new SearchItem { table = "purchase", field = "productCode", getCustomer_id = true, getSite_id = true });
                l.Add(new SearchItem { table = "purchase", field = "salesOrderNumber", getCustomer_id = true, getSite_id = true });
                l.Add(new SearchItem { table = "purchase", field = "notes", getCustomer_id = true, getSite_id = true });
                l.Add(new SearchItem { table = "site", field = "name", getCustomer_id = true, getSite_id = false });
                l.Add(new SearchItem { table = "site", field = "notes", getCustomer_id = true, getSite_id = false });

                return l;

            }
        }

        private class SearchItem
        {
            public string table;
            public string field;
            public bool getCustomer_id;
            public bool getSite_id;
        }

        private class resultItem
        {
            public long id;
            public long site_id;
            public long customerId;
            public string obj;//Table name basically
            public string name;//always customer name
            public string fld;//the name of the field the value was found in

        }



    }//eoc
}//eons

