using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Hr;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Users;
using Ladaer.BackEnd.Infrastructures.Services.Hr;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace Ladaer.BackEnd.Controllers.Hr
{
    /// <summary>
    /// Controller d? x? lư các ho?t d?ng liên quan d?n ?ng viên.
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class CandidateController : ControllerBase
    {
        private readonly ICandidateService _candidateService;

        /// <summary>
        /// Kh?i t?o m?t instance m?i c?a l?p <see cref="CandidateController"/>.
        /// </summary>
        /// <param name="candidateService">D?ch v? x? lư ?ng viên.</param>
        public CandidateController(ICandidateService candidateService)
        {
            _candidateService = candidateService;
        }

        /// <summary>
        /// T́m ki?m các ?ng viên d?a trên các tham s? du?c cung c?p.
        /// </summary>
        /// <param name="param">Các tham s? t́m ki?m.</param>
        /// <returns>K?t qu? t́m ki?m.</returns>
        [HttpPost("Search")]
        [Authorize(Roles = "Candidate.Search")]
        public async Task<IActionResult> Search([FromBody] SmartTableParam param)
        {
            var categories = await _candidateService.Search(param);
            return Ok(categories);
        }

        /// <summary>
        /// Xóa m?t ?ng viên d?a trên ID.
        /// </summary>
        /// <param name="id">ID c?a ?ng viên.</param>
        /// <returns>K?t qu? c?a ho?t d?ng xóa.</returns>
        [HttpDelete("Delete")]
        [Authorize(Roles = "Candidate.Delete")]
        public async Task<IActionResult> Delete(int id)
        {
            var result = await _candidateService.Delete(id);
            return Ok(result);
        }

        /// <summary>
        /// L?y thông tin dánh giá c?a m?t ?ng viên d?a trên ID.
        /// </summary>
        /// <param name="id">ID c?a ?ng viên.</param>
        /// <returns>Thông tin dánh giá c?a ?ng viên.</returns>
        [HttpGet("GetReviewModel")]
        [Authorize(Roles = "Candidate.GetReviewModel")]
        public async Task<IActionResult> GetReviewModel(int id)
        {
            var result = await _candidateService.GetReviewModelById(id);
            return Ok(result);
        }

        /// <summary>
        /// C?p nh?t thông tin dánh giá c?a m?t ?ng viên.
        /// </summary>
        /// <param name="model">Model ch?a thông tin dánh giá c?a ?ng viên.</param>
        /// <returns>K?t qu? c?a ho?t d?ng c?p nh?t dánh giá.</returns>
        [HttpPut("UpdateReview")]
        [Authorize(Roles = "Candidate.UpdateReview")]
        public async Task<IActionResult> UpdateReview([FromBody] CandidateReviewModel model)
        {
            var result = await _candidateService.UpdateReview(model);
            return Ok(result);
        }

        /// <summary>
        /// T?o ?ng viên m?i.
        /// </summary>
        /// <param name="model">Thông tin ?ng viên.</param>
        /// <returns>K?t qu? c?a ho?t d?ng t?o ?ng viên.</returns>
        [HttpPost("Create")]
        [Authorize(Roles = "Candidate.Create")]
        public async Task<IActionResult> Create([FromForm] CandidateModel model)
        {
            var result = new UserResult();

            // Ki?m tra ModelState
            if (!ModelState.IsValid)
            {
                result.Result = Lada.Framework.DTO.Result.Failed;
                result.Message = "Thông tin ?ng viên chua h?p l?";
                var errors = ModelState.Values.Where(v => v.ValidationState == ModelValidationState.Invalid).ToList();
                foreach (var item in errors)
                {
                    var itemErrors = item.Errors;
                    foreach (var item2 in itemErrors)
                    {
                        result.ErrorList.Add(item2.ErrorMessage);
                    }
                }
                return Ok(result);
            }

            // L?y thông tin ngu?i dùng hi?n t?i
            var currentUser = User.GetCurrentUser();
            if (currentUser == null)
            {
                result.Result = Lada.Framework.DTO.Result.Failed;
                result.Message = "Không xác d?nh du?c ngu?i dùng";
                return Ok(result);
            }

            // Gán thông tin ngu?i t?o
            model.CreatedBy = model.UpdatedBy = currentUser.UserId;
            model.CreatedByUserName = model.UpdatedByUserName = currentUser.UserName;

            // G?i service d? t?o ?ng viên
            var serviceResult = await _candidateService.Create(model);
            result.Result = serviceResult.Result;
            result.Message = serviceResult.Message;
            return Ok(result);
        }

        /// <summary>
        /// L?y thông tin ?ng viên theo ID.
        /// </summary>
        /// <param name="id">ID c?a ?ng viên.</param>
        /// <returns>Thông tin ?ng viên.</returns>
        [HttpGet("GetById")]
        [Authorize(Roles = "Candidate.GetById")]
        public async Task<IActionResult> GetById(int id)
        {
            var result = await _candidateService.GetById(id);
            return Ok(result);
        }

        /// <summary>
        /// C?p nh?t thông tin ?ng viên.
        /// </summary>
        /// <param name="model">Thông tin ?ng viên.</param>
        /// <returns>K?t qu? c?a ho?t d?ng c?p nh?t.</returns>
        [HttpPut("Update")]
        [Authorize(Roles = "Candidate.Update")]
        public async Task<IActionResult> Update([FromForm] CandidateModel model)
        {
            var result = new UserResult();

            // Ki?m tra ModelState
            if (!ModelState.IsValid)
            {
                result.Result = Lada.Framework.DTO.Result.Failed;
                result.Message = "Thông tin ?ng viên chua h?p l?";
                var errors = ModelState.Values.Where(v => v.ValidationState == ModelValidationState.Invalid).ToList();
                foreach (var item in errors)
                {
                    var itemErrors = item.Errors;
                    foreach (var item2 in itemErrors)
                    {
                        result.ErrorList.Add(item2.ErrorMessage);
                    }
                }
                return Ok(result);
            }

            // L?y thông tin ngu?i dùng hi?n t?i
            var currentUser = User.GetCurrentUser();
            if (currentUser == null)
            {
                result.Result = Lada.Framework.DTO.Result.Failed;
                result.Message = "Không xác d?nh du?c ngu?i dùng";
                return Ok(result);
            }

            // Gán thông tin ngu?i c?p nh?t
            model.UpdatedBy = currentUser.UserId;
            model.UpdatedByUserName = currentUser.UserName;

            // G?i service d? c?p nh?t ?ng viên
            var serviceResult = await _candidateService.Update(model);
            result.Result = serviceResult.Result;
            result.Message = serviceResult.Message;
            return Ok(result);
        }

        /// <summary>
        /// Download CV c?a ?ng viên
        /// </summary>
        /// <param name="id">ID c?a ?ng viên</param>
        /// <returns>File CV</returns>
        [HttpGet("DownloadCv")]
        [Authorize(Roles = "Candidate.DownloadCv")]
        public async Task<IActionResult> DownloadCv(int id)
        {
            try
            {
                var candidate = await _candidateService.GetById(id);
                if (candidate == null || candidate.Id <= 0)
                {
                    return NotFound("Không t́m th?y ?ng viên");
                }

                if (string.IsNullOrEmpty(candidate.CvFilePath))
                {
                    return NotFound("?ng viên chua có CV");
                }

                var webRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
                var filePath = Path.Combine(webRootPath, candidate.CvFilePath);

                if (!System.IO.File.Exists(filePath))
                {
                    return NotFound("File CV không t?n t?i");
                }

                var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
                var fileName = candidate.CvFileName;
                var contentType = GetContentType(candidate.CvFileType);

                return File(fileBytes, contentType, fileName);
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"L?i t?i CV: {ex.Message}");
            }
        }

        #region Helper Methods
        /// <summary>
        /// L?y content type d?a trên extension file
        /// </summary>
        /// <param name="fileExtension">Extension file</param>
        /// <returns>Content type</returns>
        private static string GetContentType(string fileExtension)
        {
            return fileExtension.ToLowerInvariant() switch
            {
                ".pdf" => "application/pdf",
                ".doc" => "application/msword",
                ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                ".jpg" or ".jpeg" => "image/jpeg",
                ".png" => "image/png",
                _ => "application/octet-stream"
            };
        }
        #endregion
    }
}
