using Marco.Pms.Model.Dtos.Expenses;
using Marco.Pms.Services.Service.ServiceInterfaces;
using MarcoBMS.Services.Helpers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;


namespace Marco.Pms.Services.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class ExpenseController : ControllerBase
    {
        private readonly UserHelper _userHelper;
        private readonly IExpensesService _expensesService;
        private readonly ISignalRService _signalR;
        private readonly Guid tenantId;
        public ExpenseController(
            UserHelper userHelper,
            IExpensesService expensesService,
            ISignalRService signalR
            )
        {
            _userHelper = userHelper;
            _expensesService = expensesService;
            _signalR = signalR;
            tenantId = userHelper.GetTenantId();
        }

        #region =================================================================== Expense Functions ===================================================================

        /// <summary>
        /// Retrieves a paginated list of expenses based on user permissions and optional filters.
        /// </summary>
        /// <param name="filter">A URL-encoded JSON string containing filter criteria. See <see cref="ExpensesFilter"/>.</param>
        /// <param name="pageSize">The number of records to return per page.</param>
        /// <param name="pageNumber">The page number to retrieve.</param>
        /// <returns>A paginated list of expenses.</returns>

        [HttpGet("list")]
        public async Task<IActionResult> GetExpensesList([FromQuery] string? searchString, [FromQuery] string? filter, [FromQuery] int pageSize = 20, [FromQuery] int pageNumber = 1)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetExpensesListAsync(loggedInEmployee, tenantId, searchString, filter, pageSize, pageNumber);
            return StatusCode(response.StatusCode, response);
        }

        [HttpGet("details/{id?}")]
        public async Task<IActionResult> GetExpenseDetails(Guid? id, [FromQuery] string? expenseUId)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetExpenseDetailsAsync(id, expenseUId, loggedInEmployee, tenantId);
            return StatusCode(response.StatusCode, response);
        }

        [HttpGet("suppler-name")]
        public async Task<IActionResult> GetSupplerNameList()
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetSupplerNameListAsync(loggedInEmployee, tenantId);
            return StatusCode(response.StatusCode, response);
        }

        [HttpGet("filter")]
        public async Task<IActionResult> GetFilterObject()
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetFilterObjectAsync(loggedInEmployee, tenantId);
            return StatusCode(response.StatusCode, response);
        }

        [HttpPost("create")]
        public async Task<IActionResult> CreateExpense([FromBody] CreateExpensesDto model)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.CreateExpenseAsync(model, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Expanse", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);
        }

        [HttpPost("action")]
        public async Task<IActionResult> ChangeStatus([FromBody] ExpenseRecordDto model)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.ChangeStatusAsync(model, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Expanse", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);
        }

        [HttpPut("edit/{id}")]
        public async Task<IActionResult> UpdateExpanse(Guid id, [FromBody] UpdateExpensesDto model)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.UpdateExpanseAsync(id, model, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Expanse", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);
        }

        [HttpDelete("delete/{id}")]
        public async Task<IActionResult> DeleteExpanse(Guid id)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.DeleteExpanseAsync(id, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Expanse", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);
        }

        #endregion

        #region =================================================================== Payment Request Functions ===================================================================

        [HttpGet("get/payment-requests/list")]
        public async Task<IActionResult> GetPaymentRequestList([FromQuery] string? searchString, [FromQuery] string? filter, [FromQuery] bool isActive = true, [FromQuery] int pageSize = 20, [FromQuery] int pageNumber = 1)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetPaymentRequestListAsync(searchString, filter, isActive, pageSize, pageNumber, loggedInEmployee, tenantId);
            return StatusCode(response.StatusCode, response);
        }

        [HttpGet("get/payment-request/details/{id?}")]
        public async Task<IActionResult> GetPaymentRequestDetails(Guid? id, [FromQuery] string? paymentRequestUId)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetPaymentRequestDetailsAsync(id, paymentRequestUId, loggedInEmployee, tenantId);
            return StatusCode(response.StatusCode, response);
        }

        [HttpGet("payment-request/payee")]
        public async Task<IActionResult> GetPayeeNameList()
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetPayeeNameListAsync(loggedInEmployee, tenantId);
            return StatusCode(response.StatusCode, response);
        }

        [HttpGet("payment-request/filter")]
        public async Task<IActionResult> GetPaymentRequestFilterObject()
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetPaymentRequestFilterObjectAsync(loggedInEmployee, tenantId);
            return StatusCode(response.StatusCode, response);
        }

        [HttpPost("payment-request/create")]
        public async Task<IActionResult> CreatePaymentRequest([FromBody] PaymentRequestDto model)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.CreatePaymentRequestAsync(model, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Payment_Request", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);
        }

        [HttpPost("payment-request/action")]
        public async Task<IActionResult> ChangePaymentRequestStatus([FromBody] PaymentRequestRecordDto model)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.ChangePaymentRequestStatusAsync(model, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Payment_Request", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);
        }

        [HttpPut("payment-request/edit/{id}")]
        public async Task<IActionResult> EditPaymentRequest(Guid id, [FromBody] PaymentRequestDto model)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.EditPaymentRequestAsync(id, model, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Payment_Request", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);
        }

        [HttpDelete("payment-request/delete/{id}")]
        public async Task<IActionResult> DeletePaymentRequestAsync(Guid id)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.DeleteExpanseAsync(id, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Payment_Request", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);
        }

        #endregion

        #region =================================================================== Recurring Payment Functions ===================================================================

        [HttpGet("get/recurring-payment/list")]
        public async Task<IActionResult> GetRecurringPaymentList([FromQuery] string? searchString, [FromQuery] string? filter, [FromQuery] bool isActive = true, [FromQuery] int pageSize = 20, [FromQuery] int pageNumber = 1)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetRecurringPaymentListAsync(searchString, filter, isActive, pageSize, pageNumber, loggedInEmployee, tenantId);
            return StatusCode(response.StatusCode, response);
        }

        [HttpGet("get/recurring-payment/details/{id?}")]
        public async Task<IActionResult> GetRecurringPaymentDetailsAsync(Guid? id, [FromQuery] string? recurringPaymentUId)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetRecurringPaymentDetailsAsync(id, recurringPaymentUId, loggedInEmployee, tenantId);
            return StatusCode(response.StatusCode, response);
        }

        [HttpPost("recurring-payment/create")]
        public async Task<IActionResult> CreateRecurringPayment([FromBody] CreateRecurringTemplateDto model)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.CreateRecurringPaymentAsync(model, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Recurring_Payment", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);

        }

        [HttpPost("recurring-payment/convert/payment-request")]
        public async Task<IActionResult> PaymentRequestConversion(PaymentRequestConversionDto model)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.PaymentRequestConversionAsync(model.RecurringTemplateIds, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Payment_Request", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);
        }

        [HttpPut("recurring-payment/edit/{id}")]
        public async Task<IActionResult> EditRecurringPaymentAsync(Guid id, [FromBody] UpdateRecurringTemplateDto model)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.EditRecurringPaymentAsync(id, model, loggedInEmployee, tenantId);
            if (response.Success)
            {
                var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Payment_Request", Response = response.Data };
                await _signalR.SendNotificationAsync(notification);
            }
            return StatusCode(response.StatusCode, response);

        }
        #endregion

        #region =================================================================== Advance Payment Functions ===================================================================

        [HttpGet("get/transactions/{employeeId}")]
        public async Task<IActionResult> GetAdvancePaymentTransaction(Guid employeeId)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetAdvancePaymentTransactionAsync(employeeId, loggedInEmployee, tenantId);

            return StatusCode(response.StatusCode, response);

        }

        [HttpGet("get/advance-payment/employee/list")]
        public async Task<IActionResult> GetAdavncePaymentEmployeeList([FromQuery] string? searchString)
        {
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var response = await _expensesService.GetAdvancePaymentEmployeeListAsync(searchString, loggedInEmployee, tenantId);

            return StatusCode(response.StatusCode, response);
        }
        #endregion
    }
}
