using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Villain.Databases
{
	public class SQLServer : IDisposable
	{
		private SqlConnection _sqlConnection;

		public Action<ConnectionState> OnStateChange;

		public SQLServer(string host, string database) : this(host, database, null, null)
		{

		}

		public SQLServer(string host, string database, string username, string password) : this(GenerateConnectionString(host, database, username, password))
		{

		}
		
		public SQLServer(string connectionString)
		{
			_sqlConnection = new SqlConnection(connectionString);

			_sqlConnection.StateChange += StateChange;

			_sqlConnection.Open();
		}

		~SQLServer()
		{
			Dispose();
		}

		public void Dispose()
		{
			_sqlConnection.Dispose();
		}

		public static string GenerateConnectionString(string host, string database, string username = null, string password = null)
		{
			string usernameToken = "";
			string passwordToken = "";

			if (username != null)
			{
				usernameToken = $" User Id={username};";
			}

			if (password != null)
			{
				passwordToken = $" Password={password};";
			}

			return $"Server={host}; Database={database}; Trusted_Connection=True;" + usernameToken + passwordToken;
		}
		
		private void StateChange(object sender, StateChangeEventArgs e)
		{
			OnStateChange?.Invoke(e.CurrentState);
		}

		public SqlCommand StoredProcedure(string name)
		{
			return StoredProcedure(name, null);
		}

		public SqlCommand StoredProcedure(string name, SqlParameter[] parameters)
		{
			SqlCommand command = null;

			if (_sqlConnection.State != ConnectionState.Closed)
			{
				command = new SqlCommand(name, _sqlConnection);
				command.CommandType = CommandType.StoredProcedure;

				if (parameters != null)
				{
					command.Parameters.AddRange(parameters);
				}
			}
			
			return command;
		}
	}
}