// EN: Super Admin API Service — calls BFF + IAM endpoints for platform management.
// VI: Super Admin API Service — gọi BFF + IAM endpoints cho quản lý nền tảng.

using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace WebClientTpos.Client.Services;

/// <summary>
/// EN: Service for Super Admin platform management APIs.
/// VI: Service cho các API quản lý nền tảng Super Admin.
/// </summary>
public class SuperAdminApiService
{
    private readonly HttpClient _http;
    private static readonly JsonSerializerOptions _json = new()
    {
        PropertyNameCaseInsensitive = true,
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
    };

    public SuperAdminApiService(HttpClient http) => _http = http;

    // ═══════════════════════════════════════════════
    // ─── DTOs ───
    // ═══════════════════════════════════════════════

    public record PlatformStatsDto(
        int TotalMerchants, int ActiveMerchants, int PendingMerchants, int SuspendedMerchants,
        int TotalShops, int ActiveShops,
        int TotalUsers, int NewUsersToday,
        int TotalOrders, int OrdersToday,
        decimal GmvTotal, decimal GmvToday);

    public record MerchantAdminDto(
        Guid Id, string BusinessName, string? Type, string? Status,
        string? VerificationStatus, string? Email, string? Phone,
        int ShopsCount, int StaffCount, string? PlanName,
        DateTime CreatedAt, DateTime? LastLoginAt);

    public record MerchantDetailDto(
        Guid Id, Guid UserId, string BusinessName, string? Type,
        string? Status, string? VerificationStatus,
        string? TaxCode, string? Address, string? City, string? District,
        string? Email, string? Phone, string? Website,
        int ShopsCount, int StaffCount,
        int SubscriptionPlanId, string? SubscriptionPlanName, string? PlanName,
        DateTime CreatedAt, DateTime? VerifiedAt, DateTime? LastLoginAt,
        List<ShopSummaryDto>? Shops);

    public record ShopSummaryDto(
        Guid Id, string Name, string? Category, string? Status, DateTime CreatedAt);

    public record SubscriptionPlanDto(
        Guid Id, string Name, string? Slug, string? Description,
        decimal PriceMonthly, decimal? PriceYearly,
        int MaxShops, int MaxStaff, int MaxProducts,
        bool IsActive, int MerchantCount, int SortOrder);

    public record ServiceHealthDto(string Name, string Status, int ResponseTimeMs, DateTime LastChecked);

    public record FeatureFlagDto(
        string Key, string? Description, bool IsEnabled,
        int RolloutPercentage, DateTime UpdatedAt, string? UpdatedBy);

    // ═══════════════════════════════════════════════
    // ─── PLATFORM DASHBOARD ───
    // ═══════════════════════════════════════════════

    public async Task<PlatformStatsDto?> GetPlatformStatsAsync()
    {
        try
        {
            var response = await _http.GetAsync("/api/bff/superadmin/stats");
            if (!response.IsSuccessStatusCode) return null;
            var json = await response.Content.ReadFromJsonAsync<JsonElement>(_json);
            if (json.TryGetProperty("data", out var data))
                return data.Deserialize<PlatformStatsDto>(_json);
            return json.Deserialize<PlatformStatsDto>(_json);
        }
        catch { return null; }
    }

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

    public async Task<(List<MerchantAdminDto> Items, int TotalCount)> GetMerchantsAsync(
        int page = 1, int pageSize = 20, string? status = null, string? search = null)
    {
        try
        {
            var url = $"/api/bff/superadmin/merchants?page={page}&pageSize={pageSize}";
            if (!string.IsNullOrEmpty(status)) url += $"&status={status}";
            if (!string.IsNullOrEmpty(search)) url += $"&search={Uri.EscapeDataString(search)}";

            var response = await _http.GetAsync(url);
            if (!response.IsSuccessStatusCode) return (new(), 0);

            var json = await response.Content.ReadFromJsonAsync<JsonElement>(_json);
            var items = new List<MerchantAdminDto>();
            int total = 0;

            // EN: Handle multiple response formats: { data: { items } }, { data: [] }, { items: [] }, or direct []
            // VI: Xử lý nhiều format response: { data: { items } }, { data: [] }, { items: [] }, hoặc trực tiếp []
            if (json.TryGetProperty("data", out var data))
            {
                if (data.ValueKind == JsonValueKind.Array)
                    items = data.Deserialize<List<MerchantAdminDto>>(_json) ?? new();
                else if (data.TryGetProperty("items", out var itms))
                    items = itms.Deserialize<List<MerchantAdminDto>>(_json) ?? new();
            }
            else if (json.TryGetProperty("items", out var directItems))
            {
                items = directItems.Deserialize<List<MerchantAdminDto>>(_json) ?? new();
            }

            // EN: Extract totalCount from multiple possible locations
            // VI: Trích xuất totalCount từ nhiều vị trí có thể
            if (json.TryGetProperty("pagination", out var pg) && pg.TryGetProperty("totalCount", out var tc))
                total = tc.GetInt32();
            else if (json.TryGetProperty("totalCount", out var tc2))
                total = tc2.GetInt32();
            if (total == 0) total = items.Count;

            return (items, total);
        }
        catch { return (new(), 0); }
    }

    public async Task<MerchantDetailDto?> GetMerchantDetailAsync(Guid id)
    {
        try
        {
            var response = await _http.GetAsync($"/api/bff/superadmin/merchants/{id}");
            if (!response.IsSuccessStatusCode) return null;
            var json = await response.Content.ReadFromJsonAsync<JsonElement>(_json);
            if (json.TryGetProperty("data", out var data))
                return data.Deserialize<MerchantDetailDto>(_json);
            return json.Deserialize<MerchantDetailDto>(_json);
        }
        catch { return null; }
    }

    public async Task<(bool Success, string? Error)> UpdateMerchantPlanAsync(Guid id, int planId)
    {
        try
        {
            var response = await _http.PutAsJsonAsync(
                $"/api/bff/superadmin/merchants/{id}/plan", new { planId }, _json);
            if (response.IsSuccessStatusCode) return (true, null);
            return (false, await ExtractError(response));
        }
        catch (Exception ex) { return (false, ex.Message); }
    }

    public async Task<(bool Success, string? Error)> ApproveMerchantAsync(Guid id, string? note = null)
    {
        try
        {
            var response = await _http.PostAsJsonAsync(
                $"/api/bff/superadmin/merchants/{id}/approve", new { note }, _json);
            if (response.IsSuccessStatusCode) return (true, null);
            return (false, await ExtractError(response));
        }
        catch (Exception ex) { return (false, ex.Message); }
    }

    public async Task<(bool Success, string? Error)> SuspendMerchantAsync(Guid id, string reason)
    {
        try
        {
            var response = await _http.PostAsJsonAsync(
                $"/api/bff/superadmin/merchants/{id}/suspend", new { reason }, _json);
            if (response.IsSuccessStatusCode) return (true, null);
            return (false, await ExtractError(response));
        }
        catch (Exception ex) { return (false, ex.Message); }
    }

    public async Task<(bool Success, string? Error)> ReactivateMerchantAsync(Guid id)
    {
        try
        {
            var response = await _http.PostAsJsonAsync(
                $"/api/bff/superadmin/merchants/{id}/reactivate", new { }, _json);
            if (response.IsSuccessStatusCode) return (true, null);
            return (false, await ExtractError(response));
        }
        catch (Exception ex) { return (false, ex.Message); }
    }

    // ═══════════════════════════════════════════════
    // ─── SUBSCRIPTIONS ───
    // ═══════════════════════════════════════════════

    public async Task<List<SubscriptionPlanDto>> GetPlansAsync()
    {
        try
        {
            var response = await _http.GetAsync("/api/bff/superadmin/plans");
            if (!response.IsSuccessStatusCode) return new();
            var json = await response.Content.ReadFromJsonAsync<JsonElement>(_json);
            if (json.TryGetProperty("data", out var data) && data.ValueKind == JsonValueKind.Array)
                return data.Deserialize<List<SubscriptionPlanDto>>(_json) ?? new();
            return new();
        }
        catch { return new(); }
    }

    public async Task<(bool Success, string? Error)> SavePlanAsync(SubscriptionPlanDto plan)
    {
        try
        {
            var response = plan.Id == Guid.Empty
                ? await _http.PostAsJsonAsync("/api/bff/superadmin/plans", plan, _json)
                : await _http.PutAsJsonAsync($"/api/bff/superadmin/plans/{plan.Id}", plan, _json);
            if (response.IsSuccessStatusCode) return (true, null);
            return (false, await ExtractError(response));
        }
        catch (Exception ex) { return (false, ex.Message); }
    }

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

    public async Task<List<ServiceHealthDto>> GetSystemHealthAsync()
    {
        try
        {
            var response = await _http.GetAsync("/api/bff/superadmin/system/health");
            if (!response.IsSuccessStatusCode) return new();
            var json = await response.Content.ReadFromJsonAsync<JsonElement>(_json);
            if (json.TryGetProperty("data", out var data) && data.ValueKind == JsonValueKind.Array)
                return data.Deserialize<List<ServiceHealthDto>>(_json) ?? new();
            return new();
        }
        catch { return new(); }
    }

    // ═══════════════════════════════════════════════
    // ─── FEATURE FLAGS ───
    // ═══════════════════════════════════════════════

    public async Task<List<FeatureFlagDto>> GetFeatureFlagsAsync()
    {
        try
        {
            var response = await _http.GetAsync("/api/bff/superadmin/feature-flags");
            if (!response.IsSuccessStatusCode) return new();
            var json = await response.Content.ReadFromJsonAsync<JsonElement>(_json);
            if (json.TryGetProperty("data", out var data) && data.ValueKind == JsonValueKind.Array)
                return data.Deserialize<List<FeatureFlagDto>>(_json) ?? new();
            return new();
        }
        catch { return new(); }
    }

    public async Task<(bool Success, string? Error)> UpdateFeatureFlagAsync(string key, bool isEnabled)
    {
        try
        {
            var response = await _http.PutAsJsonAsync(
                $"/api/bff/superadmin/feature-flags/{key}", new { isEnabled }, _json);
            if (response.IsSuccessStatusCode) return (true, null);
            return (false, await ExtractError(response));
        }
        catch (Exception ex) { return (false, ex.Message); }
    }

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

    private static async Task<string> ExtractError(HttpResponseMessage response)
    {
        try
        {
            var json = await response.Content.ReadFromJsonAsync<JsonElement>(_json);
            if (json.TryGetProperty("error", out var err) && err.TryGetProperty("message", out var m))
                return m.GetString() ?? response.ReasonPhrase ?? "Unknown error";
        }
        catch { }
        return response.ReasonPhrase ?? "Unknown error";
    }
}
