import WidgetKit
import SwiftUI

// MARK: - Маленький

/// Герой-карточка первой пары в сжатой компоновке.
struct SmallWidgetView: View {
    let entry: CryptoEntry

    private let padding: CGFloat = 14

    var body: some View {
        Group {
            if let hero = entry.quotes.first {
                HeroCard(
                    quote: hero,
                    updatedAt: entry.date,
                    horizontalPadding: padding,
                    iconSize: 20,
                    titleSize: 13,
                    priceSize: 21,
                    chartHeight: 40,
                    showFullDate: false,
                    showAbsolute: false
                )
                .padding(padding)
            } else {
                EmptyState(reason: entry.emptyReason)
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
        .containerBackground(for: .widget) { RapiraBackground() }
    }
}

// MARK: - Средний

/// Список до трёх пар со временем обновления в шапке.
struct MediumWidgetView: View {
    let entry: CryptoEntry

    var body: some View {
        Group {
            if entry.quotes.isEmpty {
                EmptyState(reason: entry.emptyReason)
            } else {
                list
            }
        }
        .containerBackground(for: .widget) { RapiraBackground() }
    }

    private var list: some View {
        VStack(spacing: 0) {
            HStack {
                UpdatedAt(date: entry.date, fontSize: 9.5)
                Spacer()
                RapiraMark(size: 13)
            }
            .padding(.bottom, 2)

            let quotes = Array(entry.quotes.prefix(3))
            ForEach(Array(quotes.enumerated()), id: \.element.id) { index, quote in
                CryptoRow(quote: quote, compact: true)
                    .frame(maxHeight: .infinity)
                if index < quotes.count - 1 {
                    RapiraPalette.divider.frame(height: 1).padding(.leading, 32)
                }
            }
        }
        .padding(.horizontal, 14)
        .padding(.vertical, 8)
    }
}

// MARK: - Большой

/// Герой первой пары + до четырёх остальных списком.
struct LargeWidgetView: View {
    let entry: CryptoEntry

    private let padding: CGFloat = 16

    var body: some View {
        Group {
            if let hero = entry.quotes.first {
                content(hero: hero, rest: Array(entry.quotes.dropFirst().prefix(4)))
            } else {
                EmptyState(reason: entry.emptyReason)
            }
        }
        .containerBackground(for: .widget) { RapiraBackground() }
    }

    private func content(hero: Quote, rest: [Quote]) -> some View {
        VStack(alignment: .leading, spacing: 0) {
            HeroCard(
                quote: hero,
                updatedAt: entry.date,
                horizontalPadding: padding,
                iconSize: 28,
                titleSize: 19,
                priceSize: 32,
                chartHeight: 70
            )

            if !rest.isEmpty {
                RapiraPalette.divider
                    .frame(height: 1)
                    .padding(.top, 14)
                    .padding(.horizontal, -padding)

                ForEach(Array(rest.enumerated()), id: \.element.id) { index, quote in
                    CryptoRow(quote: quote, compact: false)
                        .frame(maxHeight: .infinity)
                    if index < rest.count - 1 {
                        RapiraPalette.divider.frame(height: 1).padding(.leading, 34)
                    }
                }
            }
        }
        .padding(padding)
    }
}

// MARK: - Диспетчер размеров

struct CryptoWidgetEntryView: View {
    let entry: CryptoEntry

    @Environment(\.widgetFamily) private var family

    var body: some View {
        switch family {
        case .systemSmall: SmallWidgetView(entry: entry)
        case .systemMedium: MediumWidgetView(entry: entry)
        case .systemLarge: LargeWidgetView(entry: entry)
        default: MediumWidgetView(entry: entry)
        }
    }
}

extension CryptoEntry {
    var emptyReason: EmptyState.Reason {
        dataUnavailable ? .noData : .noSelection
    }
}
