using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.AppSettings;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Orders;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates;
using Ladaer.BackEnd.Infrastructures.DTO.Results;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Orders;
using Ladaer.BackEnd.Infrastructures.Services;
using Ladaer.BackEnd.Infrastructures.Services.Orders;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Lada.Framework.Data.Enums;
using System.ComponentModel;
using Lada.Framework.Infrastructures.Extensions;
using System.Reflection;
using Lada.Framework.DTO;

namespace Ladaer.BackEnd.Controllers.Orders
{
    /// <summary>
    /// Controller để xử lý các hoạt động liên quan tới đơn hàng
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class OrderController : ControllerBase
    {
        private readonly IOrderService _orderService;
        private readonly string _mapApiKey;

        /// <summary>
        /// Khởi tạo một instance mới của lớp <see cref="OrderController"/>.
        /// </summary>
        /// <param name="options">Tùy chọn cấu hình ứng dụng.</param>
        /// <param name="orderService">Dịch vụ xử lý đơn hàng.</param>
        public OrderController(IOptions<AppSetting> options, IOrderService orderService)
        {
            _orderService = orderService;
            _mapApiKey = options.Value.GoogleMapsApi.ApiKey;
        }

        /// <summary>
        /// Tìm kiếm đơn hàng theo các tham số 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 = "Order.Search")]
        public async Task<IActionResult> Search(SmartTableParam param)
        {

            var currentUser = User.GetCurrentUser();
            var result = await _orderService.Search(param, currentUser.UserId);

            return Ok(result);
        }

        /// <summary>
        /// Tạo mới một đơn hàng.
        /// </summary>
        /// <param name="model">Model chứa thông tin đơn hàng.</param>
        /// <returns>Kết quả của hoạt động tạo đơn hàng.</returns>
        [HttpPost("CreateOrder")]
        [Authorize(Roles = "Order.CreateOrder")]
        public async Task<IActionResult> CreateOrder(OrderModel model)
        {
            var rs = new OrderResult();
            if (!ModelState.IsValid)
            {
                var errors = ModelState.Where(x => x.Value != null && x.Value.Errors != null && x.Value.Errors.Count > 0)
                    .Select(x => new Error()
                    {
                        Key = x.Key,
                        Message = string.Join("\n", (x.Value?.Errors ?? new Microsoft.AspNetCore.Mvc.ModelBinding.ModelErrorCollection()).Select(v => v.ErrorMessage).ToList())
                    })
                    .ToList();
                rs.Errors = errors;
                rs.Result = Lada.Framework.DTO.Result.Failed;
                rs.Message = "Model truyền vào chưa hợp lệ";
            }
            else
            {
                var currentUser = User.GetCurrentUser();
                model.UpdatedBy = currentUser.UserId;
                model.UpdatedByUserName = currentUser.UserName;
                if (model.SaleId <= 0)
                {
                    model.SaleId = currentUser.UserId;
                }
                rs = await _orderService.Create(model, _mapApiKey);
            }

            return Ok(rs);
        }

        /// <summary>
        /// Lấy thông tin chi tiết của đơn hàng dựa trên mã đơn hàng.
        /// </summary>
        /// <param name="code">Mã đơn hàng.</param>
        /// <returns>Thông tin chi tiết của đơn hàng.</returns>
        [HttpGet("Tracking")]
        [Authorize(Roles = "Order.Orderdetail")]
        public async Task<IActionResult> Orderdetail(string code)
        {
            var currentUser = User.GetCurrentUser();
            var rs = await _orderService.OrderDetailByCode(code, currentUser);
            return Ok(rs);
        }

        /// <summary>
        /// Lấy thông tin chi tiết của đơn hàng theo mã đơn hàng với thông tin đơn vị do.
        /// </summary>
        /// <param name="code">Mã đơn hàng.</param>
        /// <returns>Thông tin chi tiết của đơn hàng với đơn vị do.</returns>
        [HttpGet("TrackingWithUnits")]
        [Authorize(Roles = "Order.OrderdetailWithUnits")]
        public async Task<IActionResult> OrderdetailWithUnits(string code)
        {
            var currentUser = User.GetCurrentUser();
            var rs = await _orderService.OrderDetailByCodeWithUnits(code, currentUser);
            return Ok(rs);
        }

        /// <summary>
        /// Hủy một đơn hàng.
        /// </summary>
        /// <param name="model">Model chứa thông tin đơn hàng cần hủy.</param>
        /// <returns>Kết quả của hoạt động hủy đơn hàng.</returns>
        [HttpPut("Cancel")]
        [Authorize(Roles = "Order.Cancel")]
        public async Task<IActionResult> Cancel(UpdateStatusModel model)
        {
            var currentUser = User.GetCurrentUser();
            model.UpdatedBy = currentUser.UserId;
            model.UpdatedByUserName = currentUser.UserName;
            var result = await _orderService.Cancel(model);
            return Ok(result);
        }

        /// <summary>
        /// Gỡ bỏ trạng thái hủy của một đơn hàng.
        /// </summary>
        /// <param name="model">Model chứa thông tin đơn hàng cần gỡ bỏ trạng thái hủy.</param>
        /// <returns>Kết quả của hoạt động gỡ bỏ trạng thái hủy.</returns>
        [HttpPut("RemoveCancel")]
        [Authorize(Roles = "Order.RemoveCancel")]
        public async Task<IActionResult> RemoveCancel(UpdateStatusModel model)
        {
            var currentUser = User.GetCurrentUser();
            model.UpdatedBy = currentUser.UserId;
            model.UpdatedByUserName = currentUser.UserName;
            var result = await _orderService.RemoveCancel(model);
            return Ok(result);
        }

        /// <summary>
        /// Lấy danh sách các phương thức thanh toán có sẵn
        /// </summary>
        /// <returns>Danh sách phương thức thanh toán</returns>
        [HttpGet("PaymentMethods")]
        [Authorize(Roles = "Order.Search")]
        public IActionResult GetPaymentMethods()
        {
            var paymentMethods = Enum.GetValues<OrderFinEnum.PayFeeType>()
                .Select(x => new
                {
                    Value = (int)x,
                    Name = x.GetDescription(),
                    Code = x.ToString()
                })
                .ToList();

            return Ok(paymentMethods);
        }

        /// <summary>
        /// Lấy danh sách các loại thời gian có sẵn cho bộ lọc
        /// </summary>
        /// <returns>Danh sách các loại thời gian</returns>
        [HttpGet("TimeFilterTypes")]
        [Authorize(Roles = "Order.Search")]
        public IActionResult GetTimeFilterTypes()
        {
            var timeFilterTypes = new[]
            {
                new
                {
                    Key = "PickupTime",
                    Name = "Thời gian lấy hàng",
                    Description = "Thời gian lấy hàng thành công",
                    StartField = "PickupTimeStart",
                    EndField = "PickupTimeEnd"
                },
                new
                {
                    Key = "DeliveryTime",
                    Name = "Thời gian giao hàng",
                    Description = "Thời gian giao hàng thành công",
                    StartField = "DeliveryTimeStart",
                    EndField = "DeliveryTimeEnd"
                },
                new
                {
                    Key = "HeadFeeTime",
                    Name = "Thời gian tổng nhận tiền",
                    Description = "Thời gian công ty nhận tiền (lấy hàng, giao hàng, chuyển khoản, cấn trừ COD)",
                    StartField = "HeadFeeTimeStart",
                    EndField = "HeadFeeTimeEnd"
                }
            };

            return Ok(timeFilterTypes);
        }

        /// <summary>
        /// Xuất Excel danh sách đơn hàng
        /// </summary>
        /// <param name="model">Model xuất Excel</param>
        /// <returns>Kết quả xuất file</returns>
        [HttpPost("Export")]
        [Authorize(Roles = "Order.ExportExcel")]
        public async Task<IActionResult> ExportOrders([FromBody] OrderExcelExportModel model)
        {
            try
            {
                var currentUser = User.GetCurrentUser();
                if (currentUser == null)
                {
                    return Unauthorized("Không xác định được người dùng");
                }

                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                // Set thông tin người tạo
                model.UpdatedBy = currentUser.UserId;
                model.UpdatedByUserName = currentUser.UserName;

                var result = await _orderService.ExportOrdersAsync(model);

                if (result.Result == Result.Success)
                {
                    // Sử dụng URL từ ExcelFileService, nếu không có thì tạo fallback URL
                    if (string.IsNullOrEmpty(result.DownloadUrl) && !string.IsNullOrEmpty(result.FilePath))
                    {
                        var fileName = Path.GetFileName(result.FilePath);
                        result.DownloadUrl = $"/api/Order/Download/{fileName}";
                    }

                    return Ok(result);
                }
                else
                {
                    return BadRequest(result);
                }
            }
            catch (Exception ex)
            {
                return StatusCode(500, new OrderExcelExportResult
                {
                    Result = Result.SystemError,
                    Message = $"Lỗi hệ thống: {ex.Message}"
                });
            }
        }

        /// <summary>
        /// Download file Excel đã xuất
        /// </summary>
        /// <param name="fileName">Tên file</param>
        /// <returns>File Excel</returns>
        [HttpGet("Download/{fileName}")]
        [Authorize]
        public async Task<IActionResult> DownloadFile(string fileName)
        {
            try
            {
                // Tìm file trong thư mục exports/orders
                var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "exports", "orders", fileName);

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

                var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
                var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

                return File(fileBytes, contentType, fileName);
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Lỗi khi download file: {ex.Message}");
            }
        }



        /// <summary>
        /// Chuẩn bị dữ liệu bộ lọc danh sách đơn hàng
        /// </summary>
        /// <returns>Các danh sách option cho bộ lọc</returns>
        [HttpPost("PrepareOrderListFilter")]
        [Authorize(Roles = "Order.Search")]
        public async Task<IActionResult> PrepareOrderListFilter([FromBody] Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderListFilter filter)
        {
            var result = await _orderService.PrepareOrderListFilterAsync(filter);
            return Ok(result);
        }
    }
}
