using Lada.Framework.Data.Enums;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Crm;
using Ladaer.BackEnd.Infrastructures.Services.Crm;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Ladaer.BackEnd.Controllers.Crm
{
    /// <summary>
    /// Controller d? x? lư các ho?t d?ng liên quan d?n d?a ch? khách hàng.
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class CustomerAddressController : ControllerBase
    {
        private readonly ICustomerAddressService _customerAddressService;

        /// <summary>
        /// Kh?i t?o m?t instance m?i c?a l?p <see cref="CustomerAddressController"/>.
        /// </summary>
        /// <param name="customerAddressService">D?ch v? x? lư d?a ch? khách hàng.</param>
        public CustomerAddressController(ICustomerAddressService customerAddressService)
        {
            _customerAddressService = customerAddressService;
        }

        /// <summary>
        /// T́m ki?m các d?a ch? khách hàng 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 = "CustomerAddress.Search")]
        public async Task<IActionResult> Search([FromBody] SmartTableParam param)
        {
            if (param.Search.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;
                if (search.CustomerId != null)
                {
                    int customerId = search.CustomerId;
                    if (customerId <= 0)
                    {
                        search.CustomerId = 0;
                    }
                }
                else
                {
                    search.CustomerId = 0;
                }
                param.Search.PredicateObject = search;
            }
            var customers = await _customerAddressService.Search(param);
            return Ok(customers);
        }

        #region SourceAddress

        /// <summary>
        /// T́m ki?m các d?a ch? ngu?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("SearchSource")]
        [Authorize(Roles = "CustomerAddress.SearchSource")]
        public async Task<IActionResult> SearchSource([FromBody] SmartTableParam param)
        {
            if (param.Search.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;
                if (search.CustomerId != null)
                {
                    int customerId = search.CustomerId;
                    if (customerId <= 0)
                    {
                        search.CustomerId = 0;
                    }
                }
                else
                {
                    search.CustomerId = 0;
                }
                search.AddressType = AddressType.Source;
                param.Search.PredicateObject = search;
            }
            var customers = await _customerAddressService.Search(param);
            return Ok(customers);
        }

        #endregion

        #region DestAddress

        /// <summary>
        /// T́m ki?m các d?a ch? dích 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("SearchDest")]
        [Authorize(Roles = "CustomerAddress.SearchDest")]
        public async Task<IActionResult> SearchDest([FromBody] SmartTableParam param)
        {
            if (param.Search.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;
                if (search.CustomerId != null)
                {
                    int customerId = search.CustomerId;
                    if (customerId <= 0)
                    {
                        search.CustomerId = 0;
                    }
                }
                else
                {
                    search.CustomerId = 0;
                }
                search.AddressType = AddressType.Dest;
                param.Search.PredicateObject = search;
            }
            var customers = await _customerAddressService.Search(param);
            return Ok(customers);
        }

        #region CRUD

        /// <summary>
        /// T?o d?a ch? dích cho khách hàng.
        /// </summary>
        /// <param name="customerAddressModel">Model ch?a thông tin d?a ch? khách hàng.</param>
        /// <returns>K?t qu? c?a ho?t d?ng t?o d?a ch? dích.</returns>
        [HttpPost("CreateDestAddress")]
        [Authorize(Roles = "CustomerAddress.CreateDestAddress")]
        public async Task<IActionResult> CreateDestAddress([FromBody] CustomerAddressModel customerAddressModel)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            customerAddressModel.AddressType = AddressType.Dest;
            var result = await CreateOrUpdate(customerAddressModel);
            return Ok(result);
        }

        #endregion
        #endregion

        /// <summary>
        /// T?o ho?c c?p nh?t thông tin d?a ch? khách hàng.
        /// </summary>
        /// <param name="customerAddressModel">Model ch?a thông tin d?a ch? khách hàng.</param>
        /// <returns>K?t qu? c?a ho?t d?ng t?o ho?c c?p nh?t.</returns>
        [HttpPost("CreateOrUpdate")]
        [Authorize(Roles = "CustomerAddress.CreateOrUpdate")]
        public async Task<IActionResult> CreateOrUpdate([FromBody] CustomerAddressModel customerAddressModel)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            if (customerAddressModel.CustomerId <= 0)
            {
                return BadRequest("Không xác d?nh du?c khách hàng");
            }
            if (customerAddressModel.AddressType <= 0)
            {
                return BadRequest("Không xác d?nh du?c lo?i d?a ch?");
            }
            var currentUser = User.GetCurrentUser();
            customerAddressModel.UpdatedBy = currentUser.UserId;
            customerAddressModel.UpdatedByUserName = currentUser.UserName;
            if (customerAddressModel.UpdatedBy <= 0 || string.IsNullOrEmpty(customerAddressModel.UpdatedByUserName))
            {
                return BadRequest("Không xác d?nh du?c ngu?i dùng");
            }
            var result = await _customerAddressService.CreateOrUpdate(customerAddressModel);
            return Ok(result);
        }

        /// <summary>
        /// L?y thông tin chi ti?t c?a m?t d?a ch? khách hàng d?a trên ID.
        /// </summary>
        /// <param name="id">ID c?a d?a ch? khách hàng.</param>
        /// <returns>Thông tin chi ti?t c?a d?a ch? khách hàng.</returns>
        [HttpGet("GetById")]
        [Authorize(Roles = "CustomerAddress.GetById")]
        public async Task<IActionResult> GetById(int id)
        {
            var result = await _customerAddressService.GetById(id);
            return Ok(result);
        }

        /// <summary>
        /// Xóa m?t d?a ch? khách hàng d?a trên ID.
        /// </summary>
        /// <param name="id">ID c?a d?a ch? khách hàng.</param>
        /// <returns>K?t qu? c?a ho?t d?ng xóa.</returns>
        [HttpDelete("Delete")]
        [Authorize(Roles = "CustomerAddress.Delete")]
        public async Task<IActionResult> Delete(int id)
        {
            var currentUser = User.GetCurrentUser();
            if (currentUser == null)
            {
                return BadRequest("Không xác d?nh du?c ngu?i dùng");
            }
            var result = await _customerAddressService.Delete(id, currentUser);
            return Ok(result);
        }

        #region Utilities

        /// <summary>
        /// G?i ư d?a ch? khách hàng d?a trên t? khóa, ID khách hàng và lo?i d?a ch?.
        /// </summary>
        /// <param name="keyword">T? khóa t́m ki?m.</param>
        /// <param name="customerId">ID c?a khách hàng.</param>
        /// <param name="type">Lo?i d?a ch?.</param>
        /// <returns>Danh sách d?a ch? phù h?p.</returns>
        [HttpGet("Suggest")]
        [Authorize(Roles = "CustomerAddress.Suggest")]
        public async Task<IActionResult> Suggest(string? keyword, int customerId, int type)
        {
            var customers = await _customerAddressService.Suggest(keyword, customerId, (AddressType)type);
            return Ok(customers);
        }

        #endregion
    }
}
