using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authorization;
using AyaNova.Models;
using AyaNova.Api.ControllerHelpers;
using AyaNova.Biz;


namespace AyaNova.Api.Controllers
{

    /// <summary>
    /// Enum pick list controller
    /// </summary>
    [ApiController]
    [ApiVersion("8.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    [Produces("application/json")]
    [Authorize]
    public class EnumPickListController : ControllerBase
    {
        private readonly AyContext ct;
        private readonly ILogger<EnumPickListController> log;
        private readonly ApiServerState serverState;


        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="dbcontext"></param>
        /// <param name="logger"></param>
        /// <param name="apiServerState"></param>
        public EnumPickListController(AyContext dbcontext, ILogger<EnumPickListController> logger, ApiServerState apiServerState)
        {
            ct = dbcontext;
            log = logger;
            serverState = apiServerState;
        }


        /// <summary>
        /// Get name value localized display value list of AyaNova enumerated types for list specified
        /// </summary>
        /// <param name="enumkey">The key name of the enumerated type</param>
        /// <returns>List</returns>
        [HttpGet("list/{enumkey}")]
        public ActionResult GetPickList([FromRoute]string enumkey)
        {
            if (!serverState.IsOpen)
            {
                return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
            }

            long LocaleId = UserLocaleIdFromContext.Id(HttpContext.Items);
            List<string> LocaleKeysToFetch = new List<string>();

            List<NameIdItem> ReturnList = new List<NameIdItem>();

            switch (enumkey)
            {
                case "datatypes":
                    {
                        //Iterate the enum and get the values
                        Type t = typeof(UiFieldDataType);
                        Enum.GetName(t, UiFieldDataType.NoType);
                        foreach (var dt in Enum.GetValues(t))
                        {
                            ReturnList.Add(new NameIdItem() { Name = Enum.GetName(t, dt), Id = (int)dt });
                        }

                    }
                    break;

                case "ayatype":
                    {

                        var values = Enum.GetValues(typeof(AyaType));
                        foreach (AyaType t in values)
                        {
                            string name = t.ToString();
                            if (t.HasAttribute(typeof(AttachableAttribute)))
                            {
                                name += " [Attachable]";
                            }
                            ReturnList.Add(new NameIdItem() { Name = name, Id = (long)t });
                        }
                    }
                    break;

                case "usertypes":
                    {
                        LocaleKeysToFetch.Add("UserTypesAdministrator");
                        LocaleKeysToFetch.Add("UserTypesSchedulable");
                        LocaleKeysToFetch.Add("UserTypesNonSchedulable");
                        LocaleKeysToFetch.Add("UserTypesClient");
                        LocaleKeysToFetch.Add("UserTypesHeadOffice");
                        LocaleKeysToFetch.Add("UserTypesSubContractor");
                        var LT = LocaleBiz.GetSubsetStaticAsync(LocaleKeysToFetch, LocaleId).Result;

                        ReturnList.Add(new NameIdItem() { Name = LT["UserTypesAdministrator"], Id = (long)UserType.Administrator });
                        ReturnList.Add(new NameIdItem() { Name = LT["UserTypesSchedulable"], Id = (long)UserType.Schedulable });
                        ReturnList.Add(new NameIdItem() { Name = LT["UserTypesNonSchedulable"], Id = (long)UserType.NonSchedulable });
                        ReturnList.Add(new NameIdItem() { Name = LT["UserTypesClient"], Id = (long)UserType.Customer });
                        ReturnList.Add(new NameIdItem() { Name = LT["UserTypesHeadOffice"], Id = (long)UserType.HeadOffice });
                        ReturnList.Add(new NameIdItem() { Name = LT["UserTypesSubContractor"], Id = (long)UserType.Subcontractor });
                    }
                    break;

                case "authorizationroles":
                    {

                        LocaleKeysToFetch.Add("AuthorizationRoleNoRole");
                        LocaleKeysToFetch.Add("AuthorizationRoleBizAdminLimited");
                        LocaleKeysToFetch.Add("AuthorizationRoleBizAdminFull");
                        LocaleKeysToFetch.Add("AuthorizationRoleDispatchLimited");
                        LocaleKeysToFetch.Add("AuthorizationRoleDispatchFull");
                        LocaleKeysToFetch.Add("AuthorizationRoleInventoryLimited");
                        LocaleKeysToFetch.Add("AuthorizationRoleInventoryFull");
                        LocaleKeysToFetch.Add("AuthorizationRoleAccountingFull");
                        LocaleKeysToFetch.Add("AuthorizationRoleTechLimited");
                        LocaleKeysToFetch.Add("AuthorizationRoleTechFull");
                        LocaleKeysToFetch.Add("AuthorizationRoleSubContractorLimited");
                        LocaleKeysToFetch.Add("AuthorizationRoleSubContractorFull");
                        LocaleKeysToFetch.Add("AuthorizationRoleCustomerLimited");
                        LocaleKeysToFetch.Add("AuthorizationRoleCustomerFull");
                        LocaleKeysToFetch.Add("AuthorizationRoleOpsAdminLimited");
                        LocaleKeysToFetch.Add("AuthorizationRoleOpsAdminFull");
                        LocaleKeysToFetch.Add("AuthorizationRoleSalesLimited");
                        LocaleKeysToFetch.Add("AuthorizationRoleSalesFull");
                        LocaleKeysToFetch.Add("AuthorizationRoleAll");
                        var LT = LocaleBiz.GetSubsetStaticAsync(LocaleKeysToFetch, LocaleId).Result;

                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleNoRole"], Id = (long)AuthorizationRoles.NoRole });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleBizAdminLimited"], Id = (long)AuthorizationRoles.BizAdminLimited });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleBizAdminFull"], Id = (long)AuthorizationRoles.BizAdminFull });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleDispatchLimited"], Id = (long)AuthorizationRoles.DispatchLimited });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleDispatchFull"], Id = (long)AuthorizationRoles.DispatchFull });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleInventoryLimited"], Id = (long)AuthorizationRoles.InventoryLimited });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleInventoryFull"], Id = (long)AuthorizationRoles.InventoryFull });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleAccountingFull"], Id = (long)AuthorizationRoles.AccountingFull });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleTechLimited"], Id = (long)AuthorizationRoles.TechLimited });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleTechFull"], Id = (long)AuthorizationRoles.TechFull });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleSubContractorLimited"], Id = (long)AuthorizationRoles.SubContractorLimited });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleSubContractorFull"], Id = (long)AuthorizationRoles.SubContractorFull });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleCustomerLimited"], Id = (long)AuthorizationRoles.CustomerLimited });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleCustomerFull"], Id = (long)AuthorizationRoles.CustomerFull });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleOpsAdminLimited"], Id = (long)AuthorizationRoles.OpsAdminLimited });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleOpsAdminFull"], Id = (long)AuthorizationRoles.OpsAdminFull });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleSalesLimited"], Id = (long)AuthorizationRoles.SalesLimited });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleSalesFull"], Id = (long)AuthorizationRoles.SalesFull });
                        ReturnList.Add(new NameIdItem() { Name = LT["AuthorizationRoleAll"], Id = (long)AuthorizationRoles.All });

                    }
                    break;


                default:
                    ReturnList.Add(new NameIdItem() { Name = $"Unknown enum type list key value {enumkey}", Id = (long)UserType.Administrator });
                    break;

            }

            return Ok(ApiOkResponse.Response(ReturnList, true));
        }




        /// <summary>
        /// Get all possible enumerated values picklist key names
        /// </summary>     
        /// <returns>List of AyaNova enumerated type list key names that can be fetched from the AyaEnumPickList/GetPickListRoute</returns>
        [HttpGet("listkeys")]
        public ActionResult GetTypesList()
        {
            if (!serverState.IsOpen)
            {
                return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
            }

            List<KeyValuePair<string, string>> ret = new List<KeyValuePair<string, string>>();
            ret.Add(new KeyValuePair<string, string>("usertypes", "AyaNova user account types"));
            ret.Add(new KeyValuePair<string, string>("authorizationroles", "AyaNova user account role types"));
            ret.Add(new KeyValuePair<string, string>("ayatype", "All AyaNova object types"));
            ret.Add(new KeyValuePair<string, string>("datatypes", "Types of data used in AyaNova for display and formatting UI purposes"));

            return Ok(ApiOkResponse.Response(ret, true));
        }




    }//eoc
}//ens