// EN: BFF Super Admin Controller — aggregates data from microservices for platform management.
// VI: BFF Super Admin Controller — tổng hợp dữ liệu từ microservices cho quản lý nền tảng.

using Microsoft.AspNetCore.Mvc;
using System.Text.Json;

namespace WebClientTpos.Server.Controllers;

/// <summary>
/// EN: BFF endpoints for Super Admin panel — proxies to IAM + Merchant services.
/// VI: BFF endpoints cho trang Super Admin — proxy đến IAM + Merchant services.
/// </summary>
[ApiController]
[Route("api/bff/superadmin")]
public class SuperAdminController : ControllerBase
{
    private readonly IHttpClientFactory _httpFactory;
    private readonly ILogger<SuperAdminController> _logger;
    private static readonly JsonSerializerOptions _json = new()
    {
        PropertyNameCaseInsensitive = true,
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    };

    public SuperAdminController(IHttpClientFactory httpFactory, ILogger<SuperAdminController> logger)
    {
        _httpFactory = httpFactory;
        _logger = logger;
    }

    // ═══════════════════════════════════════════════
    // ─── PLATFORM STATS (Dashboard) ───
    // ═══════════════════════════════════════════════

    /// <summary>
    /// EN: Get aggregated platform statistics from multiple services.
    /// VI: Lấy thống kê nền tảng tổng hợp từ nhiều services.
    /// </summary>
    [HttpGet("stats")]
    public async Task<IActionResult> GetPlatformStats()
    {
        try
        {
            var merchantClient = CreateAuthClient("MerchantService");
            var iamClient = CreateAuthClient("IamService");

            // EN: Fetch data from services in parallel
            // VI: Lấy dữ liệu từ services song song
            var merchantStatsTask = SafeGetJson(merchantClient, "/api/v1/admin/merchants/statistics");
            var usersTask = SafeGetJson(iamClient, "/api/v1/users?pageNumber=1&pageSize=1");

            await Task.WhenAll(merchantStatsTask, usersTask);

            var merchantStats = merchantStatsTask.Result;
            var usersData = usersTask.Result;

            // EN: Extract values from merchant statistics
            // VI: Trích xuất giá trị từ thống kê merchants
            int totalMerchants = 0, activeMerchants = 0, pendingMerchants = 0, suspendedMerchants = 0;
            int totalShops = 0, activeShops = 0;

            if (merchantStats != null)
            {
                var data = GetDataProperty(merchantStats.Value);
                totalMerchants = GetInt(data, "totalMerchants");
                activeMerchants = GetInt(data, "activeMerchants", GetInt(data, "active"));
                pendingMerchants = GetInt(data, "pendingMerchants", GetInt(data, "pending", GetInt(data, "pendingApproval")));
                suspendedMerchants = GetInt(data, "suspendedMerchants", GetInt(data, "suspended"));
                totalShops = GetInt(data, "totalShops");
                activeShops = GetInt(data, "activeShops");
            }

            // EN: Extract total users from pagination
            // VI: Trích xuất tổng users từ pagination
            int totalUsers = 0;
            if (usersData != null)
            {
                if (usersData.Value.TryGetProperty("pagination", out var pg) &&
                    pg.TryGetProperty("totalCount", out var tc))
                    totalUsers = tc.GetInt32();
            }

            return Ok(new
            {
                success = true,
                data = new
                {
                    totalMerchants,
                    activeMerchants,
                    pendingMerchants,
                    suspendedMerchants,
                    totalShops,
                    activeShops,
                    totalUsers,
                    newUsersToday = 0,
                    totalOrders = 0,
                    ordersToday = 0,
                    gmvTotal = 0m,
                    gmvToday = 0m
                }
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to fetch platform stats");
            return Ok(new
            {
                success = true,
                data = new
                {
                    totalMerchants = 0, activeMerchants = 0, pendingMerchants = 0, suspendedMerchants = 0,
                    totalShops = 0, activeShops = 0, totalUsers = 0, newUsersToday = 0,
                    totalOrders = 0, ordersToday = 0, gmvTotal = 0m, gmvToday = 0m
                }
            });
        }
    }

    // ═══════════════════════════════════════════════
    // ─── MERCHANTS ───
    // ═══════════════════════════════════════════════

    [HttpGet("merchants")]
    public async Task<IActionResult> GetMerchants(
        [FromQuery] int page = 1, [FromQuery] int pageSize = 20,
        [FromQuery] string? status = null, [FromQuery] string? search = null)
    {
        var client = CreateAuthClient("MerchantService");
        var url = $"/api/v1/admin/merchants?pageNumber={page}&pageSize={pageSize}";
        if (!string.IsNullOrEmpty(status)) url += $"&status={status}";
        if (!string.IsNullOrEmpty(search)) url += $"&search={Uri.EscapeDataString(search)}";

        return await ProxyGet(client, url);
    }

    [HttpGet("merchants/{id}")]
    public async Task<IActionResult> GetMerchantDetail(Guid id)
    {
        var client = CreateAuthClient("MerchantService");
        return await ProxyGet(client, $"/api/v1/admin/merchants/{id}");
    }

    [HttpPost("merchants/{id}/approve")]
    public async Task<IActionResult> ApproveMerchant(Guid id)
    {
        var client = CreateAuthClient("MerchantService");
        var result = await ProxyPost(client, $"/api/v1/admin/merchants/{id}/approve");
        _ = LogAuditAsync(21, "Merchant", id, "Approve merchant");
        return result;
    }

    [HttpPost("merchants/{id}/suspend")]
    public async Task<IActionResult> SuspendMerchant(Guid id, [FromBody] JsonElement body)
    {
        var client = CreateAuthClient("MerchantService");
        var result = await ProxyPostWithBody(client, $"/api/v1/admin/merchants/{id}/suspend", body);
        _ = LogAuditAsync(13, "Merchant", id, "Suspend merchant");
        return result;
    }

    [HttpPut("merchants/{id}/plan")]
    public async Task<IActionResult> UpdateMerchantPlan(Guid id, [FromBody] JsonElement body)
    {
        var client = CreateAuthClient("MerchantService");
        var result = await ProxyPut(client, $"/api/v1/admin/merchants/{id}/plan", body);
        _ = LogAuditAsync(31, "Merchant", id, $"Update merchant plan");
        return result;
    }

    [HttpPost("merchants/{id}/reactivate")]
    public async Task<IActionResult> ReactivateMerchant(Guid id)
    {
        var client = CreateAuthClient("MerchantService");
        var result = await ProxyPost(client, $"/api/v1/admin/merchants/{id}/reactivate");
        _ = LogAuditAsync(14, "Merchant", id, "Reactivate merchant");
        return result;
    }

    // ═══════════════════════════════════════════════
    // ─── SUBSCRIPTION PLANS (in-memory for MVP) ───
    // ═══════════════════════════════════════════════

    private static readonly List<object> _plans = new()
    {
        new { id = Guid.Parse("00000000-0000-0000-0000-000000000001"), name = "Starter", slug = "starter",
              description = "Gói miễn phí cho doanh nghiệp mới bắt đầu",
              priceMonthly = 0m, priceYearly = 0m, maxShops = 1, maxStaff = 5, maxProducts = 100,
              isActive = true, merchantCount = 0, sortOrder = 0 },
        new { id = Guid.Parse("00000000-0000-0000-0000-000000000002"), name = "Growth", slug = "growth",
              description = "Gói tăng trưởng cho doanh nghiệp đang mở rộng",
              priceMonthly = 299000m, priceYearly = 2990000m, maxShops = 3, maxStaff = 15, maxProducts = 500,
              isActive = true, merchantCount = 0, sortOrder = 1 },
        new { id = Guid.Parse("00000000-0000-0000-0000-000000000003"), name = "Pro", slug = "pro",
              description = "Gói chuyên nghiệp với đầy đủ tính năng",
              priceMonthly = 799000m, priceYearly = 7990000m, maxShops = 10, maxStaff = 50, maxProducts = 2000,
              isActive = true, merchantCount = 0, sortOrder = 2 },
        new { id = Guid.Parse("00000000-0000-0000-0000-000000000004"), name = "Enterprise", slug = "enterprise",
              description = "Gói doanh nghiệp lớn — tùy chỉnh theo nhu cầu",
              priceMonthly = 0m, priceYearly = 0m, maxShops = 999, maxStaff = 999, maxProducts = 99999,
              isActive = true, merchantCount = 0, sortOrder = 3 },
    };

    [HttpGet("plans")]
    public IActionResult GetPlans()
        => Ok(new { success = true, data = _plans });

    [HttpPost("plans")]
    public IActionResult CreatePlan([FromBody] JsonElement body)
        => Ok(new { success = true, data = body });

    [HttpPut("plans/{id}")]
    public IActionResult UpdatePlan(Guid id, [FromBody] JsonElement body)
        => Ok(new { success = true, data = body });

    // ═══════════════════════════════════════════════
    // ─── SYSTEM HEALTH ───
    // ═══════════════════════════════════════════════

    [HttpGet("system/health")]
    public async Task<IActionResult> GetSystemHealth()
    {
        var services = new[]
        {
            ("IamService", "IAM Service"),
            ("MerchantService", "Merchant Service"),
            ("CatalogService", "Catalog Service"),
            ("OrderService", "Order Service"),
            ("InventoryService", "Inventory Service"),
            ("WalletService", "Wallet Service"),
            ("MembershipService", "Membership Service"),
            ("PromotionService", "Promotion Service"),
            ("BookingService", "Booking Service"),
            ("FnbEngine", "F&B Engine"),
            ("StorageService", "Storage Service"),
        };

        var healthTasks = services.Select(async s =>
        {
            var (clientName, displayName) = s;
            try
            {
                var client = _httpFactory.CreateClient(clientName);
                var sw = System.Diagnostics.Stopwatch.StartNew();
                var response = await client.GetAsync("/health", new System.Threading.CancellationTokenSource(3000).Token);
                sw.Stop();
                return new
                {
                    name = displayName,
                    status = response.IsSuccessStatusCode ? "Healthy" : "Degraded",
                    responseTimeMs = (int)sw.ElapsedMilliseconds,
                    lastChecked = DateTime.UtcNow
                };
            }
            catch
            {
                return new
                {
                    name = displayName,
                    status = "Unhealthy",
                    responseTimeMs = -1,
                    lastChecked = DateTime.UtcNow
                };
            }
        });

        var results = await Task.WhenAll(healthTasks);
        return Ok(new { success = true, data = results });
    }

    // ═══════════════════════════════════════════════
    // ─── FEATURE FLAGS (in-memory for MVP) ───
    // ═══════════════════════════════════════════════

    private static readonly List<Dictionary<string, object>> _featureFlags = new()
    {
        new() { ["key"] = "ai_assistant", ["description"] = "AI Chat Assistant cho quản lý cửa hàng", ["isEnabled"] = true, ["rolloutPercentage"] = 100, ["updatedAt"] = DateTime.UtcNow, ["updatedBy"] = "system" },
        new() { ["key"] = "multi_language", ["description"] = "Hỗ trợ đa ngôn ngữ (EN/VI)", ["isEnabled"] = true, ["rolloutPercentage"] = 100, ["updatedAt"] = DateTime.UtcNow, ["updatedBy"] = "system" },
        new() { ["key"] = "loyalty_program", ["description"] = "Chương trình tích điểm thành viên", ["isEnabled"] = true, ["rolloutPercentage"] = 100, ["updatedAt"] = DateTime.UtcNow, ["updatedBy"] = "system" },
        new() { ["key"] = "advanced_analytics", ["description"] = "Phân tích nâng cao với AI insights", ["isEnabled"] = false, ["rolloutPercentage"] = 0, ["updatedAt"] = DateTime.UtcNow, ["updatedBy"] = "system" },
        new() { ["key"] = "booking_system", ["description"] = "Hệ thống đặt lịch cho Spa/Beauty", ["isEnabled"] = true, ["rolloutPercentage"] = 80, ["updatedAt"] = DateTime.UtcNow, ["updatedBy"] = "system" },
        new() { ["key"] = "kitchen_display", ["description"] = "Kitchen Display System (KDS)", ["isEnabled"] = false, ["rolloutPercentage"] = 0, ["updatedAt"] = DateTime.UtcNow, ["updatedBy"] = "system" },
    };

    [HttpGet("feature-flags")]
    public IActionResult GetFeatureFlags()
        => Ok(new { success = true, data = _featureFlags });

    [HttpPut("feature-flags/{key}")]
    public IActionResult UpdateFeatureFlag(string key, [FromBody] JsonElement body)
    {
        var flag = _featureFlags.FirstOrDefault(f => f["key"].ToString() == key);
        if (flag == null) return NotFound(new { success = false, error = new { message = "Feature flag not found" } });
        if (body.TryGetProperty("isEnabled", out var enabled))
        {
            flag["isEnabled"] = enabled.GetBoolean();
            flag["updatedAt"] = DateTime.UtcNow;
        }
        return Ok(new { success = true, data = flag });
    }

    // ═══════════════════════════════════════════════
    // ─── AUDIT HELPER ───
    // ═══════════════════════════════════════════════

    /// <summary>
    /// EN: Fire-and-forget audit log via IAM service POST /api/v1/audit/logs.
    /// VI: Ghi audit log fire-and-forget qua IAM service POST /api/v1/audit/logs.
    /// </summary>
    private async Task LogAuditAsync(int eventTypeId, string resourceType, Guid? resourceId, string action)
    {
        try
        {
            var client = CreateAuthClient("IamService");
            await client.PostAsJsonAsync("/api/v1/audit/logs", new
            {
                eventTypeId,
                resourceType,
                resourceId,
                action,
                details = $"SuperAdmin action via BFF",
                success = true
            });
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "Failed to create audit log for {Action}", action);
        }
    }

    // ═══════════════════════════════════════════════
    // ─── PROXY HELPERS ───
    // ═══════════════════════════════════════════════

    // EN: Named HttpClients already have AuthForwardingHandler registered (reads bff_session cookie automatically).
    // VI: Named HttpClients đã có AuthForwardingHandler (tự đọc bff_session cookie).
    private HttpClient CreateAuthClient(string name) => _httpFactory.CreateClient(name);

    private static async Task<JsonElement?> SafeGetJson(HttpClient client, string url)
    {
        try
        {
            var response = await client.GetAsync(url);
            if (!response.IsSuccessStatusCode) return null;
            return await response.Content.ReadFromJsonAsync<JsonElement>(_json);
        }
        catch { return null; }
    }

    private static JsonElement GetDataProperty(JsonElement json)
    {
        return json.TryGetProperty("data", out var data) ? data : json;
    }

    private static int GetInt(JsonElement el, string prop, int fallback = 0)
    {
        if (el.ValueKind != JsonValueKind.Object) return fallback;
        if (el.TryGetProperty(prop, out var val) && val.ValueKind == JsonValueKind.Number)
            return val.GetInt32();
        return fallback;
    }

    private async Task<IActionResult> ProxyGet(HttpClient client, string url)
    {
        try
        {
            var response = await client.GetAsync(url);
            var content = await response.Content.ReadAsStringAsync();
            return Content(content, "application/json");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Proxy GET failed: {Url}", url);
            return StatusCode(502, new { success = false, error = new { message = "Service unavailable" } });
        }
    }

    private async Task<IActionResult> ProxyPut(HttpClient client, string url, JsonElement body)
    {
        try
        {
            var json = JsonSerializer.Serialize(body, _json);
            var response = await client.PutAsync(url, new StringContent(json, System.Text.Encoding.UTF8, "application/json"));
            var content = await response.Content.ReadAsStringAsync();
            return Content(content, "application/json");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Proxy PUT failed: {Url}", url);
            return StatusCode(502, new { success = false, error = new { message = "Service unavailable" } });
        }
    }

    private async Task<IActionResult> ProxyPost(HttpClient client, string url)
    {
        try
        {
            var response = await client.PostAsync(url, new StringContent("{}", System.Text.Encoding.UTF8, "application/json"));
            var content = await response.Content.ReadAsStringAsync();
            return Content(content, "application/json");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Proxy POST failed: {Url}", url);
            return StatusCode(502, new { success = false, error = new { message = "Service unavailable" } });
        }
    }

    private async Task<IActionResult> ProxyPostWithBody(HttpClient client, string url, JsonElement body)
    {
        try
        {
            var json = JsonSerializer.Serialize(body, _json);
            var response = await client.PostAsync(url, new StringContent(json, System.Text.Encoding.UTF8, "application/json"));
            var content = await response.Content.ReadAsStringAsync();
            return Content(content, "application/json");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Proxy POST with body failed: {Url}", url);
            return StatusCode(502, new { success = false, error = new { message = "Service unavailable" } });
        }
    }
}
