using Asp.Versioning;
using DocumentFormat.OpenXml.Office2010.ExcelAc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OnlineSalesAutoCrop.CoreAPI;
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace OnlineSalesAutoCrop.CoreAPI.Controllers
{
    /// <summary>
	/// 
	/// </summary>
	/// <remarks>
	/// 
	/// </remarks>
	/// <param name="service"></param>
	/// <param name="appSettings"></param>
	/// <param name="cache"></param>
	/// <param name="logger"></param>
	[Authorize]
    [ApiController]
    [ApiVersion("1.0")]
    [ValidateAntiForgeryToken]
    [Route("api/mobile/v{version:apiVersion}/masterdata")]
    public class MobileMasterDataController(IMobileMasterDataService service, IOptions<AppSettings> appSettings, IEaseCache cache, ILogger<MobileMasterDataController> logger) : ControllerBase
    {
        private readonly ILogger _logger = logger;
        private readonly IEaseCache _cache = cache;
        private readonly IMobileMasterDataService _service = service;
        private readonly AppSettings _appSettings = appSettings?.Value;
        private readonly DateTimeOffset _options = Helper.CreateEaseCacheOptions();


        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return MarketHierarchies List</response>
        [HttpGet("MarketHierarchies")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MarketHeirarchyByEmpResponse))]
        public async Task<IActionResult> EmployeeMarketHierarchies([FromQuery] GetMarketHeirarchyByEmpRequest request)
        {
            MarketHeirarchyByEmpResponse response = new();
            try
            {
                response = await _service.GetMarketHeirarchiesByEmpAsync(request);
                return Ok(MobileResponseBase<MarketHeirarchyByEmpResponse>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on MarketHeirarchys endpoint with employee request - {request?.EmployeeNumber}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }

        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Brands List</response>
        [HttpGet("Brands")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MarketHeirarchyByEmpResponse))]
        public async Task<IActionResult> Brands([FromQuery] GetBrandsRequest request)
        {
            PagedResult<GetBrandResponse> response = new();
            try
            {
                response = await _service.GetBrandsAsync(request);
                return Ok(MobileResponseBase<PagedResult<GetBrandResponse>>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on brands endpoint with employee request - {request?.BrandCode}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }


        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Material List</response>
        [HttpGet("Materials")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetMaterialResponse))]
        public async Task<IActionResult> Materials([FromQuery] GetMaterialsRequest request)
        {
            PagedResult<GetMaterialResponse> response = new();
            try
            {
                response = await _service.GetMaterialsAsync(request);
                return Ok(MobileResponseBase<PagedResult<GetMaterialResponse>>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on Materials endpoint with employee request - {request?.BrandCode} -{request?.MaterialCode}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }

        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Material List</response>
        [HttpGet("MaterialsStock")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetMaterialStockReponse))]
        public async Task<IActionResult> GetMaterialsStock([FromQuery] GetMaterialStockRequest request)
        {
            PagedResult<GetMaterialStockReponse> response = new();
            try
            {
                response = await _service.GetMaterialsStockAsync(request);
                return Ok(MobileResponseBase<PagedResult<GetMaterialStockReponse>>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on MaterialsStock endpoint with plant request - {request?.PlantCode} ";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }

        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Material List</response>
        [HttpGet("CustomerWiseMaterialPrices")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetMaterialPriceResponse))]
        public async Task<IActionResult> GetCustomerWiseMaterialPrices([FromQuery] GetMaterialPriceRequest request)
        {
            PagedResult<GetMaterialPriceResponse> response = new();
            try
            {
                response = await _service.GetMaterialPricesAsync(request);
                return Ok(MobileResponseBase<PagedResult<GetMaterialPriceResponse>>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on Materials prices endpoint with employee request - {request?.MaterialCode} -{request?.EmployeeNumber}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }

        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Material List</response>
        [HttpGet("Customers")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetCustomerResponse))]
        public async Task<IActionResult> Customers([FromQuery] GetCustomersRequest request)
        {
            PagedResult<GetCustomerResponse> response = new();
            try
            {
                response = await _service.GetCustomersAsync(request);
                return Ok(MobileResponseBase<PagedResult<GetCustomerResponse>>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on Materials endpoint with employee request - {request?.TeritoryCode} -{request?.CustomerCode}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }


        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Attendance List</response>
        [HttpGet("Attendance")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetAttendanceByEmpResponse))]
        public async Task<IActionResult> GetAttendance([FromQuery] GetAttendanceByEmpRequest request)
        {
            GetAttendanceByEmpResponse response = new();
            try
            {
                response = await _service.GetAttendanceByEmpAsync(request);
                return Ok(MobileResponseBase<GetAttendanceByEmpResponse>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on Get Attendance endpoint with employee request - {request?.EmployeeNumber} -{request?.AttendanceDate}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }


        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Attendance List</response>
        [HttpPost("SaveAttendance")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetAttendanceByEmpResponse))]
        public async Task<IActionResult> UpsertAttendance([FromBody] UpsertAttendanceByEmpRequest request)
        {
            GetAttendanceByEmpResponse response = new();
            try
            {
                response = await _service.UpsertAttendanceByEmpAsync(request);
                return Ok(MobileResponseBase<GetAttendanceByEmpResponse>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on Save Attendance endpoint with employee request - {request?.EmployeeNumber}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }


        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Attendance List</response>
        [HttpGet("Discounts")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetDiscountResponse))]
        public async Task<IActionResult> GetDiscounts([FromQuery] GetDiscountRequest request)
        {
            PagedResult<GetDiscountResponse> response = new();
            try
            {
                response = await _service.GetDiscountAsync(request);
                return Ok(MobileResponseBase<PagedResult<GetDiscountResponse>>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on Get Discounts endpoint with request - {request?.EmployeeNumber} -{request?.DiscountCode}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }


        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Attendance List</response>
        [HttpGet("DiscountMaterials")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetDiscountMaterialResponse))]
        public async Task<IActionResult> GetDiscountMaterials([FromQuery] GetDiscountMaterialRequest request)
        {
            PagedResult<GetDiscountMaterialResponse> response = new();
            try
            {
                response = await _service.GetDiscountMaterialsAsync(request);
                return Ok(MobileResponseBase<PagedResult<GetDiscountMaterialResponse>>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on Get DiscountMaterials endpoint with  request - {request?.MaterialCode} -{request?.DiscountCode}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }


        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Attendance List</response>
        [HttpGet("FOCs")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetFOCResponse))]
        public async Task<IActionResult> GetMaterialFOCs([FromQuery] GetFOCRequest request)
        {
            PagedResult<GetFOCResponse> response = new();
            try
            {
                response = await _service.GetFOCsAsync(request);
                return Ok(MobileResponseBase<PagedResult<GetFOCResponse>>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on Get MaterialFOCs endpoint with request - {request?.EmployeeNumber} -{request?.FOCCode}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }


        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Attendance List</response>
        [HttpGet("FOCsMaterials")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetFOCMaterialResponse))]
        public async Task<IActionResult> GetFOCsMaterials([FromQuery] GetFOCMaterialRequest request)
        {
            PagedResult<GetFOCMaterialResponse> response = new();
            try
            {
                response = await _service.GetFOCMaterialsAsync(request);
                return Ok(MobileResponseBase<PagedResult<GetFOCMaterialResponse>>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on Get FOCsMaterials endpoint with  request - {request?.MaterialCode} -{request?.FOCCode}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }

        /// <summary>
        /// Login using your credential data retrieve from SqlServer
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="request"></param>
        /// <response code="200">If login successful Return Attendance List</response>
        [HttpGet("PaymentTerms")]
        [IgnoreAntiforgeryToken]
        [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetPaymentTermResponse))]
        public async Task<IActionResult> GetPaymentTerms([FromQuery] GetPaymentTermRequest request)
        {
            PagedResult<GetPaymentTermResponse> response = new();
            try
            {
                response = await _service.GetPaymentTermsAsync(request);
                return Ok(MobileResponseBase<PagedResult<GetPaymentTermResponse>>.Success(response));
            }
            catch (Exception ex)
            {
                string msg = $"Exception occur on Get PaymentTerms endpoint with  request - {request?.SalesOrgCode} -{request?.PaymentTermCode}";
                _logger.LogError(exception: ex, message: msg);
                return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
            }
        }
    }
}