using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Security.Claims;
using System.Text.Json;
using System.Threading.Tasks;
using Azure.Core;
using FirebaseAdmin.Auth;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using OnlineAssessment.Common;
using OnlineAssessment.Data.EFCore;
using OnlineAssessment.Domain.Models;
using OnlineAssessment.Domain.ViewModels;

namespace OnlineAssessment.V1.Controllers
{
    [Route("v{version:apiVersion}/[controller]")]
    [ApiController]
    [ApiVersion("1.0")]
    public class UsersController : BaseController<Users, EfCoreUserRepository>
    {
        private readonly IConfiguration _config;
        EfCoreUserRepository _repository;
        string responseMessage;
        public UsersController(EfCoreUserRepository repository, IConfiguration config, OdooService odooService)
            : base(repository, odooService) // Pass OdooService to the base class
        {
            _repository = repository;
            _config = config;
        }

/*
        /// <summary>
        /// Create a new user
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public IActionResult SignUp([FromBody] UserAddModel user)
        {
            int returnCode = 0;
            string returnMessage = string.Empty;
            IActionResult returnResponse;
            UserViewModel newUser = _repository.SignUp(user, out returnCode, out returnMessage);
            if (newUser != null)
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(newUser as dynamic));
            else
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotAdded.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage + " " + returnMessage));
            }

            return returnResponse;
        }

        /// <summary>
        /// User Log in 
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("[Action]")]
        [Authorize]
        public async System.Threading.Tasks.Task<IActionResult> SignIn()
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse;

            ClaimsIdentity identity = HttpContext.User.Identity as ClaimsIdentity;
            string uuid = Security.GetValueFromToken("user_id", identity);

            LoginViewModel login = _repository.SignUpStudent(identity, out returnMessage);
            if(login != null)
            {
                string token = await Security.GetFirebaseTokenAsync(uuid, login.id, login.role_id);
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(login));
            }
                
            else
            {
                responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage + " " + returnMessage));
            }

            return returnResponse;
        }
*/

        /// <summary>
        /// Admin/ Teacher Log in 
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("[Action]")]
        [Authorize]
        public async System.Threading.Tasks.Task<IActionResult> SignIn()
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse; 

            ClaimsIdentity identity = HttpContext.User.Identity as ClaimsIdentity;
            string uuid = Security.GetValueFromToken("user_id", identity);

            dynamic login = _repository.SignInAdminTeacher(identity, out returnMessage);
            if (login is LoginViewModel)
            {
                string token = await Security.GetFirebaseTokenAsync(uuid, login.id, login.role_id, base.InstituteId);
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(login));
            }
            else if (login is int && login == (int)UserMessage.InvalidUser)
            {
                responseMessage = _repository.GetMessageByCode(UserMessage.InvalidUser.ToString(), Constant.User);
                returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)UserMessage.InvalidUser, responseMessage));
            }
            else if (login is int && login == (int)Message.NotAllowedToResource)
            {
                responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage));
            }
            else
            {
                responseMessage = _repository.GetMessageByCode(Message.FailedToSignIn.ToString(), Constant.User);
                returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.FailedToAdd, responseMessage));
            }


            return returnResponse;
        }


        /// <summary>
        /// Add Admin/Teacher
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("[Action]")]
        [Authorize(Roles = "Admin")]
        public IActionResult AddAdminTeacher([FromBody] AddAdminTeacherModel userDetails)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse;

            if (userDetails == null || (userDetails.roleId != 2 && userDetails.roleId != 3))
            {
                responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString());
                returnResponse = BadRequest(ReturnResponse.GetFailureStatus(responseMessage));
            }
            
            dynamic login = _repository.AddAdminTeacher(InstituteId, userDetails.emailId, userDetails.roleId, out returnMessage);
            
            if (login is LoginViewModel)
            {
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(login.email_id));
            }                
            else if(login is int && login == (int)UserMessage.InvalidUser)
            {
                responseMessage = _repository.GetMessageByCode(UserMessage.InvalidUser.ToString(), Constant.User);
                returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)UserMessage.InvalidUser, responseMessage));
            }
            else if(login is int && login == (int)Message.NotAllowedToResource)
            {
                responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage));
            }
            else if (login is int && login == (int)UserMessage.UserAlreadyExists)
            {
                responseMessage = _repository.GetMessageByCode(UserMessage.UserAlreadyExists.ToString(), Constant.User);
                returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)UserMessage.UserAlreadyExists, responseMessage));
            }
            else
            {
                responseMessage = _repository.GetMessageByCode(Message.FailedToAdd.ToString(), Constant.User);
                returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.FailedToAdd, responseMessage));
            }

            return returnResponse;
        }

       /* 
        /// <summary>
        /// User Log in 
        /// </summary>
        /// <param name="loginCredentials"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("[Action]")]
        public IActionResult SignIn([FromBody] UserLogin loginCredentials)
        {
            int returnCode = 0;
            IActionResult returnResponse;
            LoginViewModel loggedOnUser = _repository.SignIn(loginCredentials, out returnCode);
            if (loggedOnUser != null && returnCode > 0)
            {
                //Generate and set the access token
                var secretKey = _config["Jwt:Key"].ToString();
                var issuer = _config["Jwt:Issuer"].ToString();
                var audience = _config["Jwt:Issuer"].ToString();

                //-----------------------------------------------------------------------------------------------
                loggedOnUser.JwtToken = Security.GetJwtToken(loggedOnUser, secretKey, issuer, audience);
                //-----------------------------------------------------------------------------------------------

                returnResponse = Ok(ReturnResponse.GetSuccessStatus(loggedOnUser as dynamic));
            }
            else
            {
                responseMessage = _repository.GetMessageByCode(Message.FailedToSignIn.ToString());
                switch (returnCode)
                {
                    case (int)UserMessage.InvalidUser:
                        responseMessage = string.Concat(responseMessage, ". Reason: ", _repository.GetMessageByCode(UserMessage.InvalidUser.ToString()));
                        break;
                    case (int)UserMessage.InvalidPasword:
                        responseMessage = string.Concat(responseMessage, ". Reason: ", _repository.GetMessageByCode(UserMessage.InvalidPasword.ToString()));
                        break;
                    case (int)UserMessage.UserNotActive:
                        responseMessage = string.Concat(responseMessage, ". Reason:", _repository.GetMessageByCode(UserMessage.UserNotActive.ToString()));
                        break;
                }

                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
            }


            return returnResponse;
        }
        */

        /// <summary>
        /// Get All Users (accessible to SuperAdmin only)
        /// </summary>
        /// <returns>All Users of all the institutes</returns>
        [HttpGet]
        [Authorize(Roles = "SuperAdmin")]
        public override IActionResult GetAll()
        {

            IActionResult returnResponse;
            dynamic userList = _repository.GetUsersList();
            if (userList == null)
            {
                responseMessage = _repository.GetMessageByCode(Message.NoData.ToString());
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
            }
            else
            {
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(userList));
            }
            return returnResponse;

        }


        /// <summary>
        /// Get details of an user  (accessible to SuperAdmin only)
        /// </summary>
        /// <param name="id">Id of the user</param>
        /// <returns>The user's information</returns>
        [HttpGet("{id}")]
        [Authorize(Roles = "SuperAdmin")]
        public override IActionResult Get(int id)
        {
            IActionResult returnResponse;
            dynamic entity = _repository.GetUserById(id);
            if (entity == null)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotFound.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
            }
            else
            {
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(entity));
            }
            return returnResponse;
        }

        /// <summary>
        /// Edit an user (accessible to SuperAdmin only)
        /// </summary>
        /// <param name="id">The id of the user to edit</param>
        /// <param name="userEdit">User's data to edit</param>
        /// <returns></returns>
        [HttpPost("{id}/Update")]
        [Authorize(Roles = "SuperAdmin")]
        public IActionResult Put(int id, [FromBody] UserEditModel userEdit)
        {
            IActionResult returnResponse = null;
            if (id != userEdit.Id)
            {
                responseMessage = _repository.GetMessageByCode(Message.IdMismatchBetweenBodyAndQueryString.ToString());
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                return returnResponse;
            }
            else
            {
                string returnMessage = string.Empty;
                UserViewModel uvm = _repository.UpdateUser(id, userEdit, out returnMessage);
                if (uvm != null)
                {
                    returnResponse = Ok(ReturnResponse.GetSuccessStatus(uvm));
                }
                else
                {
                    responseMessage = _repository.GetMessageByCode(Message.ObjectNotUpdated.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, returnMessage }));
                }
            }
            return returnResponse;
        }

        /// <summary>
        /// Delete a record (accessible to SuperAdmin only)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("{id}/Delete")]
        [Authorize(Roles = "SuperAdmin")]
        public IActionResult Delete(int id)
        {
            IActionResult returnResponse = null;
            try
            {
                bool isSuccess = _repository.Delete(id);
                if (isSuccess)
                {
                    responseMessage = _repository.GetMessageByCode(Message.SucessfullyDeleted.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetSuccessStatus(responseMessage));
                }
                else
                {
                    responseMessage = _repository.GetMessageByCode(Message.ObjectNotDeleted.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                }
            }
            catch (Exception ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotDeleted.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message.ToString(), ex.InnerException.Message.ToString() }));
            }
            return returnResponse;
        }


        [HttpGet]
        [AllowAnonymous]
        [Route("VerifyAccount/{code}")]
        public IActionResult ActivateUser(string code)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse = null;
            int userID = -1;
            try
            {
                userID = _repository.VerifyAccount(code, out returnMessage);
                if (userID > 0)
                {
                    responseMessage = _repository.GetMessageByCode(Message.Success.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetSuccessStatus(responseMessage));
                }
                else
                {
                    responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                }
            }
            catch (ApplicationException ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message.ToString(), ex.InnerException.Message.ToString() }));
            }

            return returnResponse;
        }

        /*
        [HttpPost]
        [AllowAnonymous]
        [Route("SignUpNew")]
        public async System.Threading.Tasks.Task<IActionResult> SignUpNew([FromBody] SignupRequestModel request)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse = null;

            string slugDomain = _repository.ConvertToSlug(request.DomainName);            
            
            try
            {
                //Check if the domain name exists
                if(_repository.isUniqueSlug(slugDomain) == false || _repository.isUniqueEmail(request.Email) == false)
                {
                    responseMessage = _repository.GetMessageByCode(Message.AlreadyExist.ToString(), slugDomain);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                // Create a new user
                var userRecordArgs = new UserRecordArgs
                {
                    Email = request.Email,
                    Password = request.Password,
                    DisplayName = "Admin",
                };
                UserRecord record = await FirebaseAuth.DefaultInstance.CreateUserAsync(userRecordArgs);
                if (record == null)
                {
                    responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                //Create Institute and Admin in my DB
                Users user = _repository.SignUpDB(record, slugDomain);
                if (user == null)
                {
                    responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                //Create company in Odoo
                var companyFields = new
                {
                    name = slugDomain,
                    barcode = user.InstituteId,
                    is_company = true, // Indicates this is a company
                };

                var odooCompanyId = await _odooService.CreateCompanyAsync("res.partner", companyFields);
                if (odooCompanyId <= 0)
                {
                    responseMessage = "Failed to create company in Odoo.";
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                // Create an employee in Odoo
                var contactFields = new Dictionary<string, object>
                {
                    { "name", "Admin" },
                    { "email", request.Email },
                    { "marital", "single" },
                    { "employee_type", "employee" },
                    { "barcode", user.Id }
                    //{ "type", "contact" }
                    //{ "company_id", odooCompanyId } // Optionally, link to the institute
                };

                int odooEmployeeId = await _odooService.CreateEmployeeAsync("hr.employee", contactFields);
                if (odooEmployeeId <= 0)
                {
                    responseMessage = "Failed to create employee in Odoo.";
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                // Assign custom claims
                var claims = new Dictionary<string, object>()
                {
                    { ClaimTypes.Role, "Admin"},
                    { "RoleId",  user.RoleId},
                    { "InstituteId", user.InstituteId },
                    { "UserId",  user.Id},
                };
                await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync(record.Uid, claims);


                var link = await FirebaseAuth.DefaultInstance.GenerateEmailVerificationLinkAsync(record.Email);
                string sent = _repository.SendEmailLink(record.Email, link);
                Console.WriteLine($"Verification Link: {link}"); // Use email service here

                
                // Return success response with Firebase and Odoo details
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(link));
                
            }
            catch (ApplicationException ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotAdded.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message.ToString(), ex.InnerException.Message.ToString() }));
            }

            return returnResponse;
        }
        */

        [HttpPost]
        [AllowAnonymous]
        [Route("SignUpAdmin")]
        public async System.Threading.Tasks.Task<IActionResult> SignUpAdmin([FromBody] SignUpRequestModel request)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse = null;

            try
            {
                // Create a new user
                var userRecordArgs = new UserRecordArgs
                {
                    Email = request.Email,
                    Password = request.Password,
                    DisplayName = request.Name,
                };

                UserRecord record = await FirebaseAuth.DefaultInstance.CreateUserAsync(userRecordArgs);
                if (record == null)
                {
                    responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                // Assign custom claims
                var claims = new Dictionary<string, object>()
                {
                    { ClaimTypes.Role, "Admin"},
                    { "RoleId",  2},
                    { "UserId",  record.Uid},
                };
                await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync(record.Uid, claims);



                var link = await FirebaseAuth.DefaultInstance.GenerateEmailVerificationLinkAsync(record.Email);
                string sent = _repository.SendEmailLink(record.Email, link);
                Console.WriteLine($"Verification Link: {link}"); // Use email service here


                // Return success response with Firebase and Odoo details
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(link));

            }
            catch (ApplicationException ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotAdded.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message.ToString(), ex.InnerException.Message.ToString() }));
            }

            return returnResponse;
        }

        /// <summary>
        /// Admin adds institute details 
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("AddInstitute")]
        [Authorize(Roles = "Admin")]
        public async System.Threading.Tasks.Task<IActionResult> AddInstitute([FromBody] DisplayName domainName)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse;
            int institute_id = -1;

            ClaimsIdentity identity = HttpContext.User.Identity as ClaimsIdentity;
            
            //Check if the inssititute is already set
            string InstituteId = Security.GetValueFromToken("InstituteId", identity);
            if (InstituteId != null)
            {
                institute_id = int.Parse(InstituteId);
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(institute_id));
                return returnResponse;
            }

            string slugDomain = _repository.ConvertToSlug(domainName.Name);
            //Check if the domain name is already picked
            if (_repository.isUniqueSlug(slugDomain) == false)
            {
                responseMessage = _repository.GetMessageByCode(Message.AlreadyExist.ToString(), slugDomain);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                return returnResponse;
            }

            string uuid = Security.GetValueFromToken("user_id", identity);            
            // Get the user record by UID
            UserRecord userRecord = await FirebaseAuth.DefaultInstance.GetUserAsync(uuid);
            if(userRecord == null || userRecord.EmailVerified == false)
            {
                responseMessage = _repository.GetMessageByCode(UserMessage.InvalidUser.ToString(), Constant.User);
                returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)UserMessage.InvalidUser, responseMessage));
                return returnResponse;
            }

            //Create Institute and Admin in my DB
            Users user = _repository.SignUpDB(userRecord, slugDomain);
            if (user == null)
            {
                responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                return returnResponse;
            }

            /* //Odoo code supress
            //Create company in Odoo
            var odooCompanyId = await companyService.CreateCompanyAsync(new
            {
                name = domainName.Name,
                barcode = user.InstituteId,
                is_company = true
            });
            if (odooCompanyId <= 0)
            {
                responseMessage = "Failed to create company in Odoo.";
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                return returnResponse;
            }

            // Create an employee in Odoo
            var odooEmployeeId = await employeeService.CreateEmployeeAsync(new
            {
                name = userRecord.DisplayName,
                work_email = userRecord.Email,
                employee_type = "employee",
                barcode = user.Id
            });

            if (odooEmployeeId <= 0)
            {
                responseMessage = "Failed to create employee in Odoo.";
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                return returnResponse;
            }

            //Update odoo employee ID and company ID
            _repository.updateOdooUser(user.Id, odooEmployeeId);
            _repository.updateOdooCompany(user.InstituteId, odooCompanyId);
            */

            // Assign custom claims
            var claims = new Dictionary<string, object>()
            {
                    { ClaimTypes.Role, "Admin"},
                    { "RoleId",  user.RoleId},
                    { "InstituteId", user.InstituteId },
                    { "UserId",  user.Id},
            };
            await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync(userRecord.Uid, claims);

            returnResponse = Ok(ReturnResponse.GetSuccessStatus(user.InstituteId));

            return returnResponse;
        }

        [HttpPost]
        [Authorize(Roles = "Admin")]
        [Route("AddStudent")]
        public async System.Threading.Tasks.Task<IActionResult> AddStudent([FromBody] SignupUserModel userModel)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse = null;

            try
            {
                // Create a new user in firebase
                var userRecordArgs = new UserRecordArgs
                {
                    DisplayName = userModel.FirstName + userModel.LastName,
                    Email = userModel.Email,
                    EmailVerified = false, // Mark email as not verified initially
                    Disabled = false,
                };
                UserRecord record = await FirebaseAuth.DefaultInstance.CreateUserAsync(userRecordArgs);
                if (record == null)
                {
                    responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                //Create student in my DB
                Users user = _repository.CreateUser(record, base.InstituteId, 4);
                if (user == null)
                {
                    responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                // Assign custom claims
                var claims = new Dictionary<string, object>()
                {
                    {ClaimTypes.Role, "Student"},
                    { "RoleId",  user.RoleId},
                    { "InstituteId", user.InstituteId },
                    { "UserId",  user.Id},
                };
                await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync(record.Uid, claims);

                var link = await FirebaseAuth.DefaultInstance.GeneratePasswordResetLinkAsync(record.Email);
                string sent = _repository.SendEmailLink(record.Email, link);
                Console.WriteLine($"Verification Link: {link}"); // Use email service here

                /* //Odoo code supress
                // Step 5: Create an employee in Odoo
                var odooEmployeeId = await employeeService.CreateEmployeeAsync(new
                {
                    name = $"{userModel.FirstName} {userModel.LastName}",
                    work_email = userModel.Email,
                    employee_type = "student",
                    barcode = user.Id
                });

                if (odooEmployeeId <= 0)
                {
                    responseMessage = "Failed to create employee in Odoo.";
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                //Update odoo employee ID and company ID
                _repository.updateOdooUser(user.Id, odooEmployeeId);
                */

                // Return success response with Firebase and Odoo details
                returnResponse = Ok(new
                {
                    Status = "Success",
                    FirebaseLink = link
                });
            }
            catch (ApplicationException ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotAdded.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string>
                {
                    responseMessage,
                    ex.Message.ToString(),
                    ex.InnerException?.Message.ToString()
                }));
            }
            catch (Exception ex)
            {
                responseMessage = "An unexpected error occurred.";
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string>
                {
                    responseMessage,
                    ex.Message
                }));
            }

            return returnResponse;
        }


        /* //Odoo code supress

        [HttpPost]
        [Authorize(Roles = "Admin")]
        [Route("UpdateStudentDetails")]
        public async System.Threading.Tasks.Task<IActionResult> UpdateStudentDetails([FromBody] UpdateUserModel userModel)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse = null;

            try
            {
                var empId = _repository.getOdooEmpID(userModel.user_id);


                if (empId == null || empId <= 0)
                {
                    responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString(), Constant.User);
                    return Ok(ReturnResponse.GetFailureStatus(responseMessage));
                }

                // Step 2: Build update dictionary only with non-null values
                var updateData = new Dictionary<string, object>();

                if (!string.IsNullOrEmpty(userModel.FirstName) || !string.IsNullOrEmpty(userModel.LastName))
                {
                    var fullName = $"{userModel.FirstName ?? ""} {userModel.LastName ?? ""}".Trim();
                    updateData["name"] = fullName;
                }

                if (userModel.gender == 1 || userModel.gender == 2)
                {
                    // Assuming: 1 = male, 2 = female
                    updateData["gender"] = userModel.gender == 1 ? "male" : "female";
                }

                if (userModel.DateOfBirth != null)
                {
                    updateData["birthday"] = userModel.DateOfBirth?.ToString("yyyy-MM-dd");
                }


                if (!string.IsNullOrEmpty(userModel.GuardianName) || !string.IsNullOrEmpty(userModel.GuardianContact))
                {
                    // Update guardian 
                    updateData["emergency_contact"] = userModel.GuardianName;
                    updateData["emergency_phone"] = userModel.GuardianContact;
                    if (userModel.Guardian_relation != null)
                    {
                        updateData["l10n_in_relationship"] = userModel.Guardian_relation;
                    }
                } 


                // Step 3: Call service to update employee
                var bResult = await employeeService.UpdateEmployeeAsync(empId, updateData);

                if (bResult == false)
                {
                    responseMessage = _repository.GetMessageByCode(Message.FailedToUpdate.ToString(), Constant.User);
                    return Ok(ReturnResponse.GetFailureStatus(responseMessage));
                }


                // Step 3: Get address_home_id (partner id) from employee
                var partnerId = await employeeService.GetAddressHomeIdByEmployeeIdAsync(empId);

                if (partnerId > 0)
                {
                    var partnerUpdateData = new Dictionary<string, object>();

                    if (!string.IsNullOrEmpty(userModel.Street)) partnerUpdateData["street"] = userModel.Street;
                    if (!string.IsNullOrEmpty(userModel.City)) partnerUpdateData["city"] = userModel.City;
                    if (!string.IsNullOrEmpty(userModel.Zip)) partnerUpdateData["zip"] = userModel.Zip;
                    if (userModel.StateId.HasValue) partnerUpdateData["state_id"] = userModel.StateId.Value;
                    if (userModel.CountryId.HasValue) partnerUpdateData["country_id"] = userModel.CountryId.Value;

                    await employeeService.UpdatePartnerAsync((int)partnerId, partnerUpdateData);
                }


                return Ok(ReturnResponse.GetSuccessStatus("Student details updated successfully."));
            }
            catch (Exception ex)
            {
                responseMessage = "An unexpected error occurred.";
                return Ok(ReturnResponse.GetFailureStatus(new List<string>
                {
                    responseMessage,
                    ex.Message,
                    ex.InnerException?.Message
                }));
            }
        }
        */


        [HttpPost]
        [Authorize(Roles = "Admin")]
        [Route("AddTeacher")]
        public async System.Threading.Tasks.Task<IActionResult> AddTeacher([FromBody] SignupUserModel userModel)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse = null;

            try
            {
                // Create a new user
                var userRecordArgs = new UserRecordArgs
                {
                    DisplayName = userModel.FirstName + userModel.LastName,
                    Email = userModel.Email,
                    EmailVerified = false, // Mark email as not verified initially
                    Disabled = false,
                };
                UserRecord record = await FirebaseAuth.DefaultInstance.CreateUserAsync(userRecordArgs);
                if (record == null)
                {
                    responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                Users user = _repository.CreateUser(record, base.InstituteId, 3);
                if (user == null)
                {
                    responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }
            
                // Assign custom claims
                var claims = new Dictionary<string, object>()
                {
                    {ClaimTypes.Role, "Teacher"},
                    { "RoleId",  user.RoleId},
                    { "InstituteId", user.InstituteId },
                    { "UserId",  user.Id},
                };
                await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync(record.Uid, claims);

                var link = await FirebaseAuth.DefaultInstance.GeneratePasswordResetLinkAsync(record.Email);
                string sent = _repository.SendEmailLink(record.Email, link);
                Console.WriteLine($"Verification Link: {link}"); // Use email service here

                /* //Odoo code supress
                // Step 5: Create an employee in Odoo
                var odooEmployeeId = await employeeService.CreateEmployeeAsync(new
                {
                    name = $"{userModel.FirstName} {userModel.LastName}",
                    work_email = userModel.Email,
                    employee_type = "employee",
                    barcode = user.Id
                });
                if (odooEmployeeId <= 0)
                {
                    responseMessage = "Failed to create employee in Odoo.";
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                //Update odoo employee ID and company ID
                _repository.updateOdooUser(user.Id, odooEmployeeId);
                */

                // Return success response with Firebase and Odoo details
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(link));

            }
            catch (ApplicationException ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotAdded.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message.ToString(), ex.InnerException.Message.ToString() }));
            }

            return returnResponse;
        }

        [HttpPost]
        [Authorize(Roles = "Admin, Teacher")]
        [Authorize(Policy = "SubscriptionRequired")]
        [Route("MarkAttendance")]
        public async Task<IActionResult> MarkAttendance([FromBody] AttendanceRequest request)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse = null;

            try
            {
                bool isValidUser = _repository.isValidUser(base.InstituteId, request.userId);

                if(isValidUser == false)
                {
                    responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;

                }

                int employeeId = _repository.getOdooEmpID(request.userId);

                string currentTime = DateTime.UtcNow.ToString("HH:mm:ss");
                string checkInTime = $"{request.date:yyyy-MM-dd} {currentTime}";
                string checkOutTime = $"{request.date:yyyy-MM-dd} {DateTime.UtcNow.AddMinutes(1):HH:mm:ss}";

                // Record attendance
                var attendanceId = await attendanceService.RecordAttendanceAsync(new
                {
                    employee_id = employeeId,
                    check_in = checkInTime,  // Current UTC time
                    check_out = checkOutTime  // 1 minute later
                });

                returnResponse = Ok(ReturnResponse.GetSuccessStatus(attendanceId));

            }
            catch (Exception ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotAdded.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message.ToString(), ex.InnerException.Message.ToString() }));
            }

            return returnResponse;
        }


        [HttpPost]
        [Authorize(Roles = "Admin, Teacher")]
        [Authorize(Policy = "SubscriptionRequired")]
        [Route("MarkAbsent")]
        public async Task<IActionResult> MarkAbsent([FromBody] AttendanceRequest request)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse = null;

            try
            {
                bool isValidUser = _repository.isValidUser(base.InstituteId, request.userId);

                if (!isValidUser)
                {
                    responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                int employeeId = _repository.getOdooEmpID(request.userId);

                // Call DeleteAttendanceAsync to delete the attendance record for the employee and date
                bool isDeleted = await attendanceService.DeleteAttendanceAsync(employeeId, request.date);

                if (isDeleted)
                {
                    returnResponse = Ok(ReturnResponse.GetSuccessStatus("Attendance marked as absent successfully."));
                }
                else
                {
                    responseMessage = _repository.GetMessageByCode(Message.FailedToDelete.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                }
            }
            catch (Exception ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotAdded.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message.ToString(), ex.InnerException?.Message.ToString() }));
            }

            return returnResponse;
        }

        [HttpPost]
        [Route("GetAttendanceByDate")]
        [Authorize(Roles = "Admin, Teacher")]
        public async Task<IActionResult> GetAttendanceByDate([FromBody] AttendanceRequestList request)
        {
            IActionResult returnResponse = null;

            try
            {
                if (request.EmployeeIds == null || request.EmployeeIds.Count == 0)
                {
                    responseMessage = _repository.GetMessageByCode(Message.MustNotEmpty.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                if (request.FromDate >= request.ToDate)
                {
                    responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                List<int> odooEmployeeIds = _repository.getOdooEmpIDList(request.EmployeeIds);

                var filterData = new
                {
                    domain = new List<object>
                    {
                        new object[] { "employee_id", "in", odooEmployeeIds },
                        new object[] { "check_in", ">=", request.FromDate.ToString("yyyy-MM-dd HH:mm:ss") },
                        new object[] { "check_in", "<=", request.ToDate.ToString("yyyy-MM-dd HH:mm:ss") }
                    }
                };

                var attendanceRecords = await attendanceService.GetAttendanceAsync(filterData);

                var attendanceLookup = attendanceRecords
                    .Select(record => ((JsonElement)record).GetProperty("employee_id").EnumerateArray().FirstOrDefault().GetInt32())
                    .ToHashSet();

                var result = request.EmployeeIds
                    .Select((userId, index) => new
                    {
                        EmployeeId = userId, // Database User ID
                        Present = attendanceLookup.Contains(odooEmployeeIds[index]) // Fast lookup
                    })
                    .ToList();

                returnResponse = Ok(ReturnResponse.GetSuccessStatus(result));
                
            }
            catch (Exception ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotAdded.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message.ToString(), ex.InnerException.Message.ToString() }));
            }

            return returnResponse;
        }


        [HttpPost]
        [Route("CreateTimetable")]
        [Authorize(Roles = "Admin, Teacher")]
        public async Task<IActionResult> CreateTimetable([FromBody] CalendarRequest request)
        {
            IActionResult returnResponse = null;

            try
            {
                if (request == null || string.IsNullOrWhiteSpace(request.Title) || request.StartTime >= request.EndTime)
                {
                    responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                var eventData = new
                {
                    name = request.Title,
                    start = request.StartTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    stop = request.EndTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    location = request.Location,
                    description = request.Description
                };

                var eventId = await calendarService.CreateEventAsync(eventData);

                returnResponse = Ok(ReturnResponse.GetSuccessStatus(new { EventId = eventId }));
            }
            catch (Exception ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotAdded.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message, ex.InnerException?.Message }));
            }

            return returnResponse;
        }


        [HttpPost]
        [Route("GetTimetableByDate")]
        [Authorize(Roles = "Admin, Teacher")]
        public async Task<IActionResult> GetTimetableByDate([FromBody] CalendarRequestList request)
        {
            IActionResult returnResponse = null;

            try
            {
                /*
                if (request.EmployeeIds == null || request.EmployeeIds.Count == 0)
                {
                    responseMessage = _repository.GetMessageByCode(Message.MustNotEmpty.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }*/

                if (request.FromDate >= request.ToDate)
                {
                    responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                //List<int> odooEmployeeIds = _repository.getOdooEmpIDList(request.EmployeeIds);

                var filterData = new
                {
                    domain = new List<object>
                {
                    //new object[] { "employee_id", "in", odooEmployeeIds },
                    new object[] { "start", ">=", request.FromDate.ToString("yyyy-MM-dd HH:mm:ss") },
                    new object[] { "stop", "<=", request.ToDate.ToString("yyyy-MM-dd HH:mm:ss") }
                }
                };

                var calenderRecords = await calendarService.GetEventsAsync(filterData);


                var eventRecords = calenderRecords
                    .Select(record =>
                    {
                        var jsonElement = (JsonElement)record;
                        return new
                        {
                            Id = jsonElement.GetProperty("id").GetInt32(),
                            Name = jsonElement.GetProperty("name").GetString(),
                            Start = jsonElement.GetProperty("start").GetString(),
                            Stop = jsonElement.GetProperty("stop").GetString(),
                            UserId = jsonElement.GetProperty("user_id").EnumerateArray().FirstOrDefault().GetInt32(),
                            PartnerIds = jsonElement.GetProperty("partner_ids").EnumerateArray().Select(p => p.GetInt32()).ToList()
                        };
                    })
                    .Select(eventObj => new CalendarRecordList
                    {
                        Id = eventObj.Id,
                        Name = eventObj.Name,
                        Start = eventObj.Start,
                        Stop = eventObj.Stop,
                        UserId = eventObj.UserId,
                        PartnerIds = eventObj.PartnerIds
                    })
                    .ToList();

                returnResponse = Ok(ReturnResponse.GetSuccessStatus(eventRecords));
            }
            catch (Exception ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotAdded.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message, ex.InnerException?.Message }));
            }

            return returnResponse;
        }

        [HttpPost]
        [Route("UpdateTimetable")]
        [Authorize(Roles = "Admin, Teacher")]
        public async Task<IActionResult> UpdateTimetable([FromBody] UpdateMeetingRequest request)
        {
            IActionResult returnResponse = null;

            try
            {
                if (request.MeetingId <= 0)
                {
                    responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                var updateData = new Dictionary<string, object>();

                if (!string.IsNullOrWhiteSpace(request.Title))
                    updateData["name"] = request.Title;

                if (request.StartTime != default)
                    updateData["start"] = request.StartTime.ToString("yyyy-MM-dd HH:mm:ss");

                if (request.EndTime != default)
                    updateData["stop"] = request.EndTime.ToString("yyyy-MM-dd HH:mm:ss");

                if (!string.IsNullOrWhiteSpace(request.Location))
                    updateData["location"] = request.Location;

                if (!string.IsNullOrWhiteSpace(request.Description))
                    updateData["description"] = request.Description;

                if (updateData.Count == 0)
                {
                    responseMessage = _repository.GetMessageByCode(Message.MustNotEmpty.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                    return returnResponse;
                }

                var success = await calendarService.UpdateMeetingAsync(request.MeetingId, updateData);

                if (success)
                {
                    returnResponse = Ok(ReturnResponse.GetSuccessStatus("Meeting updated successfully"));
                }
                else
                {
                    responseMessage = _repository.GetMessageByCode(Message.ObjectNotUpdated.ToString(), Constant.User);
                    returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
                }
            }
            catch (Exception ex)
            {
                responseMessage = _repository.GetMessageByCode(Message.ObjectNotUpdated.ToString(), Constant.User);
                returnResponse = Ok(ReturnResponse.GetFailureStatus(new List<string> { responseMessage, ex.Message, ex.InnerException?.Message }));
            }

            return returnResponse;
        }


        [HttpPost]
        [Authorize]
        [Route("SendEmailVerification")]
        public async Task<IActionResult> SendOrResendVerification([FromQuery] bool isResend)
        {
            string returnMessage = string.Empty;
            IActionResult returnResponse = null;
            
            try
            {
                // Extract the user's UID from the Firebase token
                ClaimsIdentity identity = HttpContext.User.Identity as ClaimsIdentity;
                string uid = Security.GetValueFromToken("user_id", identity);

                var userRecord = await FirebaseAuth.DefaultInstance.GetUserAsync(uid);
                if (userRecord.EmailVerified && isResend)
                {
                    return BadRequest(new { Message = "Email is already verified" });
                }

                var link = await FirebaseAuth.DefaultInstance.GenerateEmailVerificationLinkAsync(userRecord.Email);
                _repository.SendEmailLink(userRecord.Email, link);

                Console.WriteLine($"Verification Link: {link}"); // Use email service here

                return Ok(new { Message = isResend ? "Verification email resent!" : "Verification email sent!" });
            }
            catch (Exception ex)
            {
                return BadRequest(new { Message = "Error processing request", Error = ex.Message });
            }
        }



/*
        [HttpPost]
        [AllowAnonymous]
        [Route("SignInAdmin")]
        public async Task<IActionResult> SignInAdmin([FromBody] SignInRequest request)
        {
            if (string.IsNullOrEmpty(request.Email) || string.IsNullOrEmpty(request.Password))
            {
                return BadRequest(new { Message = "Email and Password are required" });
            }

            try
            {
                // Sign in with Firebase using email and password
                var auth = FirebaseAuth.DefaultInstance;
                var userCredential = await auth.SignInWithEmailAndPasswordAsync(request.Email, request.Password);

                // Get the user information
                var user = userCredential.User;
                string uid = user.Uid;

                // Check if the email is verified
                if (user.EmailVerified)
                {
                    // If email is verified, return Firebase ID token
                    string idToken = await user.GetIdTokenAsync();
                    return Ok(new { Message = "Sign-in successful", IdToken = idToken });
                }
                else
                {
                    // If the email is not verified, send verification email
                    await SendVerificationEmailAsync(user.Email);
                    return Ok(new { Message = "Email not verified. A verification email has been sent." });
                }
            }
            catch (Exception ex)
            {
                // Handle sign-in error
                return Unauthorized(new { Message = "Sign-in failed", Error = ex.Message });
            }
        }

*/

        /// <summary>
        /// Update language
        /// </summary>
        /// <param name="language"></param>
        /// <returns></returns>
        [HttpPost("{language}/UpdatePreference")]
        [Authorize(Roles = "Student")]
        public IActionResult UpdatePreference(string language)
        {
            IActionResult returnResponse = null;
            string return_message = string.Empty;
            int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity);

            int language_id = _repository.GetLanguageIdByCode(language);

            if (language_id <= 0)
            {
                responseMessage = _repository.GetMessageByCode(Message.NoData.ToString());
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
            }

            //TODO: check if works fine
            int langId = _repository.UpdateMyLanguage(user_id, language_id, out return_message);
            if (langId < 0)
            {
                responseMessage = _repository.GetMessageByCode(Message.FailedToAttach.ToString());
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
            }
            else
            {
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(return_message));
            }

            return returnResponse;
        }


        /// <summary>
        /// Attch me to usergroup
        /// </summary>
        /// <param name="user_group_id"></param>
        /// <param name="defaultGroup"></param>
        /// <returns></returns>
        [HttpPost("{user_group_id}/AttachBatch")]
        [Authorize(Roles = "Student")]
        public IActionResult AttachMeToUserGroup(int user_group_id, [FromBody] DefaultGroup defaultGroup)
        {
            IActionResult returnResponse = null;
            string return_message = string.Empty;
            int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity);

            //TODO: check if works fine
            ClassStructureViewModel csvm = _repository.AttachMeToUserGroup(base.InstituteId, user_group_id, user_id, defaultGroup.isDefault, out return_message);
            if (csvm == null)
            {
                responseMessage = _repository.GetMessageByCode(Message.FailedToAttach.ToString());
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
            }
            else
            {
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(csvm));
            }

            return returnResponse;
        }

        /// <summary>
        /// Detach user group of a user
        /// </summary>
        /// <param name="user_group_id"></param>
        /// <returns></returns>
        [HttpPost("{user_group_id}/Detach")]
        [Authorize(Roles = "Admin,Teacher,Student")]
        public IActionResult DetachUserGroup(int user_group_id)
        {
            IActionResult returnResponse = null;
            string return_message = string.Empty;
            int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity);

            int recordsEffected = _repository.DetachUserGroup(base.InstituteId, user_id, user_group_id, out return_message);
            if (recordsEffected < 0)
            {
                responseMessage = _repository.GetMessageByCode(Message.FailedToDetach.ToString());
                returnResponse = Ok(ReturnResponse.GetFailureStatus(responseMessage));
            }
            else
            {
                returnResponse = Ok(ReturnResponse.GetSuccessStatus(return_message));
            }
            
            return returnResponse;
        }
    }
}
