using System.Text.Json;

namespace PlanTempus.Application.Features.Customers.Components;

/// <summary>
/// Shared catalog for customer detail data.
/// Loads from customerDetailMock.json and used by all CustomerDetail* ViewComponents.
/// </summary>
public static class CustomerDetailCatalog
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNameCaseInsensitive = true
    };

    private static Dictionary<string, CustomerDetailRecord>? _customers;

    private static Dictionary<string, CustomerDetailRecord> Customers
    {
        get
        {
            if (_customers == null)
            {
                var jsonPath = Path.Combine(
                    AppDomain.CurrentDomain.BaseDirectory,
                    "Features", "Customers", "Data", "customerDetailMock.json");
                var json = File.ReadAllText(jsonPath);
                _customers = JsonSerializer.Deserialize<Dictionary<string, CustomerDetailRecord>>(json, JsonOptions)
                    ?? new Dictionary<string, CustomerDetailRecord>();
            }
            return _customers;
        }
    }

    public static CustomerDetailRecord Get(string customerId)
    {
        if (!Customers.TryGetValue(customerId, out var customer))
            throw new KeyNotFoundException($"Customer with id '{customerId}' not found");
        return customer;
    }

    public static IEnumerable<string> AllIds => Customers.Keys;
}

// Root record for customer detail
public record CustomerDetailRecord
{
    public required string Id { get; init; }
    public required CustomerHeaderRecord Header { get; init; }
    public required CustomerContactRecord Contact { get; init; }
    public List<CustomerProfileItem> Profile { get; init; } = new();
    public required CustomerMarketingRecord Marketing { get; init; }
    public required CustomerPaymentRecord Payment { get; init; }
    public required CustomerPreferencesRecord Preferences { get; init; }
    public List<CustomerWarningItem> Warnings { get; init; } = new();
    public required CustomerGroupRecord Group { get; init; }
    public List<CustomerRelationRecord> Relations { get; init; } = new();
    public required CustomerStatisticsRecord Statistics { get; init; }
    public List<CustomerJournalEntry> Journal { get; init; } = new();
    public required CustomerAppointmentsRecord Appointments { get; init; }
    public required CustomerGiftcardsRecord Giftcards { get; init; }
    public List<CustomerActivityEntry> Activity { get; init; } = new();
    public CustomerEconomyRecord? Economy { get; init; }
}

// Header section
public record CustomerHeaderRecord
{
    public required string Initials { get; init; }
    public required string Name { get; init; }
    public required string CustomerSince { get; init; }
    public List<string> Tags { get; init; } = new();
    public bool BookingAllowed { get; init; }
    public required CustomerFactsRecord Facts { get; init; }
}

public record CustomerFactsRecord
{
    public int Visits { get; init; }
    public int AvgIntervalDays { get; init; }
    public required string PreferredHairdresser { get; init; }
    public decimal TotalRevenue { get; init; }
}

// Contact section
public record CustomerContactRecord
{
    public required string Phone { get; init; }
    public required string Email { get; init; }
    public required string Address { get; init; }
    public required string Zip { get; init; }
    public required string City { get; init; }
}

// Profile item (flexible)
public record CustomerProfileItem
{
    public required string Title { get; init; }
    public required string Value { get; init; }
}

// Marketing settings
public record CustomerMarketingRecord
{
    public bool EmailOptIn { get; init; }
    public bool SmsOptIn { get; init; }
}

// Payment settings
public record CustomerPaymentRecord
{
    public bool RequirePrepayment { get; init; }
    public bool AllowPartialPayment { get; init; }
}

// Preferences
public record CustomerPreferencesRecord
{
    public required string PreferredHairdresser { get; init; }
    public required string PreferredDays { get; init; }
    public required string SpecialRequests { get; init; }
}

// Warning item (flexible)
public record CustomerWarningItem
{
    public required string Title { get; init; }
    public required string Value { get; init; }
}

// Group
public record CustomerGroupRecord
{
    public required string GroupId { get; init; }
    public required string GroupName { get; init; }
}

// Relation
public record CustomerRelationRecord
{
    public required string Id { get; init; }
    public required string Name { get; init; }
    public required string Initials { get; init; }
    public required string Type { get; init; }
}

// Statistics
public record CustomerStatisticsRecord
{
    public required CustomerAttendanceRecord Attendance { get; init; }
    public List<CustomerTopItem> TopServices { get; init; } = new();
    public List<CustomerTopItem> TopProducts { get; init; } = new();
    public required CustomerBookingBehaviorRecord BookingBehavior { get; init; }
    public required CustomerLoyaltyRecord Loyalty { get; init; }
}

public record CustomerAttendanceRecord
{
    public int Attended { get; init; }
    public int Cancelled { get; init; }
    public int NoShow { get; init; }
    public int ReliabilityPercent { get; init; }
}

public record CustomerTopItem
{
    public required string Name { get; init; }
    public int Count { get; init; }
}

public record CustomerBookingBehaviorRecord
{
    public int AvgBookingNoticeDays { get; init; }
    public required string PreferredDay { get; init; }
    public required string PreferredTimeSlot { get; init; }
    public int OnlineBookingRate { get; init; }
    public int AvgCancellationNoticeDays { get; init; }
}

public record CustomerLoyaltyRecord
{
    public double CustomerSinceYears { get; init; }
    public int DaysSinceLastVisit { get; init; }
    public required string ChurnRisk { get; init; }
    public int AvgIntervalDays { get; init; }
}

// Journal
public record CustomerJournalEntry
{
    public required string Id { get; init; }
    public required string Type { get; init; }
    public required string Tag { get; init; }
    public List<string> Subtags { get; init; } = new();
    public required string Text { get; init; }
    public required string Date { get; init; }
    public required string Author { get; init; }
}

// Appointments
public record CustomerAppointmentsRecord
{
    public List<CustomerUpcomingAppointment> Upcoming { get; init; } = new();
    public List<CustomerHistoryAppointment> History { get; init; } = new();
}

public record CustomerUpcomingAppointment
{
    public required string Date { get; init; }
    public required string Time { get; init; }
    public required string Service { get; init; }
    public required string Hairdresser { get; init; }
    public required string Duration { get; init; }
}

public record CustomerHistoryAppointment
{
    public required string Date { get; init; }
    public required string Service { get; init; }
    public required string Hairdresser { get; init; }
    public required string Duration { get; init; }
    public decimal Price { get; init; }
}

// Giftcards
public record CustomerGiftcardsRecord
{
    public List<CustomerGiftcardItem> Active { get; init; } = new();
    public List<CustomerGiftcardItem> Expired { get; init; } = new();
}

public record CustomerGiftcardItem
{
    public required string Id { get; init; }
    public required string Type { get; init; }
    public required string Label { get; init; }
    public decimal? OriginalValue { get; init; }
    public decimal? CurrentBalance { get; init; }
    public int? TotalPunches { get; init; }
    public int? UsedPunches { get; init; }
    public string? ExpiresAt { get; init; }
}

// Activity
public record CustomerActivityEntry
{
    public required string Date { get; init; }
    public required string Time { get; init; }
    public required string Type { get; init; }
    public required string Icon { get; init; }
    public required string Title { get; init; }
    public string? Actor { get; init; }
    public List<string> Badges { get; init; } = new();
}

// Economy
public record CustomerEconomyRecord
{
    public required CustomerYearRevenue CurrentYear { get; init; }
    public required CustomerYearRevenue LastYear { get; init; }
    public decimal AvgPerVisit { get; init; }
    public decimal AvgPerMonth { get; init; }
    public CustomerChartData? ChartData { get; init; }
    public List<CustomerPurchase> Purchases { get; init; } = new();
}

public record CustomerChartData
{
    public List<string> Categories { get; init; } = new();
    public List<CustomerChartSeries> Series { get; init; } = new();
}

public record CustomerChartSeries
{
    public required string Name { get; init; }
    public required string Color { get; init; }
    public List<CustomerChartDataPoint> Data { get; init; } = new();
}

public record CustomerChartDataPoint
{
    public required string X { get; init; }
    public decimal Y { get; init; }
}

public record CustomerYearRevenue
{
    public int Year { get; init; }
    public decimal Total { get; init; }
}

public record CustomerPurchase
{
    public required string Invoice { get; init; }
    public required string Date { get; init; }
    public required string Time { get; init; }
    public required string Employee { get; init; }
    public required string Services { get; init; }
    public required string Type { get; init; }
    public decimal Amount { get; init; }
}
