using Lada.Framework.Data.Enums;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Business;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Categories;
using Ladaer.BackEnd.Infrastructures.Services.Business;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp;

namespace Ladaer.BackEnd.Controllers.Ops
{
    /// <summary>
    /// Controller quản lý các hoạt động liên quan đến triển khai đơn hàng.
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class DeployController : ControllerBase
    {
        private readonly IDeployService _deployService;

        /// <summary>
        /// Khởi tạo một instance mới của lớp <see cref="DeployController"/>.
        /// </summary>
        /// <param name="deployService">Dịch vụ xử lý triển khai đơn hàng.</param>
        public DeployController(IDeployService deployService)
        {
            _deployService = deployService;
        }

        /// <summary>
        /// Lấy danh sách các địa điểm triển khai.
        /// </summary>
        /// <returns>Danh sách các địa điểm triển khai.</returns>
        [HttpGet("GetDeployLocations")]
        [Authorize(Roles = "Deploy.GetDeployLocations")]
        public async Task<IActionResult> GetDeployLocations()
        {
            var orderStatus = OrderStatus.New;
            var physicalStatus = OrderPhysicalStatus.WaitToPickup;
            var addressType = AddressType.Source;
            var result = await _deployService.GetDeployLocations(orderStatus, physicalStatus, addressType);
            return Ok(result);
        }

        #region Delivery
        /// <summary>
        /// Lấy danh sách các địa điểm trung chuyển.
        /// </summary>
        /// <returns>Danh sách các địa điểm nhận hàng.</returns>
        [HttpGet("GetDeliveryLocations")]
        [Authorize(Roles = "Deploy.GetDeliveryLocations")]
        public async Task<IActionResult> GetDeliveryLocations()
        {
            var orderStatus = OrderStatus.Received;
            var physicalStatus = OrderPhysicalStatus.Inbound;
            var addressType = AddressType.Dest;
            var result = await _deployService.GetDeployLocations(orderStatus, physicalStatus, addressType);
            return Ok(result);
        }

        /// <summary>
        /// Lấy danh sách các đơn hàng cần nhận hàng dựa trên các tham số tìm kiếm.
        /// </summary>
        /// <param name="param">Các tham số tìm kiếm.</param>
        /// <returns>Danh sách các đơn hàng cần nhận hàng.</returns>
        [HttpPost("GetDeliveryOrders")]
        [Authorize(Roles = "Deploy.GetDeliveryOrders")]
        public async Task<IActionResult> GetDeliveryOrders(SmartTableParam param)
        {
            var orderStatus = OrderStatus.Received;
            var physicalStatuses = new List<OrderPhysicalStatus>() { OrderPhysicalStatus.Inbound };
            var addressType = AddressType.Dest;

            param.Search.PredicateObject["OrderStatus"] = new JValue(orderStatus);
            param.Search.PredicateObject["OrderPhysicalStatuses"] = new JArray(physicalStatuses);
            param.Search.PredicateObject["AddressType"] = new JValue(addressType);

            var result = await _deployService.GetDeployOrders(param);
            return Ok(result);
        }

        /// <summary>
        /// Gán giao hàng
        /// </summary>
        /// <param name="model">Model gán</param>
        /// <returns></returns>
        [HttpPost("AssignDelivery")]
        [Authorize(Roles = "Deploy.AssignDelivery")]
        public async Task<IActionResult> AssignDelivery(AssignModel model)
        {
            var currentUser = User.GetCurrentUser();
            if (currentUser == null)
            {
                return BadRequest("Không xác định được người dùng");
            }

            model.UpdatedBy = currentUser.UserId;
            model.UpdatedByUserName = currentUser.UserName;
            if (model.UpdatedBy <= 0 || string.IsNullOrEmpty(model.UpdatedByUserName))
            {
                return BadRequest("Không xác định được người dùng");
            }
            var result = await _deployService.AssignDelivery(model);
            return Ok(result);
        }

        #endregion


        #region Pickup
        /// <summary>
        /// Lấy danh sách các địa điểm nhận hàng.
        /// </summary>
        /// <returns>Danh sách các địa điểm nhận hàng.</returns>
        [HttpGet("GetPickupLocations")]
        [Authorize(Roles = "Deploy.GetPickupLocations")]
        public async Task<IActionResult> GetPickupLocations()
        {
            var orderStatus = OrderStatus.New;
            var physicalStatus = OrderPhysicalStatus.WaitToPickup;
            var addressType = AddressType.Source;
            var result = await _deployService.GetDeployLocations(orderStatus, physicalStatus, addressType);
            return Ok(result);
        }

        /// <summary>
        /// Lấy danh sách các đơn hàng cần nhận hàng dựa trên các tham số tìm kiếm.
        /// </summary>
        /// <param name="param">Các tham số tìm kiếm.</param>
        /// <returns>Danh sách các đơn hàng cần nhận hàng.</returns>
        [HttpPost("GetPickupOrders")]
        [Authorize(Roles = "Deploy.GetPickupOrders")]
        public async Task<IActionResult> GetPickupOrders(SmartTableParam param)
        {
            var orderStatus = OrderStatus.New;
            var physicalStatuses = new List<OrderPhysicalStatus>() { OrderPhysicalStatus.WaitToPickup };
            var addressType = AddressType.Source;

            param.Search.PredicateObject["OrderStatus"] = new JValue(orderStatus);
            param.Search.PredicateObject["OrderPhysicalStatuses"] = new JArray(physicalStatuses);
            param.Search.PredicateObject["AddressType"] = new JValue(addressType);

            var result = await _deployService.GetDeployOrders(param);
            return Ok(result);
        }

        /// <summary>
        /// Gán nhiệm vụ nhận hàng cho người dùng.
        /// </summary>
        /// <param name="model">Model chứa thông tin gán nhiệm vụ.</param>
        /// <returns>Kết quả của hoạt động gán nhiệm vụ.</returns>
        [HttpPost("AssignPickup")]
        [Authorize(Roles = "Deploy.AssignPickup")]
        public async Task<IActionResult> AssignPickup(AssignModel model)
        {
            var currentUser = User.GetCurrentUser();
            if (currentUser == null)
            {
                return BadRequest("Không xác định được người dùng");
            }

            model.UpdatedBy = currentUser.UserId;
            model.UpdatedByUserName = currentUser.UserName;
            if (model.UpdatedBy <= 0 || string.IsNullOrEmpty(model.UpdatedByUserName))
            {
                return BadRequest("Không xác định được người dùng");
            }
            var result = await _deployService.AssignPickup(model);
            return Ok(result);
        }

        /// <summary>
        /// Hủy gán nhiệm vụ nhận hàng cho người dùng.
        /// </summary>
        /// <param name="model">Model chứa thông tin hủy gán nhiệm vụ.</param>
        /// <returns>Kết quả của hoạt động hủy gán nhiệm vụ.</returns>
        [HttpPost("UnAssignPickup")]
        [Authorize(Roles = "Deploy.UnAssignPickup")]
        public async Task<IActionResult> UnAssignPickup(AssignModel model)
        {
            var currentUser = User.GetCurrentUser();
            if (currentUser == null)
            {
                return BadRequest("Không xác định được người dùng");
            }

            model.UpdatedBy = currentUser.UserId;
            model.UpdatedByUserName = currentUser.UserName;
            if (model.UpdatedBy <= 0 || string.IsNullOrEmpty(model.UpdatedByUserName))
            {
                return BadRequest("Không xác định được người dùng");
            }
            var result = await _deployService.UnAssignPickup(model);
            return Ok(result);
        }
        #endregion


        #region Transit
        /// <summary>
        /// Lấy danh sách các địa điểm trung chuyển.
        /// </summary>
        /// <returns>Danh sách các địa điểm trung chuyển.</returns>
        [HttpGet("GetTransitLocations")]
        [Authorize(Roles = "Deploy.GetTransitLocations")]
        public async Task<IActionResult> GetTransitLocations()
        {
            var orderStatus = OrderStatus.Received;
            var physicalStatus = OrderPhysicalStatus.Inbound;
            var addressType = AddressType.Dest;
            var result = await _deployService.GetDeployLocations(orderStatus, physicalStatus, addressType);
            return Ok(result);
        }

        /// <summary>
        /// Lấy danh sách các đơn hàng cần trung chuyển dựa trên các tham số tìm kiếm.
        /// </summary>
        /// <param name="param">Các tham số tìm kiếm.</param>
        /// <returns>Danh sách các đơn hàng cần trung chuyển.</returns>
        [HttpPost("GetTransitOrders")]
        [Authorize(Roles = "Deploy.GetTransitOrders")]
        public async Task<IActionResult> GetTransitOrders(SmartTableParam param)
        {
            var orderStatus = OrderStatus.Received;
            var physicalStatuses = new List<OrderPhysicalStatus>() { OrderPhysicalStatus.Inbound };
            var addressType = AddressType.Dest;

            param.Search.PredicateObject["OrderStatus"] = new JValue(orderStatus);
            param.Search.PredicateObject["OrderPhysicalStatuses"] = new JArray(physicalStatuses);
            param.Search.PredicateObject["AddressType"] = new JValue(addressType);

            var result = await _deployService.GetDeployOrders(param);
            return Ok(result);
        }

        /// <summary>
        /// Gán trung chuyển
        /// </summary>
        /// <param name="model">Model gán</param>
        /// <returns></returns>
        [HttpPost("AssignTransit")]
        [Authorize(Roles = "Deploy.AssignTransit")]
        public async Task<IActionResult> AssignTransit(AssignModel model)
        {
            var currentUser = User.GetCurrentUser();
            if (currentUser == null)
            {
                return BadRequest("Không xác định được người dùng");
            }

            model.UpdatedBy = currentUser.UserId;
            model.UpdatedByUserName = currentUser.UserName;
            if (model.UpdatedBy <= 0 || string.IsNullOrEmpty(model.UpdatedByUserName))
            {
                return BadRequest("Không xác định được người dùng");
            }
            var result = await _deployService.AssignTransit(model);
            return Ok(result);
        }

        #endregion


        /// <summary>
        /// Lấy thông tin giám sát đơn hàng.
        /// </summary>
        /// <param name="pageNumber">Số trang.</param>
        /// <param name="pageSize">Kích thước trang.</param>
        /// <returns>Thông tin giám sát đơn hàng.</returns>
        [HttpGet("GetDeployMonitor")]
        [Authorize(Roles = "Deploy.GetDeployMonitor")]
        public async Task<IActionResult> GetDeployMonitor(int pageNumber = 1, int pageSize = 10)
        {
            var result = await _deployService.GetDeployMonitor(pageNumber, pageSize);
            return Ok(result);
        }

        /// <summary>
        /// Lấy chi tiết đơn hàng dựa trên các tham số tìm kiếm.
        /// </summary>
        /// <param name="param">Các tham số tìm kiếm.</param>
        /// <returns>Chi tiết đơn hàng.</returns>
        [HttpPost("GetDeployDetail")]
        [Authorize(Roles = "Deploy.GetDeployDetail")]
        public async Task<IActionResult> GetDeployDetail(SmartTableParam param)
        {
            var result = await _deployService.GetDeployDetail(param);
            return Ok(result);
        }
        /// <summary>
        /// Sắp xếp thứ tự hiển thị đơn hàng
        /// </summary>
        [HttpPost("ReorderOrders")]
        [Authorize(Roles = "Deploy.ReorderOrders")]
        public async Task<IActionResult> ReorderOrders([FromBody] ReorderModel model)
        {
            var currentUser = User.GetCurrentUser();
            if (currentUser == null)
            {
                return BadRequest("Không có người dùng");
            }
            if (currentUser.UserId <= 0)
            {
                return BadRequest("Không xác định được người dùng");
            }

            try
            {
                var result = await _deployService.ReorderOrders(model, currentUser.UserId, currentUser.UserName);
                return Ok(result);
            }
            catch (System.Exception ex)
            {
                return StatusCode(500, "Đã xảy ra lỗi khi sắp xếp đơn hàng");
            }
        }
    }
}
