using Hangfire;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Lada.Framework.Infrastructures.Services;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Categories;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Categories;
using Ladaer.BackEnd.Infrastructures.Services.Categories;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Ladaer.BackEnd.Controllers.Systems
{
    /// <summary>
    /// Controller để xử lý các hoạt động liên quan tới địa điểm.
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class LocationController : ControllerBase
    {
        private readonly ILocationService _locationService;

        /// <summary>
        /// Khởi tạo một instance mới của lớp <see cref="LocationController"/>.
        /// </summary>
        /// <param name="locationService">Dịch vụ xử lý địa điểm.</param>
        public LocationController(ILocationService locationService, IGoogleMapService googleMapService)
        {
            _locationService = locationService;
        }

        #region SEARCH

        /// <summary>
        /// Tìm kiếm các địa điểm dựa trên các tham số đượ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 = "Location.Search")]
        public async Task<IActionResult> Search([FromBody] SmartTableParam param)
        {
            var locations = await _locationService.Search(param);
            return Ok(locations);
        }

        #endregion

        #region CRUD

        /// <summary>
        /// Tạo hoặc cập nhật thông tin địa điểm.
        /// </summary>
        /// <param name="locationModel">Model chứa thông tin địa điểm.</param>
        /// <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        [HttpPost("CreateOrUpdate")]
        [Authorize(Roles = "Location.CreateOrUpdate")]
        public async Task<IActionResult> CreateOrUpdate([FromBody] LocationModel locationModel)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var currentUser = User.GetCurrentUser();
            locationModel.UpdatedBy = currentUser.UserId;
            locationModel.UpdatedByUserName = currentUser.UserName;
            if (locationModel.UpdatedBy <= 0 || string.IsNullOrEmpty(locationModel.UpdatedByUserName))
            {
                return BadRequest("Không xác định được người dùng");
            }

            var result = await _locationService.CreateOrUpdate(locationModel);
            return Ok(result);
        }

        /// <summary>
        /// Lấy thông tin chi tiết của một địa điểm dựa trên ID.
        /// </summary>
        /// <param name="id">ID của địa điểm.</param>
        /// <returns>Thông tin chi tiết của địa điểm.</returns>
        [HttpGet("GetById")]
        [Authorize(Roles = "Location.GetById")]
        public async Task<IActionResult> GetById(int id)
        {
            var result = await _locationService.GetById(id);
            return Ok(result);
        }

        /// <summary>
        /// Lấy địa chỉ đầy đủ của một phường/xã dựa trên ID.
        /// </summary>
        /// <param name="id">ID của phường/xã.</param>
        /// <returns>Địa chỉ đầy đủ của phường/xã.</returns>
        [HttpGet("GetFullAddressByWard")]
        [Authorize(Roles = "Location.GetFullAddressByWard")]
        public async Task<IActionResult> GetFullAddressByWard(int id)
        {
            var result = await _locationService.GetFullAddress(id, 3);
            return Ok(result);
        }

        /// <summary>
        /// Xóa một địa điểm dựa trên ID.
        /// </summary>
        /// <param name="id">ID của địa điểm.</param>
        /// <returns>Kết quả của hoạt động xóa.</returns>
        [HttpDelete("Delete")]
        [Authorize(Roles = "Location.Delete")]
        public async Task<IActionResult> Delete(int id)
        {
            var currentUser = User.GetCurrentUser();
            if (currentUser == null)
            {
                return BadRequest("Không xác định được người dùng");
            }
            var result = await _locationService.Delete(id, currentUser);
            return Ok(result);
        }

        #endregion

        #region Autocomplete

        /// <summary>
        /// Gọi API tìm kiếm địa điểm dựa trên từ khóa, loại và ID cha.
        /// </summary>
        /// <param name="keyword">Từ khóa tìm kiếm.</param>
        /// <param name="type">Loại địa điểm.</param>
        /// <param name="parentId">ID cha.</param>
        /// <returns>Danh sách địa điểm phù hợp.</returns>
        [HttpGet("LoSug")]
        [Authorize(Roles = "Location.LocationSuggestion")]
        public async Task<IActionResult> LocationSuggestion(string? keyword, SuggestionType type, int parentId)
        {
            var suggests = await _locationService.GetSugLocations(keyword, type, parentId);
            return Ok(suggests);
        }

        /// <summary>
        /// Tìm kiếm địa chỉ hoàn thành dựa trên từ khóa.
        /// </summary>
        /// <param name="keyword">Từ khóa tìm kiếm.</param>
        /// <returns>Danh sách địa chỉ phù hợp.</returns>
        [HttpGet("AddressAutocomplete")]
        [Authorize(Roles = "Location.AddressAutocomplete")]
        public async Task<IActionResult> AddressAutocomplete(string? keyword)
        {
            var suggests = await _locationService.PlaceAutocomplete(keyword);
            return Ok(suggests);
        }

        /// <summary>
        /// Lấy chi tiết địa điểm dựa trên ID địa điểm.
        /// </summary>
        /// <param name="placeId">ID của địa điểm.</param>
        /// <returns>Chi tiết địa điểm.</returns>
        [HttpGet("PlaceDetail")]
        [Authorize(Roles = "Location.PlaceDetail")]
        public async Task<IActionResult> PlaceDetail(string placeId)
        {
            var suggests = await _locationService.PlaceDetail(placeId);
            return Ok(suggests);
        }

        #endregion

        #region Hangfire Job

        /// <summary>
        /// Kích hoạt công việc cập nhật tên kết hợp (CombinedName).
        /// </summary>
        /// <returns>Thông báo kết quả kích hoạt công việc.</returns>
        [HttpGet("UpdateCombinedName")]
        [Authorize(Roles = "Founder")]
        public IActionResult UpdateCombinedName()
        {
            try
            {
                RecurringJob.AddOrUpdate("UpdateCombinedName", () => _locationService.UpdateCombinedName(), Cron.Minutely());
                return Ok("GetLatLngJob - �� k�ch ho?t t? d?ng c?p nh?t CombinedName");
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

        #endregion
    }
}
