using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using WK_KLI_LAPS_Service.App_Data;
using WK_KLI_LAPS_Service.Controllers.WorkArea;
using WK_KLI_LAPS_Service.Hub;
using WK_KLI_LAPS_Service.Models;
using WK_KLI_LAPS_Service.Models.Master;

namespace WK_KLI_LAPS_Service.Controllers.Master.User
{
    [EnableCors("CorsPolicy")]
    // [ApiExceptionFilter]
    [Authorize]
    [ApiController]
    [Route("api/[controller]")]
    public class UserApiController : ControllerBase
    {
        CommonRepository oCommonRepository = new CommonRepository();

        private IUserService _userService;
        private readonly Appsettings _appSettings;
        private IHubContext<AuthHub> _hubContext;

        private IHostingEnvironment _hostingEnvironment;
        WorkAreaService oWorkAreaService = new WorkAreaService();
        // private ISendMailService _sendmailService;

        public UserApiController(
            IUserService userService,
            IOptions<Appsettings> appSettings,
            IHubContext<AuthHub> hubContext, IHostingEnvironment hostingEnvironment
            // , ISendMailService sendmailService
            )
        {

            _userService = userService;
            _appSettings = appSettings.Value;
            _hubContext = hubContext;
            _hostingEnvironment = hostingEnvironment;
            //_sendmailService = sendmailService;
        }
        [AllowAnonymous]
        [HttpPost("authenticate")]
        public IActionResult Authenticate([FromBody] userModel ouserModel)
        {

            if (ouserModel == null)
            {
                return BadRequest("Invalid client request");
            }

            var user = _userService.Authenticate(ouserModel.emailid, ouserModel.password);

            if (user == null)
                return BadRequest("Email Id or password is incorrect");

            if (ouserModel.loggedinflag == 0)
            {
                if (AuthHub._HubDict.TryGetValue(user.userid.ToString(), out HubCallerContext _clientHub))
                {
                    return BadRequest("loggedin");
                }
            }

            if (ouserModel.loggedinflag == 1)
            {

                string clientid = "";
                if (AuthHub._HubDict.TryGetValue(user.userid.ToString(), out HubCallerContext _clientHub))
                {
                    clientid = _clientHub.ConnectionId;
                }

                _hubContext.Clients.Client(clientid).SendAsync("Logoutclient", user.userid.ToString());

            }



            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, user.userid.ToString())
                }),
                Expires = DateTime.UtcNow.AddDays(7),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);

            //Add Login History

            loginhistoryModel lhistory = new loginhistoryModel();
            lhistory.Userid = user.userid;
            lhistory.ipaddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress?.ToString();

            Int64 returnedlogid = _userService.Addloginhistory(lhistory);
            //login checkin -> to convert lot 'H' to 'P'

            //Login_checkin(user.userid.ToString());

            // return basic user info (without password) and token to store client side
            return Ok(new
            {
                userid = user.userid,
                emailid = user.emailid,
                firstname = user.firstname,
                lastname = user.lastname,
                Token = tokenString,
                logid = returnedlogid,
                isrolemap = user.isrolemap,
                roleid=user.roleid
            });
        }

        [Authorize]
        [HttpPost("add")]

        public IActionResult add([FromForm] userModel ouserModel)
        {
            try
            {
                var res = _userService.FindbyMailId_user(ouserModel.emailid);
                if (res)
                {
                    // save 

                    if ((ouserModel.ImgFile != null) && (ouserModel.ImgFile.Length != 0))
                    {
                        string fileName = ContentDispositionHeaderValue.Parse(ouserModel.ImgFile.ContentDisposition).FileName.Trim('"');
                        fileName = DateTime.Now.ToString("ddmmyyyyhhmm_") + fileName;
                        var extension = Path.GetExtension(fileName);
                        var size = ouserModel.ImgFile.Length;

                        if (!extension.ToLower().Equals(".jpg") && !extension.ToLower().Equals(".jpeg") && !extension.ToLower().Equals(".png") && !extension.ToLower().Equals(".gif"))
                            return BadRequest("File extension is not valid.");

                        if (size > (5 * 1024 * 1024))
                            return BadRequest("File size is bigger than 5MB.");
                        string fullPath = "";
                        string folderName = "iconupload";
                        //string webRootPath = _hostingEnvironment.WebRootPath;
                        string contentRootPath = _hostingEnvironment.ContentRootPath;
                        string newPath = Path.Combine(contentRootPath, folderName);
                        if (!Directory.Exists(newPath))
                        {
                            Directory.CreateDirectory(newPath);
                        }
                        if (ouserModel.ImgFile.Length > 0)
                        {
                            fullPath = Path.Combine(newPath, fileName);
                            using (var stream = new FileStream(fullPath, System.IO.FileMode.Create))
                            {
                                ouserModel.ImgFile.CopyTo(stream);
                            }
                        }

                        ouserModel.profileimagepath = fileName;
                    }
                    ouserModel.ImgFile = null;
                    _userService.Add(ouserModel);
                    return Ok();
                }
                else
                {
                    return BadRequest("Email Id Already Exists");
                }

            }
            catch (Exception ex)
            {
                oCommonRepository.ErrorLog(ex);
                // return error message if there was an exception
                return BadRequest(new { message = ex.Message });
            }
        }

        [Authorize]
        [HttpPost("Update")]

        public IActionResult Update([FromForm] userModel ouserModel)
        {
            try
            {
                var res = _userService.FindbyMailId_userupdate(ouserModel.emailid, ouserModel.userid);
                if (res)
                {

                    if ((ouserModel.ImgFile != null) && (ouserModel.ImgFile.Length != 0))
                    {
                        string fileName = ContentDispositionHeaderValue.Parse(ouserModel.ImgFile.ContentDisposition).FileName.Trim('"');
                        var extension = Path.GetExtension(fileName);
                        var size = ouserModel.ImgFile.Length;

                        if (!extension.ToLower().Equals(".jpg") && !extension.ToLower().Equals(".jpeg") && !extension.ToLower().Equals(".png") && !extension.ToLower().Equals(".gif"))
                            return BadRequest("File extension is not valid.");

                        if (size > (5 * 1024 * 1024))
                            return BadRequest("File size is bigger than 5MB.");

                        string fullPath = "";
                        string folderName = "iconupload";
                        //string webRootPath = _hostingEnvironment.WebRootPath;
                        string contentRootPath = _hostingEnvironment.ContentRootPath;
                        string newPath = Path.Combine(contentRootPath, folderName);
                        if (!Directory.Exists(newPath))
                        {
                            Directory.CreateDirectory(newPath);
                        }
                        if (ouserModel.ImgFile.Length > 0)
                        {
                            fullPath = Path.Combine(newPath, fileName);
                            using (var stream = new FileStream(fullPath, System.IO.FileMode.Create))
                            {
                                ouserModel.ImgFile.CopyTo(stream);
                            }
                        }
                        ouserModel.profileimagepath = fileName;
                    }
                    ouserModel.ImgFile = null;
                    if (ouserModel.requestapprovedby > 0)
                    {
                        _userService.Update(ouserModel, "requestapprove");
                    }
                    else
                    {
                        _userService.Update(ouserModel, "updateuser");
                    }
                    return Ok();
                }
                else
                {
                    return BadRequest("Email Id Already Exists");
                }

            }
            catch (Exception ex)
            {
                oCommonRepository.ErrorLog(ex);
                // return error message if there was an exception
                return BadRequest(new { message = ex.Message });
            }
        }

        [AllowAnonymous]
        [HttpGet("{id}")]
        public IActionResult GetById(int id)
        {
            var user = _userService.GetById(id);
            return Ok(user);
        }

        [AllowAnonymous]
        [HttpGet("GetByUserId/{id}")]
        public IActionResult GetByUserId(int id)
        {
            var user = _userService.GetByuserId(id);
            return Ok(user);
        }



        [AllowAnonymous]
        [HttpGet("FindByMailId_User")]
        public IActionResult FindByMailId_User(string mailid)
        {
            var res = _userService.FindbyMailId_user(mailid);
            if (res)
            {
                return Ok();
            }
            else
            {
                return BadRequest("Given MailId already existed");
            }

        }

        [AllowAnonymous]
        [HttpPost("SendEmail/{emailid}")]
        public IActionResult SendEmail(string emailid)
        {
            var res = _userService.FindbyMailId_user(emailid);
            if (res == false)
            {
                //string status = _sendmailService.sendmail(emailid, "forgotpassword", _appSettings);
                //// string status = _userService.sendmail(emailid, "forgotpassword", _appSettings);
                //if (status.ToString().Equals("success"))
                //    return Ok();
                //else
                return BadRequest();
            }
            else
            {
                return BadRequest("Email Id not exists");
            }



        }




        [AllowAnonymous]
        [HttpPost("Resetpassword")]
        public IActionResult Resetpassword([FromBody] userModel ouserModel)
        {
            _userService.Resetpassword(ouserModel);
            return Ok();

        }



        [Authorize]
        [HttpPost("Changepassword")]
        public IActionResult Changepassword([FromBody] userModel ouserModel)
        {
            _userService.Changepassword(ouserModel);
            return Ok();

        }
        [Authorize]
        [HttpPost("checkoldpassword")]
        public IActionResult checkoldpassword([FromBody] userModel ouserModel)
        {
            var user = _userService.Authenticate(ouserModel.username, ouserModel.password);
            if (user == null)
                return BadRequest("Old password is incorrect");
            else
                return Ok();
        }

        [Authorize]
        [HttpGet]
        public IActionResult GetAll()
        {
            var users = _userService.GetAll();
            return Ok(users);
        }

        [Authorize]
        [HttpPost("logout/{loginid}")]
        public IActionResult Logout(string loginid)
       // [HttpPost("logout/{loginid}/{userid}")]
       // public IActionResult Logout(string loginid, string userid)
        {
            if (!string.IsNullOrEmpty(loginid))
            {
                Int64 returnedlogid = _userService.Logout(Convert.ToInt64(loginid));
                //for user status update to hold while logout
                if (returnedlogid == -1)
                {
                    // Logout_checkout(userid);
                }
            }
            

            return Ok();
        }  
        [Authorize]
        [HttpPost("PendingLotInfo/{userid}")]
        public IActionResult PendingLotInfo(string userid)
        {
            if (!string.IsNullOrEmpty(userid))
            {
                _userService.Pendinglots(Convert.ToInt64(userid));
            }
            return Ok();
        }
        public void Logout_checkout(string userid)
        {
            try
            {
                var result = oWorkAreaService.getCheckout("0", userid, "", "logout_checkout", "0", "");

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public void Login_checkin(string userid)
        {
            try
            {
                var result = oWorkAreaService.getCheckout("0", userid, "", "login_checkin", "0", "");

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        [Authorize]
        [HttpPost("GetByRoleId")]
        //Code to retrieve all data
        public IActionResult GetByRoleId([FromBody] userModel ouserModel)
        {
            var _countResult = _userService.GetByRoleId(ouserModel);
            return Ok(_countResult);
        }
        [Authorize]
        [HttpGet("GetActiveUsers")]
        //Code to retrieve active data
        public IActionResult GetActiveUsers()
        {
            try
            {
                var _list = _userService.GetActiveUsers();
                return Ok(_list);
            }
            catch (Exception ex)
            {
                oCommonRepository.ErrorLog(ex);
                return NotFound();
            }

        }

        [Authorize]
        [HttpPost("delete")]
        public IActionResult Delete([FromBody] userModel user)
        {
            _userService.Delete(user);
            return Ok();
        }

        //Code to get profile image
        [Authorize]
        [HttpPost("GetIcon/{filename}")]

        public IActionResult GetIcon(string filename)
        {
            if (filename != null || filename.Length > 0)
            {
                try
                {
                    string contentRootPath = _hostingEnvironment.ContentRootPath;
                    string path = contentRootPath + "/iconupload/" + filename;
                    byte[] image = System.IO.File.ReadAllBytes(path);
                    return Ok(new { Image = image });
                }
                catch
                {
                    return Ok(new { Image = "" });
                }

            }

            return Ok();
        }

        [Authorize]
        [HttpGet("GetUsersByDepartment/{departmentid}")]
        public IActionResult GetUsersByDepartment(int departmentid)
        {
            var user = _userService.GetUsersByDepartment(departmentid);
            return Ok(user);
        }
        [Authorize]
        [HttpGet("GetUsersPendinginfo/{id}")]
        public IActionResult GetUsersPendinginfo(int id)
        {
            try
            {
                var user = _userService.GetUserPending(id);
                return Ok(user);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                return NotFound();
            }

        } [Authorize]
        [HttpGet("GetUsersRights/{id}")]
        public IActionResult GetUsersRights(int id)
        {
            try
            {
                var user = _userService.GetUserRights(id);
                return Ok(user);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                return NotFound();
            }

        }

        //gokul added 01-02-2023
        [Authorize]
        [HttpGet("Get_allusermailmapping")]
        public IActionResult Get_allusermailmapping()
        
        {
            try
            {
                var list = _userService.GetMailFolderLst();
                //var list_ = JsonConvert.DeserializeObject(list.ToString());
                return Ok(list);
            }
            catch (Exception ex)
            {
                oCommonRepository.ErrorLog(ex);
                // return error message if there was an exception
                return BadRequest(new { message = ex.Message });
            }
           
        }

        [Authorize]
        [HttpPost("Add_mailfoldername")]
        public IActionResult Add_mailfoldername([FromBody] usermailfoldermapping_model data)
        {
            try
            {
                var mailfolder = _userService.Add_Mailfolder(data);
                if(Convert.ToInt32(mailfolder) == 2)
                {
                    return BadRequest("Folder name is already exist");
                }
                else
                {
                    return Ok();
                }
               

            }catch(Exception ex)
            {
                oCommonRepository.ErrorLog(ex);
                // return error message if there was an exception
                return BadRequest(new { message = ex.Message });
            }
        }

        [Authorize]
        [HttpPost("Add_usermailfoldername")]
        public IActionResult Add_usermailfoldername([FromBody] usermailfoldermapping_model data)
        {
            try
            {
                var mailfolder = _userService.Add_userMailfolder(data);
                return Ok();

            }
            catch (Exception ex)
            {
                oCommonRepository.ErrorLog(ex);
                // return error message if there was an exception
                return BadRequest(new { message = ex.Message });
            }
        }
        
        [Authorize]
        [HttpPost("Update_usermailfolder")]
        public IActionResult Update_usermailfolder([FromBody] usermailfoldermapping_model data)
        {
            try
            {
                var mailfolder = _userService.Update_userMailfolder(data);
                return Ok();

            }
            catch (Exception ex)
            {
                oCommonRepository.ErrorLog(ex);
                // return error message if there was an exception
                return BadRequest(new { message = ex.Message });
            }
        }
        [Authorize]
        [HttpPost("Update_foldername")]
        public IActionResult Update_foldername([FromBody] usermailfoldermapping_model data)
        {
            try
            {
                var mailfolder = _userService.Update_foldername(data);
                return Ok();

            }
            catch (Exception ex)
            {
                oCommonRepository.ErrorLog(ex);
                // return error message if there was an exception
                return BadRequest(new { message = ex.Message });
            }
        }
        
        [Authorize]
        [HttpPost("Delete_mailfoldermapping")]
        public IActionResult Delete_mailfoldermapping([FromBody] usermailfoldermapping_model data)
        {
            try
            {
                var mailfolder = _userService.Delete_mailfoldermapping(data);
                return Ok();

            }
            catch (Exception ex)
            {
                oCommonRepository.ErrorLog(ex);
                // return error message if there was an exception
                return BadRequest(new { message = ex.Message });
            }
        }


        

    }
}