import SwiftUI
import Bedrock
import SwiftData

struct BusinessCardView: View {
    let card: BusinessCard
    var isCompact: Bool = false

    private var hasOverlappingContent: Bool {
        card.headerLayout.hasOverlappingContent
    }

    var body: some View {
        VStack(spacing: 0) {
            CardBannerView(card: card)
            
            CardContentView(card: card, isCompact: isCompact)
                .offset(y: hasOverlappingContent ? -Design.CardSize.avatarOverlap : 0)
                .padding(.bottom, hasOverlappingContent ? -Design.CardSize.avatarOverlap : 0)
        }
        .background(Color.AppBackground.elevated)
        .clipShape(.rect(cornerRadius: Design.CornerRadius.xLarge))
        .shadow(
            color: Color.Text.secondary.opacity(Design.Opacity.hint),
            radius: Design.Shadow.radiusLarge,
            x: Design.Shadow.offsetNone,
            y: Design.Shadow.offsetMedium
        )
        .accessibilityElement(children: .ignore)
        .accessibilityLabel(String.localized("Business card"))
        .accessibilityValue("\(card.effectiveDisplayName), \(card.role), \(card.company)")
    }
}

// MARK: - Banner View

private struct CardBannerView: View {
    let card: BusinessCard
    
    var body: some View {
        Group {
            switch card.headerLayout.bannerContent {
            case .profile:
                ProfileBannerContent(card: card)
            case .logo:
                LogoBannerContent(card: card)
            case .cover:
                CoverBannerContent(card: card)
            }
        }
        .frame(height: Design.CardSize.bannerHeight)
    }
}

// MARK: - Profile Banner Content

private struct ProfileBannerContent: View {
    let card: BusinessCard
    
    var body: some View {
        ZStack {
            if let photoData = card.photoData, let uiImage = UIImage(data: photoData) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFill()
                    .clipped()
            } else {
                LinearGradient(
                    colors: [card.theme.primaryColor, card.theme.secondaryColor],
                    startPoint: .topLeading,
                    endPoint: .bottomTrailing
                )
                
                VStack(spacing: Design.Spacing.xSmall) {
                    Image(systemName: "person.fill")
                        .font(.system(size: Design.BaseFontSize.display, weight: .bold))
                    Text("Profile")
                        .font(.title3)
                        .bold()
                }
                .foregroundStyle(card.theme.textColor.opacity(Design.Opacity.medium))
            }
        }
    }
}

// MARK: - Logo Banner Content

private struct LogoBannerContent: View {
    let card: BusinessCard
    
    var body: some View {
        ZStack {
            LinearGradient(
                colors: [card.theme.primaryColor, card.theme.secondaryColor],
                startPoint: .topLeading,
                endPoint: .bottomTrailing
            )
            
            if let logoData = card.logoData, let uiImage = UIImage(data: logoData) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFill()
                    .clipped()
            } else {
                VStack(spacing: Design.Spacing.xSmall) {
                    Image(systemName: "building.2.fill")
                        .font(.system(size: Design.BaseFontSize.display, weight: .bold))
                    Text("Logo")
                        .font(.title3)
                        .bold()
                }
                .foregroundStyle(card.theme.textColor.opacity(Design.Opacity.medium))
            }
        }
    }
}

// MARK: - Cover Banner Content

private struct CoverBannerContent: View {
    let card: BusinessCard
    
    var body: some View {
        if let coverPhotoData = card.coverPhotoData, let uiImage = UIImage(data: coverPhotoData) {
            Image(uiImage: uiImage)
                .resizable()
                .scaledToFill()
                .clipped()
        } else {
            ZStack {
                LinearGradient(
                    colors: [card.theme.primaryColor, card.theme.secondaryColor],
                    startPoint: .topLeading,
                    endPoint: .bottomTrailing
                )
                
                VStack(spacing: Design.Spacing.xSmall) {
                    Image(systemName: "photo.fill")
                        .font(.system(size: Design.BaseFontSize.display, weight: .bold))
                    Text("Cover")
                        .font(.title3)
                        .bold()
                }
                .foregroundStyle(card.theme.textColor.opacity(Design.Opacity.medium))
            }
        }
    }
}

// MARK: - Content View

private struct CardContentView: View {
    let card: BusinessCard
    let isCompact: Bool
    
    private var textColor: Color { Color.Text.primary }
    
    var body: some View {
        VStack(alignment: .leading, spacing: Design.Spacing.medium) {
            contentOverlay
            
            VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) {
                HStack(spacing: Design.Spacing.xSmall) {
                    Text(card.effectiveDisplayName)
                        .font(.title2)
                        .bold()
                        .foregroundStyle(textColor)
                    
                    if !card.pronouns.isEmpty {
                        Text("(\(card.pronouns))")
                            .font(.subheadline)
                            .foregroundStyle(Color.Text.secondary)
                    }
                }
                
                Text(card.role)
                    .font(.headline)
                    .foregroundStyle(textColor)
                
                Text(card.company)
                    .font(.subheadline)
                    .foregroundStyle(Color.Text.secondary)
                
                if !card.headline.isEmpty {
                    Text(card.headline)
                        .font(.caption)
                        .foregroundStyle(Color.Text.secondary)
                        .padding(.top, Design.Spacing.xxSmall)
                }
            }
            
            if !isCompact {
                Divider()
                    .padding(.vertical, Design.Spacing.xSmall)
                
                ContactFieldsListView(card: card)
            }
        }
        .padding(.horizontal, Design.Spacing.large)
        .padding(.bottom, Design.Spacing.large)
    }
    
    @ViewBuilder
    private var contentOverlay: some View {
        switch card.headerLayout.contentOverlay {
        case .none:
            EmptyView()
        case .avatar:
            HStack {
                ProfileAvatarView(card: card)
                Spacer()
            }
        case .logoRectangle:
            HStack {
                LogoRectangleView(card: card)
                Spacer()
            }
        case .avatarAndLogo:
            HStack(alignment: .bottom) {
                ProfileAvatarView(card: card)
                Spacer()
                LogoRectangleView(card: card)
            }
        }
    }
}

// MARK: - Profile Avatar

private struct ProfileAvatarView: View {
    let card: BusinessCard
    
    var body: some View {
        Group {
            if let photoData = card.photoData, let uiImage = UIImage(data: photoData) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFill()
            } else {
                Image(systemName: card.avatarSystemName)
                    .font(.system(size: Design.BaseFontSize.title))
                    .foregroundStyle(card.theme.textColor)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(card.theme.accentColor)
            }
        }
        .frame(width: Design.CardSize.avatarLarge, height: Design.CardSize.avatarLarge)
        .clipShape(.circle)
        .overlay(Circle().stroke(Color.AppBackground.elevated, lineWidth: Design.LineWidth.thick))
        .shadow(color: Color.Text.secondary.opacity(Design.Opacity.hint), radius: Design.Shadow.radiusSmall, x: Design.Shadow.offsetNone, y: Design.Shadow.offsetSmall)
    }
}

// MARK: - Logo Badge View

private struct LogoBadgeView: View {
    let card: BusinessCard
    
    var body: some View {
        Group {
            if let logoData = card.logoData, let uiImage = UIImage(data: logoData) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFill()
                    .clipped()
            } else {
                VStack(spacing: Design.Spacing.xxSmall) {
                    Image(systemName: "building.2")
                        .font(.system(size: Design.BaseFontSize.body))
                    Text("Logo")
                        .font(.caption2)
                }
                .foregroundStyle(card.theme.textColor)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            }
        }
        .frame(width: Design.CardSize.avatarLarge, height: Design.CardSize.avatarLarge)
        .background(card.theme.accentColor)
        .clipShape(.rect(cornerRadius: Design.CornerRadius.medium))
        .overlay(RoundedRectangle(cornerRadius: Design.CornerRadius.medium).stroke(Color.AppBackground.elevated, lineWidth: Design.LineWidth.thick))
        .shadow(color: Color.Text.secondary.opacity(Design.Opacity.hint), radius: Design.Shadow.radiusSmall, x: Design.Shadow.offsetNone, y: Design.Shadow.offsetSmall)
    }
}

// MARK: - Logo Rectangle View

private struct LogoRectangleView: View {
    let card: BusinessCard
    
    private let aspectRatio: CGFloat = Design.CardSize.logoContainerAspectRatio
    
    var body: some View {
        Group {
            if let logoData = card.logoData, let uiImage = UIImage(data: logoData) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFill()
                    .clipped()
            } else {
                VStack(spacing: Design.Spacing.xxSmall) {
                    Image(systemName: "building.2")
                        .font(.system(size: Design.BaseFontSize.body))
                    Text("Logo")
                        .font(.caption2)
                }
                .foregroundStyle(card.theme.textColor)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            }
        }
        .frame(width: Design.CardSize.avatarLarge * aspectRatio, height: Design.CardSize.avatarLarge)
        .background(card.theme.accentColor)
        .clipShape(.rect(cornerRadius: Design.CornerRadius.medium))
        .overlay(RoundedRectangle(cornerRadius: Design.CornerRadius.medium).stroke(Color.AppBackground.elevated, lineWidth: Design.LineWidth.thick))
        .shadow(color: Color.Text.secondary.opacity(Design.Opacity.hint), radius: Design.Shadow.radiusSmall, x: Design.Shadow.offsetNone, y: Design.Shadow.offsetSmall)
    }
}

// MARK: - Contact Fields List

private struct ContactFieldsListView: View {
    @Environment(\.openURL) private var openURL
    let card: BusinessCard
    
    var body: some View {
        VStack(alignment: .leading, spacing: Design.Spacing.small) {
            ForEach(card.orderedContactFields) { field in
                ContactFieldRowView(field: field) {
                    if let url = field.buildURL() {
                        openURL(url)
                    }
                }
            }
        }
    }
}

private struct ContactFieldRowView: View {
    let field: ContactField
    let action: () -> Void
    
    var body: some View {
        Button(action: action) {
            HStack(alignment: .top, spacing: Design.Spacing.medium) {
                field.iconImage()
                    .font(.body)
                    .foregroundStyle(.white)
                    .frame(width: Design.CardSize.socialIconSize, height: Design.CardSize.socialIconSize)
                    .background(field.iconColor)
                    .clipShape(.circle)
                
                VStack(alignment: .leading, spacing: 0) {
                    Text(field.displayValue)
                        .font(.subheadline)
                        .foregroundStyle(Color.Text.primary)
                        .multilineTextAlignment(.leading)
                    
                    Text(field.title.isEmpty ? field.displayName : field.title)
                        .font(.caption)
                        .foregroundStyle(Color.Text.secondary)
                        .lineLimit(1)
                }
                
                Spacer()
                
                Image(systemName: "chevron.right")
                    .font(.caption)
                    .foregroundStyle(Color.Text.tertiary)
            }
            .contentShape(.rect)
        }
        .buttonStyle(.plain)
        .accessibilityLabel("\(field.displayName): \(field.value)")
        .accessibilityHint(field.title.isEmpty ? String(localized: "Opens \(field.displayName)") : field.title)
    }
}

// MARK: - Previews

#Preview("Profile Banner") {
    @Previewable @State var card = BusinessCard(
        displayName: "Matt Bruce",
        role: "Lead iOS Developer",
        company: "Toyota",
        themeName: "Coral",
        headerLayoutRawValue: "profileBanner"
    )
    
    BusinessCardView(card: card)
        .padding()
        .background(Color.AppBackground.base)
}

#Preview("Cover + Avatar + Logo") {
    @Previewable @State var card = BusinessCard(
        displayName: "Matt Bruce",
        role: "Lead iOS Developer",
        company: "Toyota",
        themeName: "Violet",
        headerLayoutRawValue: "coverWithAvatarAndLogo"
    )
    
    BusinessCardView(card: card)
        .padding()
        .background(Color.AppBackground.base)
}
