import SwiftUI

// MARK: - Row Background Environment Key

/// Lets parent views communicate their background color to descendants
/// so that elements like the online-indicator border can match dynamically.
private struct RowBackgroundColorKey: EnvironmentKey {
    static let defaultValue: Color? = nil
}

extension EnvironmentValues {
    var rowBackgroundColor: Color? {
        get { self[RowBackgroundColorKey.self] }
        set { self[RowBackgroundColorKey.self] = newValue }
    }
}

// MARK: - AvatarView

struct AvatarView: View {
    let initials: String
    let colorIndex: Int
    let size: CGFloat
    var isOnline: Bool = false
    var isSavedMessages: Bool = false
    /// Optional avatar photo. When non-nil, displayed as a circular image.
    var image: UIImage? = nil
    /// Override for the online-indicator border (matches row background).
    var onlineBorderColor: Color?

    @Environment(\.colorScheme) private var colorScheme
    @Environment(\.rowBackgroundColor) private var rowBackgroundColor

    private var avatarPair: (tint: Color, text: Color) {
        RosettaColors.avatarColors[colorIndex % RosettaColors.avatarColors.count]
    }

    /// Mantine "light" variant: shade-3 in dark, shade-6 (tint) in light.
    private var textColor: Color {
        colorScheme == .dark ? avatarPair.text : avatarPair.tint
    }

    private var fontSize: CGFloat { size * 0.38 }
    /// Desktop parity: 12px dot on 50px avatar = 24%.
    private var badgeSize: CGFloat { size * 0.24 }
    /// Desktop parity: 2px border on 50px avatar = 4%.
    private var badgeBorderWidth: CGFloat { max(size * 0.04, 1.5) }

    /// Mantine dark body background (#1A1B1E).
    private static let mantineDarkBody = Color(hex: 0x1A1B1E)

    var body: some View {
        ZStack {
            if let image {
                // Avatar photo — circular crop
                Image(uiImage: image)
                    .resizable()
                    .scaledToFill()
                    .frame(width: size, height: size)
                    .clipShape(Circle())
            } else if isSavedMessages {
                Circle().fill(RosettaColors.primaryBlue)

                Image(systemName: "bookmark.fill")
                    .font(.system(size: fontSize, weight: .semibold))
                    .foregroundStyle(.white)
            } else {
                // Mantine "light" variant: opaque base + semi-transparent tint
                Circle().fill(RosettaColors.adaptive(light: .white, dark: Self.mantineDarkBody))
                Circle().fill(avatarPair.tint.opacity(colorScheme == .dark ? 0.15 : 0.10))

                Text(initials)
                    .font(.system(size: fontSize, weight: .bold, design: .rounded))
                    .foregroundStyle(textColor)
                    .lineLimit(1)
                    .minimumScaleFactor(0.5)
            }
        }
        .frame(width: size, height: size)
        .overlay(alignment: .bottomTrailing) {
            if isOnline && !isSavedMessages {
                Circle()
                    .fill(RosettaColors.primaryBlue)
                    .frame(width: badgeSize, height: badgeSize)
                    .overlay {
                        Circle()
                            .stroke(
                                onlineBorderColor ?? rowBackgroundColor ?? RosettaColors.Adaptive.background,
                                lineWidth: badgeBorderWidth
                            )
                    }
                    .offset(x: 1, y: -1)
            }
        }
        .accessibilityLabel(isSavedMessages ? "Saved Messages" : initials)
        .accessibilityAddTraits(isOnline ? [.isStaticText] : [])
    }
}

// MARK: - Preview

#Preview {
    HStack(spacing: 16) {
        AvatarView(initials: "AJ", colorIndex: 0, size: 56, isOnline: true)
        AvatarView(initials: "BS", colorIndex: 2, size: 56, isOnline: false)
        AvatarView(initials: "S", colorIndex: 4, size: 56, isSavedMessages: true)
        AvatarView(initials: "CD", colorIndex: 6, size: 40, isOnline: true)
    }
    .padding()
    .background(RosettaColors.Adaptive.background)
}
