using AutoMapper; using Marco.Pms.DataAccess.Data; using Marco.Pms.Helpers.Utility; using Marco.Pms.Model.Dtos.Util; using Marco.Pms.Model.Mapper; using Marco.Pms.Model.Master; using Marco.Pms.Model.TenantModels; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels.Tenant; using MarcoBMS.Services.Service; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace Marco.Pms.Services.Controllers { [Route("api/[controller]")] [ApiController] public class MarketController : ControllerBase { private readonly IDbContextFactory _dbContextFactory; private readonly FeatureDetailsHelper _featureDetailsHelper; private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IEmailSender _emailSender; private readonly IConfiguration _configuration; public MarketController(IDbContextFactory dbContextFactory, IServiceScopeFactory serviceScopeFactory, IEmailSender emailSender, IConfiguration configuration, FeatureDetailsHelper featureDetailsHelper) { _dbContextFactory = dbContextFactory ?? throw new ArgumentNullException(nameof(dbContextFactory)); _serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory)); _emailSender = emailSender ?? throw new ArgumentNullException(nameof(emailSender)); _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); _featureDetailsHelper = featureDetailsHelper ?? throw new ArgumentNullException(nameof(featureDetailsHelper)); } [HttpGet] [Route("industries")] public async Task GetIndustries() { await using var _context = await _dbContextFactory.CreateDbContextAsync(); var industries = await _context.Industries.ToListAsync(); return Ok(ApiResponse.SuccessResponse(industries, "Success.", 200)); } [HttpPost("enquire")] public async Task RequestDemo([FromBody] InquiryDto inquiryDto) { await using var _context = await _dbContextFactory.CreateDbContextAsync(); Inquiries inquiry = inquiryDto.ToInquiriesFromInquiriesDto(); _context.Inquiries.Add(inquiry); await _context.SaveChangesAsync(); Industry industry = await _context.Industries.FirstOrDefaultAsync(i => i.Id == inquiryDto.IndustryId) ?? new Industry(); if (industry != null && industry.Name != null) { InquiryEmailObject inquiryEmailObject = inquiryDto.ToInquiryEmailObjectFromInquiriesDto(industry.Name); string emails = _configuration["MailingList:RequestDemoReceivers"] ?? ""; List result = emails .Split(';', StringSplitOptions.RemoveEmptyEntries) .Select(item => item.Trim()) .ToList(); await _emailSender.SendRequestDemoEmail(result, inquiryEmailObject); return Ok(ApiResponse.SuccessResponse(new { }, "Email sent.", 200)); } return NotFound(ApiResponse.ErrorResponse("Industry not found.", "Industry not found.", 404)); } [HttpGet("list/subscription-plan")] public async Task GetSubscriptionPlanList([FromQuery] PLAN_FREQUENCY? frequency) { using var scope = _serviceScopeFactory.CreateScope(); var _logger = scope.ServiceProvider.GetRequiredService(); var _mapper = scope.ServiceProvider.GetRequiredService(); _logger.LogInfo("GetSubscriptionPlanList called with frequency: {Frequency}", frequency ?? PLAN_FREQUENCY.MONTHLY); // Initialize the list to store subscription plan view models List detailsVM = new List(); try { // Create DbContext await using var _context = await _dbContextFactory.CreateDbContextAsync(); // Load subscription plans with optional frequency filtering IQueryable query = _context.SubscriptionPlanDetails.Include(sp => sp.Plan).Include(sp => sp.Currency); if (frequency.HasValue) { query = query.Where(sp => sp.Frequency == frequency.Value); _logger.LogInfo("Filtering subscription plans by frequency: {Frequency}", frequency); } else { _logger.LogInfo("Fetching all subscription plans without frequency filter"); } var subscriptionPlans = await query.ToListAsync(); // Map and fetch feature details for each subscription plan foreach (var subscriptionPlan in subscriptionPlans) { var response = _mapper.Map(subscriptionPlan); try { response.Features = await _featureDetailsHelper.GetFeatureDetails(subscriptionPlan.FeaturesId); } catch (Exception exFeature) { _logger.LogError(exFeature, "Failed to fetch features for FeaturesId: {FeaturesId}", subscriptionPlan.FeaturesId); response.Features = null; // or set to a default/fallback value } detailsVM.Add(response); } _logger.LogInfo("Successfully fetched {Count} subscription plans", detailsVM.Count); return Ok(ApiResponse.SuccessResponse(detailsVM, "List of plans fetched successfully", 200)); } catch (Exception ex) { _logger.LogError(ex, "Error occurred while fetching subscription plans"); return StatusCode(500, ApiResponse.ErrorResponse("An error occurred while fetching subscription plans.")); } } } }