import SwiftUI
import Bedrock
import SwiftData
import PhotosUI

struct CardEditorView: View {
    @Environment(AppState.self) private var appState
    @Environment(\.dismiss) private var dismiss
    
    let card: BusinessCard?
    let onSave: (BusinessCard) -> Void
    
    // Name fields
    @State private var displayName = ""
    @State private var prefix = ""
    @State private var firstName = ""
    @State private var middleName = ""
    @State private var lastName = ""
    @State private var suffix = ""
    @State private var maidenName = ""
    @State private var preferredName = ""
    @State private var pronouns = ""
    @State private var showNameDetails = false
    
    // Professional info
    @State private var role = ""
    @State private var department = ""
    @State private var company = ""
    @State private var headline = ""
    @State private var label = "Work"
    @State private var bio = ""
    @State private var accreditations = ""
    
    // Contact fields (unified list for picker-based UI)
    @State private var contactFields: [AddedContactField] = []
    
    // Appearance
    @State private var avatarSystemName = "person.crop.circle"
    @State private var selectedTheme: CardTheme = .coral
    @State private var selectedLayout: CardLayoutStyle = .stacked
    
    // Photos
    @State private var photoData: Data?
    @State private var coverPhotoData: Data?
    @State private var logoData: Data?
    
    // Default card
    @State private var isDefault = false
    
    // Photo editor state - just one variable!
    @State private var editingImageType: ImageType?
    
    @State private var showingPreview = false
    
    enum ImageType: String, Identifiable {
        case profile
        case cover
        case logo
        
        var id: String { rawValue }
        
        var title: String {
            switch self {
            case .profile: return String.localized("Add profile picture")
            case .cover: return String.localized("Add cover photo")
            case .logo: return String.localized("Add company logo")
            }
        }
        
        var cropAspectRatio: CropAspectRatio {
            switch self {
            case .profile: return .square
            case .cover: return .banner
            case .logo: return .square
            }
        }
    }
    
    private var isEditing: Bool { card != nil }
    private var isFormValid: Bool {
        !effectiveDisplayName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
    }
    
    /// Simple name for validation and storage (without quotes/parentheses formatting)
    private var effectiveDisplayName: String {
        if !displayName.isEmpty { return displayName }
        let parts = [prefix, firstName, middleName, lastName, suffix].filter { !$0.isEmpty }
        return parts.joined(separator: " ")
    }
    
    /// Formatted name for display with special formatting
    private var formattedDisplayName: String {
        if !displayName.isEmpty { return displayName }
        
        var parts: [String] = []
        
        if !prefix.isEmpty { parts.append(prefix) }
        if !firstName.isEmpty { parts.append(firstName) }
        if !preferredName.isEmpty { parts.append("\"\(preferredName)\"") }
        if !middleName.isEmpty { parts.append(middleName) }
        if !lastName.isEmpty { parts.append(lastName) }
        if !suffix.isEmpty { parts.append(suffix) }
        if !maidenName.isEmpty { parts.append("(\(maidenName))") }
        if !pronouns.isEmpty { parts.append("(\(pronouns))") }
        
        return parts.joined(separator: " ")
    }
    
    var body: some View {
        NavigationStack {
            Form {
                // Default card toggle
                Section {
                    Toggle(isOn: $isDefault) {
                        Label(String.localized("Default Card"), systemImage: "checkmark.seal.fill")
                    }
                } footer: {
                    Text("The default card is used for sharing and widgets.")
                }
                
                // Card Style section
                Section {
                    CardStylePicker(selectedTheme: $selectedTheme)
                }
                
                // Images & Layout section
                Section {
                    ImageLayoutRow(
                        photoData: $photoData,
                        coverPhotoData: $coverPhotoData,
                        logoData: $logoData,
                        avatarSystemName: avatarSystemName,
                        selectedTheme: selectedTheme,
                        onSelectImage: { imageType in
                            editingImageType = imageType
                        }
                    )
                } header: {
                    Text("Images & layout")
                }
                
                // Personal details section
                Section {
                    // Name row with expand button
                    Button {
                        withAnimation { showNameDetails.toggle() }
                    } label: {
                        HStack {
                            Text(formattedDisplayName.isEmpty ? "Full Name" : formattedDisplayName)
                                .foregroundStyle(formattedDisplayName.isEmpty ? Color.secondary : Color.primary)
                            Spacer()
                            Image(systemName: showNameDetails ? "chevron.up" : "chevron.down")
                                .foregroundStyle(Color.accentColor)
                        }
                    }
                    .tint(.primary)
                    
                    if showNameDetails {
                        TextField("Prefix (e.g. Dr., Mr., Ms.)", text: $prefix)
                        TextField("First Name", text: $firstName)
                        TextField("Middle Name", text: $middleName)
                        TextField("Last Name", text: $lastName)
                        TextField("Suffix (e.g. Jr., III)", text: $suffix)
                        TextField("Maiden Name", text: $maidenName)
                        TextField("Preferred Name", text: $preferredName)
                        TextField("Pronouns (e.g. she/her)", text: $pronouns)
                    }
                } header: {
                    Text("Personal details")
                }
                
                // Professional section
                Section {
                    TextField("Job Title", text: $role)
                    TextField("Department", text: $department)
                    TextField("Company", text: $company)
                    TextField("Headline", text: $headline)
                }
                
                // Accreditations
                Section {
                    AccreditationsRow(accreditations: $accreditations)
                } header: {
                    Text("Accreditations")
                }
                
                // Card Label
                Section {
                    Picker("Card Label", selection: $label) {
                        ForEach(["Work", "Personal", "Creative", "Other"], id: \.self) { option in
                            Text(option).tag(option)
                        }
                    }
                    .pickerStyle(.segmented)
                } header: {
                    Text("Card Label")
                }
                
                // Contact & social fields manager
                Section {
                    ContactFieldsManagerView(fields: $contactFields)
                } header: {
                    Text("Contact Fields")
                }
                
                // Bio section
                Section {
                    TextField("Tell people about yourself...", text: $bio, axis: .vertical)
                        .lineLimit(3...8)
                } header: {
                    Text("About")
                }
            }
            .safeAreaInset(edge: .bottom) {
                PreviewCardButton { showingPreview = true }
            }
            .navigationTitle(isEditing ? String.localized("Edit Card") : String.localized("New Card"))
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button(String.localized("Cancel")) { dismiss() }
                }
                ToolbarItem(placement: .confirmationAction) {
                    Button(String.localized("Save")) { saveCard() }
                        .bold()
                        .disabled(!isFormValid)
                }
            }
            .sheet(item: $editingImageType) { imageType in
                ImageEditorFlow(
                    imageType: imageType,
                    hasExistingImage: hasExistingPhoto(for: imageType)
                ) { imageData in
                    if let imageData {
                        if imageData.isEmpty {
                            // Empty data = remove photo
                            removePhoto(for: imageType)
                        } else {
                            // Save the cropped image
                            savePhoto(imageData, for: imageType)
                        }
                    }
                    // nil = cancelled, do nothing
                    editingImageType = nil
                }
            }
            .onAppear { loadCardData() }
            .sheet(isPresented: $showingPreview) {
                CardPreviewSheet(card: buildPreviewCard())
            }
        }
    }
}

// MARK: - Card Style Picker

private struct CardStylePicker: View {
    @Binding var selectedTheme: CardTheme
    
    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: Design.Spacing.medium) {
                ForEach(CardTheme.all) { theme in
                    Button {
                        selectedTheme = theme
                    } label: {
                        Circle()
                            .fill(theme.primaryColor)
                            .frame(width: Design.CardSize.colorSwatchSize, height: Design.CardSize.colorSwatchSize)
                            .overlay(
                                Circle()
                                    .stroke(selectedTheme == theme ? Color.primary : .clear, lineWidth: Design.LineWidth.medium)
                                    .padding(Design.Spacing.xxSmall)
                            )
                    }
                    .buttonStyle(.plain)
                    .accessibilityLabel(theme.name)
                    .accessibilityAddTraits(selectedTheme == theme ? .isSelected : [])
                }
            }
        }
    }
}

// MARK: - Image Layout Row

private struct ImageLayoutRow: View {
    @Binding var photoData: Data?
    @Binding var coverPhotoData: Data?
    @Binding var logoData: Data?
    let avatarSystemName: String
    let selectedTheme: CardTheme
    let onSelectImage: (CardEditorView.ImageType) -> Void
    
    var body: some View {
        VStack(alignment: .leading, spacing: Design.Spacing.medium) {
            // Card preview with edit buttons
            ZStack(alignment: .bottomLeading) {
                // Banner with cover photo or gradient
                BannerPreviewView(
                    coverPhotoData: coverPhotoData,
                    logoData: logoData,
                    selectedTheme: selectedTheme,
                    onEditCover: { onSelectImage(.cover) },
                    onEditLogo: { onSelectImage(.logo) }
                )
                
                // Profile photo with edit button
                ZStack(alignment: .bottomTrailing) {
                    ProfilePhotoView(photoData: photoData, avatarSystemName: avatarSystemName, theme: selectedTheme)
                    
                    Button {
                        onSelectImage(.profile)
                    } label: {
                        Image(systemName: "pencil")
                            .font(.caption2)
                            .padding(Design.Spacing.xSmall)
                            .background(.ultraThinMaterial)
                            .clipShape(.circle)
                    }
                    .buttonStyle(.plain)
                }
                .offset(x: Design.Spacing.large, y: Design.CardSize.avatarOverlap)
            }
            .padding(.bottom, Design.CardSize.avatarOverlap)
            
            // Photo action buttons
            ImageActionButtonsRow(
                photoData: $photoData,
                coverPhotoData: $coverPhotoData,
                logoData: $logoData,
                onSelectImage: onSelectImage
            )
        }
    }
}

// MARK: - Banner Preview View

private struct BannerPreviewView: View {
    let coverPhotoData: Data?
    let logoData: Data?
    let selectedTheme: CardTheme
    let onEditCover: () -> Void
    let onEditLogo: () -> Void
    
    var body: some View {
                ZStack {
            // Background: cover photo or gradient
            if let coverPhotoData, let uiImage = UIImage(data: coverPhotoData) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFill()
                    .frame(height: Design.CardSize.bannerHeight)
                    .clipped()
            } else {
                    LinearGradient(
                        colors: [selectedTheme.primaryColor, selectedTheme.secondaryColor],
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    )
            }
                    
            // Company logo overlay
                        if let logoData, let uiImage = UIImage(data: logoData) {
                            Image(uiImage: uiImage)
                                .resizable()
                                .scaledToFit()
                                .frame(height: Design.CardSize.logoSize)
                        }
                        
            // Edit buttons overlay
                        VStack {
                            HStack {
                    // Edit cover photo button (top-left)
                    Button(action: onEditCover) {
                        Image(systemName: "photo")
                            .font(.caption)
                            .padding(Design.Spacing.small)
                            .background(.ultraThinMaterial)
                            .clipShape(.circle)
                    }
                    .buttonStyle(.plain)
                    .accessibilityLabel(String.localized("Edit cover photo"))
                    
                                Spacer()
                    
                    // Edit logo button (top-right)
                    Button(action: onEditLogo) {
                        Image(systemName: "building.2")
                                        .font(.caption)
                                        .padding(Design.Spacing.small)
                                        .background(.ultraThinMaterial)
                                        .clipShape(.circle)
                                }
                                .buttonStyle(.plain)
                    .accessibilityLabel(String.localized("Edit company logo"))
                            }
                            Spacer()
                        }
                        .padding(Design.Spacing.small)
                }
                .frame(height: Design.CardSize.bannerHeight)
                .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
    }
}

// MARK: - Image Action Buttons Row

private struct ImageActionButtonsRow: View {
    @Binding var photoData: Data?
    @Binding var coverPhotoData: Data?
    @Binding var logoData: Data?
    let onSelectImage: (CardEditorView.ImageType) -> Void
    
    var body: some View {
        VStack(alignment: .leading, spacing: Design.Spacing.small) {
            // Profile photo action
            ImageActionRow(
                title: String.localized("Profile Photo"),
                subtitle: photoData == nil ? String.localized("Add your headshot") : String.localized("Change or remove"),
                systemImage: "person.crop.circle",
                hasImage: photoData != nil,
                onTap: { onSelectImage(.profile) },
                onRemove: { photoData = nil }
            )
            
            // Cover photo action
            ImageActionRow(
                title: String.localized("Cover Photo"),
                subtitle: coverPhotoData == nil ? String.localized("Add banner background") : String.localized("Change or remove"),
                systemImage: "photo.fill",
                hasImage: coverPhotoData != nil,
                onTap: { onSelectImage(.cover) },
                onRemove: { coverPhotoData = nil }
            )
            
            // Company logo action
            ImageActionRow(
                title: String.localized("Company Logo"),
                subtitle: logoData == nil ? String.localized("Add your logo") : String.localized("Change or remove"),
                systemImage: "building.2",
                hasImage: logoData != nil,
                onTap: { onSelectImage(.logo) },
                onRemove: { logoData = nil }
            )
        }
    }
}

// MARK: - Image Action Row

private struct ImageActionRow: View {
    let title: String
    let subtitle: String
    let systemImage: String
    let hasImage: Bool
    let onTap: () -> Void
    let onRemove: () -> Void
    
    var body: some View {
        Button(action: onTap) {
            HStack(spacing: Design.Spacing.medium) {
                Image(systemName: systemImage)
                    .font(.title3)
                    .foregroundStyle(hasImage ? Color.accentColor : Color.Text.secondary)
                    .frame(width: Design.CardSize.socialIconSize)
                
                VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) {
                    Text(title)
                        .font(.subheadline)
                        .foregroundStyle(Color.Text.primary)
                    
                    Text(subtitle)
                        .font(.caption)
                        .foregroundStyle(Color.Text.secondary)
                }
                
                Spacer()
                
                Image(systemName: "chevron.right")
                    .font(.caption)
                    .foregroundStyle(Color.Text.tertiary)
            }
            .padding(.vertical, Design.Spacing.xSmall)
            .contentShape(.rect)
                }
                .buttonStyle(.plain)
        .accessibilityLabel("\(title): \(subtitle)")
        .contextMenu {
            if hasImage {
                Button(role: .destructive) {
                    onRemove()
                } label: {
                    Label(String.localized("Remove"), systemImage: "trash")
                }
            }
        }
    }
}

private struct ProfilePhotoView: View {
    let photoData: Data?
    let avatarSystemName: String
    let theme: CardTheme
    
    var body: some View {
        Group {
            if let photoData, let uiImage = UIImage(data: photoData) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFill()
            } else {
                Image(systemName: avatarSystemName)
                    .font(.title)
                    .foregroundStyle(theme.textColor)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(theme.accentColor)
            }
        }
        .frame(width: Design.CardSize.avatarLarge, height: Design.CardSize.avatarLarge)
        .clipShape(.circle)
        .overlay(Circle().stroke(Color.AppBackground.elevated, lineWidth: Design.LineWidth.thick))
    }
}

// MARK: - Accreditations Row

private struct AccreditationsRow: View {
    @Binding var accreditations: String
    @State private var accreditationInput = ""
    
    private var accreditationsList: [String] {
        accreditations.split(separator: ",")
            .map { $0.trimmingCharacters(in: .whitespaces) }
            .filter { !$0.isEmpty }
    }
    
    var body: some View {
        VStack(alignment: .leading, spacing: Design.Spacing.small) {
            // Input row
            HStack {
                TextField("e.g. MBA, CPA, PhD", text: $accreditationInput)
                
                Button {
                    addAccreditation()
                } label: {
                    Image(systemName: "plus.circle.fill")
                        .font(.title2)
                        .foregroundStyle(Color.accentColor)
                }
                .buttonStyle(.plain)
                .disabled(accreditationInput.trimmingCharacters(in: .whitespaces).isEmpty)
            }
            
            // Tag bubbles
            if !accreditationsList.isEmpty {
                ScrollView(.horizontal, showsIndicators: false) {
                    HStack(spacing: Design.Spacing.small) {
                        ForEach(accreditationsList, id: \.self) { tag in
                            HStack(spacing: Design.Spacing.xSmall) {
                                Text(tag)
                                    .font(.subheadline)
                                Button {
                                    removeAccreditation(tag)
                                } label: {
                                    Image(systemName: "xmark.circle.fill")
                                        .font(.caption)
                                        .foregroundStyle(Color.secondary)
                                }
                                .buttonStyle(.plain)
                            }
                            .padding(.horizontal, Design.Spacing.small)
                            .padding(.vertical, Design.Spacing.xSmall)
                            .background(Color.secondary.opacity(Design.Opacity.subtle))
                            .clipShape(.capsule)
                        }
                    }
                }
            }
        }
    }
    
    private func addAccreditation() {
        let trimmed = accreditationInput.trimmingCharacters(in: .whitespaces)
        guard !trimmed.isEmpty else { return }
        
        var list = accreditationsList
        list.append(trimmed)
        accreditations = list.joined(separator: ", ")
        accreditationInput = ""
    }
    
    private func removeAccreditation(_ tag: String) {
        var list = accreditationsList
        list.removeAll { $0 == tag }
        accreditations = list.joined(separator: ", ")
    }
}

// MARK: - Supporting Views

private struct PreviewCardButton: View {
    let action: () -> Void
    
    var body: some View {
        Button(action: action) {
            Text("Preview card")
                .font(.headline)
                .foregroundStyle(.white)
                .frame(maxWidth: .infinity)
                .padding(Design.Spacing.medium)
                .background(Color.Text.primary)
                .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
        }
        .padding(.horizontal, Design.Spacing.large)
        .padding(.vertical, Design.Spacing.medium)
        .background(.ultraThinMaterial)
    }
}

private struct CardPreviewSheet: View {
    let card: BusinessCard
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        NavigationStack {
            ScrollView {
                BusinessCardView(card: card)
                    .padding(Design.Spacing.large)
            }
            .background(Color.AppBackground.base)
            .navigationTitle(String.localized("Preview"))
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .confirmationAction) {
                    Button(String.localized("Done")) { dismiss() }
                }
            }
        }
    }
}

// MARK: - Data Operations

private extension CardEditorView {
    func loadCardData() {
        guard let card else { return }
        displayName = card.displayName
        prefix = card.prefix
        firstName = card.firstName
        middleName = card.middleName
        lastName = card.lastName
        suffix = card.suffix
        maidenName = card.maidenName
        preferredName = card.preferredName
        pronouns = card.pronouns
        role = card.role
        department = card.department
        company = card.company
        headline = card.headline
        label = card.label
        bio = card.bio
        accreditations = card.accreditations
        avatarSystemName = card.avatarSystemName
        isDefault = card.isDefault
        
        // Load contact fields from the array
        contactFields = card.orderedContactFields.compactMap { $0.toAddedContactField() }
        selectedTheme = card.theme
        selectedLayout = card.layoutStyle
        photoData = card.photoData
        coverPhotoData = card.coverPhotoData
        logoData = card.logoData
    }
    
    // MARK: - Photo Helpers
    
    func hasExistingPhoto(for imageType: ImageType?) -> Bool {
        guard let imageType else { return false }
        switch imageType {
        case .profile: return photoData != nil
        case .cover: return coverPhotoData != nil
        case .logo: return logoData != nil
        }
    }
    
    func removePhoto(for imageType: ImageType?) {
        guard let imageType else { return }
        switch imageType {
        case .profile: photoData = nil
        case .cover: coverPhotoData = nil
        case .logo: logoData = nil
        }
    }
    
    func savePhoto(_ data: Data, for imageType: ImageType) {
        switch imageType {
        case .profile: photoData = data
        case .cover: coverPhotoData = data
        case .logo: logoData = data
        }
    }
    
    func saveCard() {
        if let existingCard = card {
            updateCard(existingCard)
            onSave(existingCard)
            
            // Handle default card toggle
            if isDefault {
                appState.cardStore.setDefaultCard(existingCard)
            }
        } else {
            let newCard = createCard()
            onSave(newCard)
            
            // Handle default card toggle for new cards
            if isDefault {
                appState.cardStore.setDefaultCard(newCard)
            }
        }
        dismiss()
    }
    
    func updateCard(_ card: BusinessCard) {
        card.displayName = displayName.isEmpty ? effectiveDisplayName : displayName
        card.prefix = prefix
        card.firstName = firstName
        card.middleName = middleName
        card.lastName = lastName
        card.suffix = suffix
        card.maidenName = maidenName
        card.preferredName = preferredName
        card.pronouns = pronouns
        card.role = role
        card.department = department
        card.company = company
        card.headline = headline
        card.label = label
        card.bio = bio
        card.accreditations = accreditations
        card.avatarSystemName = avatarSystemName
        card.theme = selectedTheme
        card.layoutStyle = selectedLayout
        card.photoData = photoData
        card.coverPhotoData = coverPhotoData
        card.logoData = logoData
        
        // Save contact fields to the model's array
        saveContactFieldsToCard(card)
    }
    
    func createCard() -> BusinessCard {
        let newCard = BusinessCard(
            displayName: displayName.isEmpty ? effectiveDisplayName : displayName,
            role: role,
            company: company,
            label: label,
            isDefault: false,
            themeName: selectedTheme.name,
            layoutStyleRawValue: selectedLayout.rawValue,
            avatarSystemName: avatarSystemName,
            prefix: prefix,
            firstName: firstName,
            middleName: middleName,
            lastName: lastName,
            suffix: suffix,
            maidenName: maidenName,
            preferredName: preferredName,
            pronouns: pronouns,
            department: department,
            headline: headline,
            bio: bio,
            accreditations: accreditations,
            photoData: photoData,
            coverPhotoData: coverPhotoData,
            logoData: logoData
        )
        
        // Save contact fields to the model's array
        saveContactFieldsToCard(newCard)
        
        return newCard
    }
    
    func buildPreviewCard() -> BusinessCard {
        let previewCard = BusinessCard(
            displayName: displayName.isEmpty ? effectiveDisplayName : displayName,
            role: role,
            company: company,
            label: label,
            isDefault: false,
            themeName: selectedTheme.name,
            layoutStyleRawValue: selectedLayout.rawValue,
            avatarSystemName: avatarSystemName,
            prefix: prefix,
            firstName: firstName,
            middleName: middleName,
            lastName: lastName,
            suffix: suffix,
            maidenName: maidenName,
            preferredName: preferredName,
            pronouns: pronouns,
            department: department,
            headline: headline,
            bio: bio,
            accreditations: accreditations,
            photoData: photoData,
            coverPhotoData: coverPhotoData,
            logoData: logoData
        )
        
        // Add contact fields to preview card
        for (index, field) in contactFields.enumerated() {
            let contactField = ContactField(
                typeId: field.fieldType.id,
                value: field.value,
                title: field.title,
                orderIndex: index
            )
            if previewCard.contactFields == nil {
                previewCard.contactFields = []
            }
            previewCard.contactFields?.append(contactField)
        }
        
        return previewCard
    }
    
    // MARK: - Contact Fields Sync
    
    /// Saves the contactFields array to the BusinessCard model
    func saveContactFieldsToCard(_ card: BusinessCard) {
        // Clear existing contact fields
        card.contactFields?.removeAll()
        
        // Add new fields from the UI array
        for (index, addedField) in contactFields.enumerated() {
            let value = addedField.value.trimmingCharacters(in: .whitespacesAndNewlines)
            guard !value.isEmpty else { continue }
            
            let field = ContactField(
                typeId: addedField.fieldType.id,
                value: value,
                title: addedField.title,
                orderIndex: index
            )
            field.card = card
            if card.contactFields == nil {
                card.contactFields = []
            }
            card.contactFields?.append(field)
        }
    }
}

// MARK: - Preview

#Preview("New Card") {
    let container = try! ModelContainer(for: BusinessCard.self, Contact.self)
    return CardEditorView(card: nil) { _ in }
        .environment(AppState(modelContext: container.mainContext))
}
