using Ease.NetCore.DataAccess;
using Ease.NetCore.DataAccess.SQL;
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Setups;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Setups;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Setups;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;

namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Setups
{
	/// <summary>
	/// 
	/// </summary>
	/// <param name="settings"></param>
	public class AuthModulesService(IOptions<AppSettings> settings) : IAuthModulesService
	{
		private readonly AppSettings _settings = settings?.Value;

		/// <summary>
		/// 
		/// </summary>
		/// <param name="userId"></param>
		/// <param name="status"></param>
		/// <param name="entryModule"></param>
		/// <returns></returns>
		/// <exception cref="Exception"></exception>
		public async Task<AuthSummariesResponse> GetAuthSummariesAsync(int userId, short status, int entryModule)
		{
			AuthSummariesResponse response = new() { Value = [] };
			try
			{
				using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
				try
				{
					SqlParameter[] p =
					[
						SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: userId),
						SqlHelperExtension.CreateInParam(pName: "@Status", pType: SqlDbType.Int, pValue: status),
					];
					using (IDataReader dr = tc.ExecuteReaderSp(spName: "dbo.GetAuthPendingData", parameterValues: p))
					{
						while (dr.Read())
						{
							AuthModule item = new()
							{
								ModuleName = dr.GetString(0),
								ModuleId = dr.GetString(1),
								PendingItems = dr.GetInt32(2)
							};
							response.Value.Add(item);
						}
						dr.Close();
					}

					tc.End();
				}
				catch (Exception ie)
				{
					tc?.HandleError();

					throw DBCustomError.GenerateCustomError(ie);
				}
			}
			catch (Exception e)
			{
				throw new InvalidOperationException(e.Message, e);
			}

			return response;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="moduleId"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		/// <exception cref="Exception"></exception>
		public async Task<AuthDetailsResponse> GetAuthDetailsAsync(string moduleId, short status)
		{
			AuthDetailsResponse response = new() { Columns = [], Data = [] };
			try
			{
				using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
				try
				{
					SqlParameter[] p =
					[
						SqlHelperExtension.CreateInParam(pName: "@ModuleId", pType: SqlDbType.VarChar, pValue: moduleId, size: 25),
						SqlHelperExtension.CreateInParam(pName: "@Status", pType: SqlDbType.Int, pValue: status)
					];

					using (IDataReader dr = tc.ExecuteReaderSp(spName: "dbo.GetAuthProcessDetail", parameterValues: p))
					{
						//Read Columns
						for (int fldIdx = 0; fldIdx < dr.FieldCount; fldIdx++)
						{
							string[] fldParam = dr.GetName(fldIdx).Split('~');
							DynamicColumn column = new()
							{
								Field = fldParam[0],
								Title = fldParam[1],
								Width = Convert.ToInt32(fldParam[2])
							};

							response.Columns.Add(column);
						}

						//Read Data 
						while (dr.Read())
						{
							Dictionary<string, object> row = [];
							for (int fldIdx = 0; fldIdx < dr.FieldCount; fldIdx++)
							{
								object value = dr.IsDBNull(fldIdx) ? default : dr[fldIdx];
								string key = response.Columns[fldIdx].Field;

								row[key] = value;
							}
							response.Data.Add(row);
						}

						dr.Close();
					}

					tc.End();
				}
				catch (Exception ie)
				{
					tc?.HandleError();

					throw DBCustomError.GenerateCustomError(ie);
				}
			}
			catch (Exception e)
			{
				throw new InvalidOperationException(e.Message, e);
			}

			return response;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="moduleId"></param>
		/// <param name="ipAddress"></param>
		/// <param name="remarks"></param>
		/// <param name="status"></param>
		/// <param name="userId"></param>
		/// <param name="loginId"></param>
		/// <param name="ids"></param>
		/// <returns></returns>
		/// <exception cref="InvalidOperationException"></exception>
		public async Task<bool> UpdateAuthStatusAsync(string moduleId, string ipAddress, string remarks, short status, int userId, string loginId, string ids)
		{
			bool returnValue;
			try
			{
				using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
				try
				{
					SqlParameter[] p =
					[
						SqlHelperExtension.CreateInParam(pName: "@ModuleId", pType: SqlDbType.VarChar, pValue: moduleId, size: 25),
						SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: ipAddress, size: 20),
						SqlHelperExtension.CreateInParam(pName: "@Remarks", pType: SqlDbType.VarChar, pValue: remarks, size: 50),
						SqlHelperExtension.CreateInParam(pName: "@Status", pType: SqlDbType.SmallInt, pValue: status),
						SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: userId),
						SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: loginId, size: 40),
						SqlHelperExtension.CreateInParam(pName: "@Ids", pType: SqlDbType.VarChar, pValue: ids, size: 7500),
					];
					_ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateAuthStatus", parameterValues: p);

					tc.End();

					returnValue = true;
				}
				catch (Exception ie)
				{
					tc?.HandleError();

					throw DBCustomError.GenerateCustomError(ie);
				}
			}
			catch (Exception e)
			{
				throw new InvalidOperationException(e.Message, e);
			}

			return returnValue;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="userId"></param>
		/// <returns></returns>
		/// <exception cref="InvalidOperationException"></exception>
		public async Task<PendingAuthResponse> GetPendingAuthsAsync(int userId)
		{
			PendingAuthResponse response = new() { Value = [] };
			try
			{
				using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
				try
				{
					SqlParameter[] p = [SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: userId)];
					using (IDataReader dr = tc.ExecuteReaderSp(spName: "dbo.GetPendingAuths", parameterValues: p))
					{
						while (dr.Read())
						{
							PendingAuthModule item = new()
							{
								ModuleId = dr.GetString(0),
								ModuleName = dr.GetString(1),
								ModuleHref = dr.GetString(2),
								BasicData = dr.GetInt16(3) != 0,
								PendingAuthItems = dr.GetInt32(4),
								PendingItems = dr.GetInt32(5)
							};
							response.Value.Add(item);
						}
						dr.Close();
					}

					tc.End();
				}
				catch (Exception ie)
				{
					tc?.HandleError();

					throw DBCustomError.GenerateCustomError(ie);
				}
			}
			catch (Exception e)
			{
				throw new InvalidOperationException(e.Message, e);
			}

			return response;
		}
	}
}
