using Microsoft.AspNetCore.Mvc;
using QRRapidoApp.Data;
using QRRapidoApp.Models;
using MongoDB.Driver;

namespace QRRapidoApp.Controllers
{
    /// <summary>
    /// Admin controller - ONLY accessible from localhost for security
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class AdminController : ControllerBase
    {
        private readonly MongoDbContext _context;
        private readonly ILogger<AdminController> _logger;

        public AdminController(MongoDbContext context, ILogger<AdminController> logger)
        {
            _context = context;
            _logger = logger;
        }

        /// <summary>
        /// Seed/Update MongoDB Plans collection
        /// Only accessible from localhost (127.0.0.1 or ::1)
        /// </summary>
        [HttpPost("SeedPlans")]
        public async Task<IActionResult> SeedPlans([FromBody] List<Plan> plans)
        {
            // SECURITY: Only allow from localhost
            var remoteIp = HttpContext.Connection.RemoteIpAddress;
            var isLocalhost = remoteIp != null &&
                             (remoteIp.ToString() == "127.0.0.1" ||
                              remoteIp.ToString() == "::1" ||
                              remoteIp.ToString() == "localhost");

            if (!isLocalhost)
            {
                _logger.LogWarning($"Unauthorized admin access attempt from {remoteIp}");
                return Forbid("This endpoint is only accessible from localhost");
            }

            try
            {
                _logger.LogInformation($"SeedPlans called from localhost - Upserting {plans.Count} plans");

                foreach (var plan in plans)
                {
                    // Upsert based on interval (month/year)
                    var filter = Builders<Plan>.Filter.Eq(p => p.Interval, plan.Interval);
                    var options = new ReplaceOptions { IsUpsert = true };

                    await _context.Plans.ReplaceOneAsync(filter, plan, options);
                    _logger.LogInformation($"Upserted plan: {plan.Interval}");
                }

                return Ok(new {
                    success = true,
                    message = $"{plans.Count} plans seeded successfully",
                    plans = plans.Select(p => new {
                        interval = p.Interval,
                        priceIds = p.PricesByCountry.ToDictionary(
                            kvp => kvp.Key,
                            kvp => kvp.Value.StripePriceId
                        )
                    })
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error seeding plans");
                return StatusCode(500, new { success = false, error = ex.Message });
            }
        }

        /// <summary>
        /// Get all plans from MongoDB
        /// Only accessible from localhost
        /// </summary>
        [HttpGet("Plans")]
        public async Task<IActionResult> GetPlans()
        {
            // SECURITY: Only allow from localhost
            var remoteIp = HttpContext.Connection.RemoteIpAddress;
            var isLocalhost = remoteIp != null &&
                             (remoteIp.ToString() == "127.0.0.1" ||
                              remoteIp.ToString() == "::1" ||
                              remoteIp.ToString() == "localhost");

            if (!isLocalhost)
            {
                _logger.LogWarning($"Unauthorized admin access attempt from {remoteIp}");
                return Forbid("This endpoint is only accessible from localhost");
            }

            try
            {
                var plans = await _context.Plans.Find(_ => true).ToListAsync();
                return Ok(new { success = true, count = plans.Count, plans });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving plans");
                return StatusCode(500, new { success = false, error = ex.Message });
            }
        }

        /// <summary>
        /// Delete all plans from MongoDB
        /// Only accessible from localhost
        /// </summary>
        [HttpDelete("Plans")]
        public async Task<IActionResult> DeleteAllPlans()
        {
            // SECURITY: Only allow from localhost
            var remoteIp = HttpContext.Connection.RemoteIpAddress;
            var isLocalhost = remoteIp != null &&
                             (remoteIp.ToString() == "127.0.0.1" ||
                              remoteIp.ToString() == "::1" ||
                              remoteIp.ToString() == "localhost");

            if (!isLocalhost)
            {
                _logger.LogWarning($"Unauthorized admin access attempt from {remoteIp}");
                return Forbid("This endpoint is only accessible from localhost");
            }

            try
            {
                var result = await _context.Plans.DeleteManyAsync(_ => true);
                _logger.LogInformation($"Deleted {result.DeletedCount} plans");
                return Ok(new { success = true, deletedCount = result.DeletedCount });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error deleting plans");
                return StatusCode(500, new { success = false, error = ex.Message });
            }
        }
    }
}
