using Lada.Framework.Data.Enums;
using Lada.Framework.DTO;
using Lada.Framework.DTO.Models;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.AppSettings;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Finances;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Export;
using Ladaer.BackEnd.Infrastructures.Services.Finances;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;

namespace Ladaer.BackEnd.Controllers.Finance
{
    /// <summary>
    /// Controller d? x? lư các ho?t d?ng liên quan d?n giá c?.
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class PriceController : ControllerBase
    {
        private readonly IPriceService _priceService;
        private readonly IBackFeeService _backFeeService;
        private readonly IWebHostEnvironment _hostEnvironment;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly string _mapApiKey;

        /// <summary>
        /// Kh?i t?o m?t instance m?i c?a l?p <see cref="PriceController"/>.
        /// </summary>
        /// <param name="options">Tùy ch?n c?u h́nh ?ng d?ng.</param>
        /// <param name="priceService">D?ch v? x? lư giá c?.</param>
        /// <param name="backFeeService">D?ch v? x? lư phí tr? l?i.</param>
        /// <param name="hostEnvironment">Môi tru?ng luu tr? web.</param>
        /// <param name="httpContextAccessor">Truy c?p ng? c?nh HTTP.</param>
        public PriceController(IOptions<AppSetting> options, IPriceService priceService, IBackFeeService backFeeService,
            IWebHostEnvironment hostEnvironment, IHttpContextAccessor httpContextAccessor)
        {
            _priceService = priceService;
            _hostEnvironment = hostEnvironment;
            _httpContextAccessor = httpContextAccessor;
            _backFeeService = backFeeService;
            _mapApiKey = options.Value.GoogleMapsApi.ApiKey;
        }

        /// <summary>
        /// L?y danh sách giá m?c d?nh.
        /// </summary>
        /// <param name="priceType">Lo?i giá.</param>
        /// <returns>Danh sách giá m?c d?nh.</returns>
        [HttpGet("GetDefaultPriceList")]
        [Authorize(Roles = "Price.GetDefaultPriceList")]
        public async Task<IActionResult> GetDefaultPriceList(PriceType priceType)
        {
            var result = await _priceService.GetDefaultPriceList(priceType);
            return Ok(result);
        }

        /// <summary>
        /// C?p nh?t danh sách giá m?c d?nh.
        /// </summary>
        /// <param name="model">Model ch?a thông tin danh sách giá.</param>
        /// <returns>K?t qu? c?a ho?t d?ng c?p nh?t danh sách giá.</returns>
        [HttpPut("UpdateDefaultPriceList")]
        [Authorize(Roles = "Price.UpdateDefaultPriceList")]
        public async Task<IActionResult> UpdateDefaultPriceList(PriceListModel model)
        {
            var currentUser = User.GetCurrentUser();
            model.UpdatedBy = currentUser.UserId;
            model.UpdatedByUserName = currentUser.UserName;
            var result = new BaseResult();
            if (model.UpdatedBy <= 0 || string.IsNullOrEmpty(model.UpdatedByUserName))
            {
                result.Result = Result.Failed;
                result.Message = "Không xác d?nh du?c ngu?i dùng";
            }
            else
            {
                result = await _priceService.UpdateDefaultPriceList(model);
            }

            return Ok(result);
        }

        /// <summary>
        /// Xu?t danh sách giá m?c d?nh.
        /// </summary>
        /// <returns>K?t qu? c?a ho?t d?ng xu?t danh sách giá.</returns>
        [HttpGet("ExportDefaultPriceList")]
        [Authorize(Roles = "Price.ExportDefaultPriceList")]
        public async Task<IActionResult> ExportDefaultPriceList()
        {
            var filePath = InitFilePath();
            var result = new ExportResult();
            if (!string.IsNullOrEmpty(filePath))
            {
                result = await _priceService.ExportDefaultPriceList(filePath);
                if (!string.IsNullOrEmpty(result.Url))
                {
                    result.Url = ConvertToUrl(result.Url);
                }
            }
            else
            {
                result.Result = Result.Failed;
                result.Message = "Không l?y du?c du?ng d?n";
            }

            return Ok(result);
        }

        /// <summary>
        /// Ki?m tra phí.
        /// </summary>
        /// <param name="model">Model ch?a thông tin ki?m tra phí.</param>
        /// <returns>K?t qu? c?a ho?t d?ng ki?m tra phí.</returns>
        [HttpPost("CheckFee")]
        [Authorize(Roles = "Price.CheckFee")]
        public async Task<IActionResult> CheckFee([FromBody] CheckFeeModel model)
        {
            // Đ?i tr?ng lu?ng t? kg sang gram
            var feeByWardModel = new FeeByWardModel
            {
                Weight = model.Weight * 1000,
                SourceWardId = model.SourceWardId,
                DestWardId = model.DestWardId,
                CustomerId = model.CustomerId
            };

            var result = await _backFeeService.GetFeeByWard(feeByWardModel, _mapApiKey);
            return Ok(result);
        }

        #region Utilities
        /// <summary>
        /// Kh?i t?o du?ng d?n t?p.
        /// </summary>
        /// <returns>Đu?ng d?n t?p.</returns>
        private string InitFilePath()
        {
            try
            {
                var result = "";
                var currentUser = User.GetCurrentUser();

                string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
                string webRootPath = _hostEnvironment.WebRootPath;
                string folderPath = Path.Combine(webRootPath, currentUser.UserName,
                                        DateTime.Now.Year.ToString(),
                                        DateTime.Now.Month.ToString(),
                                        DateTime.Now.Day.ToString());
                Directory.CreateDirectory(folderPath);

                result = Path.Combine(folderPath, $"{timestamp}.xlsx");
                return result;
            }
            catch (Exception ex)
            {
                return "";
            }
        }

        /// <summary>
        /// Chuy?n d?i du?ng d?n c?c b? thành URL.
        /// </summary>
        /// <param name="localUrl">Đu?ng d?n c?c b?.</param>
        /// <returns>URL.</returns>
        private string ConvertToUrl(string localUrl)
        {
            try
            {
                var result = localUrl;

                string webRootPath = _hostEnvironment.WebRootPath;
                var request = _httpContextAccessor.HttpContext.Request;

                string protocol = request.Scheme; // L?y giao th?c hi?n t?i (http ho?c https)
                string domain = request.Host.Value; // L?y tên mi?n hi?n t?i

                string domainWithProtocol = $"{protocol}://{domain}";

                result = result.Replace(webRootPath, domainWithProtocol);
                result = result.Replace("\\", "/");

                return result;
            }
            catch (Exception ex)
            {
                return "";
            }
        }
        #endregion
    }
}
