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

using Dapper;

using Fab2ApprovalSystem.Misc;
using Fab2ApprovalSystem.Models;

namespace Fab2ApprovalSystem.DMO;

public class UserAccountDMO {
    private readonly IDbConnection db = new SqlConnection(GlobalVars.DB_CONNECTION_STRING);

    public IEnumerable<LoginModel> GetAllUsers() {
        StringBuilder sql = new();
        sql.Append("  SELECT U.FirstName + ' ' + U.LastName AS FullName, U.* , U1.FirstName + ' ' + U1.LastName AS DelegatedToFullName ");
        sql.Append("FROM Users U LEFT JOIN Users U1 ON U.DelegatedTo  = U1.UserID ");
        sql.Append("ORDER BY FirstName ");

        return db.Query<LoginModel>(sql.ToString()).ToList();
    }

    public IEnumerable<LoginModel> GetAllActiveUsers() {
        StringBuilder sql = new();
        sql.Append("  SELECT U.FirstName + ' ' + U.LastName AS FullName, U.* , U1.FirstName + ' ' + U1.LastName AS DelegatedToFullName ");
        sql.Append("FROM Users U LEFT JOIN Users U1 ON U.DelegatedTo  = U1.UserID ");
        sql.Append("WHERE U.IsActive = 1 ");
        sql.Append("ORDER BY FirstName ");

        return db.Query<LoginModel>(sql.ToString()).ToList();
    }

    public LoginModel GetUser(string loginID) =>
        db.Query<LoginModel>("SELECT FirstName + ' ' + LastName AS FullName, * FROM Users WHERE LoginID = @loginID AND IsActive = 1 ", new { loginID = loginID }).Take(1).SingleOrDefault();

    public LoginModel GetUserByID(int userID) {
        return db.Query<LoginModel>(
            "SELECT FirstName + ' ' + LastName AS FullName, * FROM Users WHERE UserID = @UserID ",
            new { UserID = userID }).Take(1).SingleOrDefault();
    }

    public string GetUserEmailByID(int userID) {
        return db.Query<string>(
            "SELECT Email FROM Users WHERE UserID = @UserID ",
            new { UserID = userID }).Take(1).SingleOrDefault();
    }

    internal void UpdateUser(LoginModel model) {
        string sql;
        sql = "UPDATE Users SET LoginID = @LoginID, FirstName = @FirstName, LastName = @LastName, Email =  @Email, IsActive = @IsActive, IsAdmin = @IsAdmin WHERE UserID = @UserID";
        DynamicParameters parameters = new();
        parameters.Add("@UserID", model.UserID);
        parameters.Add("@LoginID", model.LoginID);
        parameters.Add("@FirstName", model.FirstName);
        parameters.Add("@LastName", model.LastName);
        parameters.Add("@Email", model.Email);
        parameters.Add("@IsAdmin", model.IsAdmin);
        parameters.Add("@IsActive", model.IsActive);

        db.Execute(sql, parameters);
    }

    internal void DeleteUser(LoginModel model) {
        string sql;
        sql = "UPDATE Users SET IsActive = 0 WHERE UserID = @UserID";
        DynamicParameters parameters = new();
        parameters.Add("@UserID", model.UserID);

        db.Execute(sql, parameters);
    }

    internal void InsertUser(LoginModel model) {
        DynamicParameters parameters = new();
        parameters.Add("@UserID", model.UserID, DbType.Int32, direction: ParameterDirection.InputOutput);
        parameters.Add("@LoginID", model.LoginID);
        parameters.Add("@FirstName", model.FirstName);
        parameters.Add("@LastName", model.LastName);
        parameters.Add("@Email", model.Email);
        parameters.Add("@IsAdmin", model.IsAdmin);

        db.Execute("InsertUsers", parameters, commandType: CommandType.StoredProcedure);
        int userid = parameters.Get<int>("@UserID");
        model.UserID = userid;
    }

    internal void UpdateInsertITARAccess(string userID, string hasITARAccess) {
        DynamicParameters parameters = new();
        parameters.Add("@UserID", userID);
        parameters.Add("@HasITARAccess", hasITARAccess);

        db.Execute("ITARAccessUpdateInsert", parameters, commandType: CommandType.StoredProcedure);
    }

    internal bool GetITARAccess(int userID) {
        DynamicParameters parameters = new();
        parameters.Add("@UserID", userID);

        var results = db.Query<string>(
            "SELECT HasITARAccess FROM SAMUsers, Users WHERE Users.UserID = @UserID AND SAMUsers.UserID = Users.LoginID",
            parameters, commandType: CommandType.Text);
        if ((results != null) && (results.Count() > 0) && (results.First() == "1"))
            return true;

        return false;
    }

    internal bool GetEC_AD_Users(string userID) {
        DynamicParameters parameters = new();
        parameters.Add("@UserID", userID);

        var results = db.Query<string>(
            "SELECT UserID FROM EC_AD_Users WHERE UserID = @UserID",
            parameters, commandType: CommandType.Text);
        if ((results != null) && (results.Count() > 0))
            return true;

        return false;
    }

    internal void ProcessOoO() {
        DynamicParameters parameters = new();
        db.Execute("ProcesOOOEnableStatus", commandType: CommandType.StoredProcedure);
    }

    internal void ExpireOoO() {
        DynamicParameters parameters = new();
        db.Execute("ProcesOOOExpiration", commandType: CommandType.StoredProcedure);
    }
}