import SwiftUI
import Bedrock
import SwiftData
import PhotosUI

struct ContactDetailView: View {
    @Environment(AppState.self) private var appState
    @Environment(\.dismiss) private var dismiss
    
    @Bindable var contact: Contact
    
    @State private var showingDeleteConfirmation = false
    @State private var showingMoreActions = false
    @State private var showingAddTag = false
    @State private var showingAddNote = false
    @State private var newTag = ""
    
    // Photo picker state
    @State private var showingPhotoSourcePicker = false
    @State private var showingPhotoPicker = false
    @State private var showingCamera = false
    @State private var pendingAction: PendingPhotoAction?
    
    private enum PendingPhotoAction {
        case library
        case camera
    }
    
    var body: some View {
        ZStack(alignment: .bottom) {
            ScrollView {
                VStack(spacing: 0) {
                    // Header banner with photo
                    ContactBannerView(
                        contact: contact,
                        onEditPhoto: { showingPhotoSourcePicker = true }
                    )
                    
                    // Content
                    VStack(alignment: .leading, spacing: Design.Spacing.large) {
                        // Name
                        Text(contact.name.isEmpty ? String.localized("Contact") : contact.name)
                            .font(.largeTitle)
                            .bold()
                            .foregroundStyle(Color.Text.primary)
                        
                        // Connection details
                        VStack(alignment: .leading, spacing: Design.Spacing.small) {
                            Text("Connection details")
                                .font(.subheadline)
                                .foregroundStyle(Color.Text.tertiary)
                            
                            HStack(spacing: Design.Spacing.small) {
                                Image(systemName: "calendar")
                                    .foregroundStyle(Color.Text.primary)
                                Text(contact.lastSharedDate, format: .dateTime.day().month().year().hour().minute())
                                    .font(.subheadline)
                                    .foregroundStyle(Color.Text.primary)
                            }
                        }
                        
                        // Tags
                        HStack(spacing: Design.Spacing.small) {
                            ForEach(contact.tagList, id: \.self) { tag in
                                TagPill(text: tag, onDelete: {
                                    removeTag(tag)
                                })
                            }
                            
                            Button {
                                showingAddTag = true
                            } label: {
                                Label(String.localized("Add tag"), systemImage: "plus")
                                    .font(.subheadline)
                                    .bold()
                                    .foregroundStyle(Color.AppText.inverted)
                                    .padding(.horizontal, Design.Spacing.medium)
                                    .padding(.vertical, Design.Spacing.small)
                                    .background(Color.Text.primary)
                                    .clipShape(.capsule)
                            }
                        }
                        
                        // Contact info card - shows both legacy fields and new contact fields
                        ContactInfoCard(contact: contact, openURL: openURL)
                        
                        // Notes section
                        VStack(alignment: .leading, spacing: Design.Spacing.medium) {
                            Text("Notes")
                                .font(.headline)
                                .bold()
                                .foregroundStyle(Color.Text.primary)
                            
                            if contact.notes.isEmpty {
                                NotesEmptyState()
                            } else {
                                Text(contact.notes)
                                    .font(.body)
                                    .foregroundStyle(Color.Text.secondary)
                                    .frame(maxWidth: .infinity, alignment: .leading)
                                    .padding(Design.Spacing.medium)
                                    .background(Color.AppBackground.card)
                                    .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
                            }
                            
                            Button {
                                showingAddNote = true
                            } label: {
                                Label(String.localized("Add note"), systemImage: "plus")
                                    .font(.subheadline)
                                    .foregroundStyle(Color.Text.primary)
                                    .frame(maxWidth: .infinity)
                                    .padding(.vertical, Design.Spacing.medium)
                                    .background(Color.AppBackground.card)
                                    .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
                                    .overlay(
                                        RoundedRectangle(cornerRadius: Design.CornerRadius.large)
                                            .stroke(Color.Text.tertiary.opacity(Design.Opacity.light), lineWidth: Design.LineWidth.thin)
                                    )
                            }
                        }
                        .padding(.top, Design.Spacing.medium)
                        
                        // Spacer for bottom bar
                        Spacer()
                            .frame(height: Design.Spacing.xLarge * 4)
                    }
                    .padding(.horizontal, Design.Spacing.large)
                    .padding(.top, Design.Spacing.large)
                }
            }
            .background(Color.AppBackground.secondary)
            .ignoresSafeArea(edges: .top)
            
            // Bottom action bar
            BottomActionBar(
                onMore: { showingMoreActions = true },
                onAddTag: { showingAddTag = true },
                onAddNote: { showingAddNote = true }
            )
        }
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button {
                    // Edit action - could navigate to edit mode
                } label: {
                    Image(systemName: "square.and.pencil")
                        .foregroundStyle(Color.AppText.inverted)
                }
            }
        }
        .toolbarBackground(.hidden, for: .navigationBar)
        .confirmationDialog(String.localized("More"), isPresented: $showingMoreActions) {
            Button(String.localized("Download contact")) {
                // Download action
            }
            Button(String.localized("Share contact")) {
                // Share action
            }
            Button(String.localized("Delete Contact"), role: .destructive) {
                showingDeleteConfirmation = true
            }
            Button(String.localized("Cancel"), role: .cancel) { }
        }
        .alert(String.localized("Delete Contact"), isPresented: $showingDeleteConfirmation) {
            Button(String.localized("Cancel"), role: .cancel) { }
            Button(String.localized("Delete"), role: .destructive) {
                appState.contactsStore.deleteContact(contact)
                dismiss()
            }
        } message: {
            Text("Are you sure you want to delete this contact?")
        }
        .alert(String.localized("Add Tag"), isPresented: $showingAddTag) {
            TextField(String.localized("Tag name"), text: $newTag)
            Button(String.localized("Cancel"), role: .cancel) {
                newTag = ""
            }
            Button(String.localized("Add")) {
                addTag()
            }
        }
        .sheet(isPresented: $showingAddNote) {
            AddNoteSheet(notes: $contact.notes)
        }
        .sheet(isPresented: $showingPhotoSourcePicker, onDismiss: {
            guard let action = pendingAction else { return }
            pendingAction = nil
            
            Task { @MainActor in
                try? await Task.sleep(for: .milliseconds(100))
                switch action {
                case .library:
                    showingPhotoPicker = true
                case .camera:
                    showingCamera = true
                }
            }
        }) {
            PhotoSourcePicker(
                title: String.localized("Add profile picture"),
                hasExistingPhoto: contact.photoData != nil,
                onSelectFromLibrary: {
                    pendingAction = .library
                },
                onTakePhoto: {
                    pendingAction = .camera
                },
                onRemovePhoto: {
                    contact.photoData = nil
                }
            )
        }
        .fullScreenCover(isPresented: $showingPhotoPicker) {
            NavigationStack {
                PhotoPickerWithCropper(
                    onSave: { croppedData in
                        contact.photoData = croppedData
                        showingPhotoPicker = false
                    },
                    onCancel: {
                        showingPhotoPicker = false
                    }
                )
            }
        }
        .fullScreenCover(isPresented: $showingCamera) {
            CameraWithCropper(
                onSave: { croppedData in
                    contact.photoData = croppedData
                    showingCamera = false
                },
                onCancel: {
                    showingCamera = false
                }
            )
        }
    }
    
    private func openURL(_ urlString: String) {
        guard let url = URL(string: urlString) else { return }
        UIApplication.shared.open(url)
    }
    
    private func addTag() {
        let tag = newTag.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !tag.isEmpty else { return }
        
        if contact.tags.isEmpty {
            contact.tags = tag
        } else {
            contact.tags += ", \(tag)"
        }
        newTag = ""
    }
    
    private func removeTag(_ tag: String) {
        var tags = contact.tagList
        tags.removeAll { $0 == tag }
        contact.tags = tags.joined(separator: ", ")
    }
}

// MARK: - Banner View

private struct ContactBannerView: View {
    let contact: Contact
    let onEditPhoto: () -> Void
    
    private var initials: String {
        let parts = contact.name.split(separator: " ")
        if parts.count >= 2 {
            return "\(parts[0].prefix(1))\(parts[1].prefix(1))".uppercased()
        } else if let first = parts.first {
            return String(first.prefix(2)).uppercased()
        }
        return "?"
    }
    
    var body: some View {
        ZStack {
            // Background: photo or gradient
            if let photoData = contact.photoData, let uiImage = UIImage(data: photoData) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFill()
                    .frame(height: Design.CardSize.bannerHeight * 1.5)
                    .clipped()
                    .overlay(
                        LinearGradient(
                            colors: [.clear, .black.opacity(Design.Opacity.light)],
                            startPoint: .top,
                            endPoint: .bottom
                        )
                    )
            } else {
            // Gradient background
            LinearGradient(
                colors: [
                    Color.CardPalette.coral,
                    Color.CardPalette.coral.opacity(Design.Opacity.strong)
                ],
                startPoint: .top,
                endPoint: .bottom
            )
            
            // Decorative circles
            Circle()
                .fill(Color.white.opacity(Design.Opacity.subtle))
                .frame(width: Design.CardSize.qrSize, height: Design.CardSize.qrSize)
                .offset(y: -Design.Spacing.xLarge)
            
            // Initials
            VStack(spacing: Design.Spacing.xxSmall) {
                Text(String(initials.prefix(1)))
                    .font(.system(size: Design.BaseFontSize.display, weight: .light))
                Text(String(initials.dropFirst().prefix(1)))
                    .font(.system(size: Design.BaseFontSize.display, weight: .light))
            }
            .foregroundStyle(Color.white.opacity(Design.Opacity.accent))
            }
            
            // Edit photo button
            VStack {
                HStack {
                    Spacer()
                    Button(action: onEditPhoto) {
                        Image(systemName: contact.photoData == nil ? "camera.fill" : "pencil")
                            .font(.body)
                            .foregroundStyle(.white)
                            .padding(Design.Spacing.medium)
                            .background(.ultraThinMaterial)
                            .clipShape(.circle)
                    }
                    .buttonStyle(.plain)
                    .accessibilityLabel(contact.photoData == nil ? String.localized("Add photo") : String.localized("Change photo"))
                }
                .padding(Design.Spacing.large)
                .padding(.top, Design.Spacing.xLarge)
                Spacer()
            }
        }
        .frame(height: Design.CardSize.bannerHeight * 1.5)
    }
}

// MARK: - Tag Pill

private struct TagPill: View {
    let text: String
    let onDelete: () -> Void
    
    var body: some View {
        HStack(spacing: Design.Spacing.xSmall) {
            Text(text)
                .font(.subheadline)
            Button {
                onDelete()
            } label: {
                Image(systemName: "xmark")
                    .font(.caption2)
            }
        }
        .foregroundStyle(Color.Text.primary)
        .padding(.horizontal, Design.Spacing.medium)
        .padding(.vertical, Design.Spacing.small)
        .background(Color.AppBackground.card)
        .clipShape(.capsule)
        .overlay(
            Capsule()
                .stroke(Color.Text.tertiary.opacity(Design.Opacity.light), lineWidth: Design.LineWidth.thin)
        )
    }
}

// MARK: - Contact Info Card

private struct ContactInfoCard: View {
    let contact: Contact
    let openURL: (String) -> Void
    
    private var allContactFields: [ContactField] {
        var fields: [ContactField] = []
        
        // Add phones
        fields.append(contentsOf: contact.phoneNumbers)
        
        // Add emails
        fields.append(contentsOf: contact.emailAddresses)
        
        // Add addresses
        fields.append(contentsOf: contact.addresses)
        
        // Add links
        fields.append(contentsOf: contact.links)
        
        return fields
    }
    
    private var hasLegacyFields: Bool {
        !contact.phone.isEmpty || !contact.email.isEmpty
    }
    
    var body: some View {
        if !allContactFields.isEmpty || hasLegacyFields {
            VStack(spacing: 0) {
                // New contact fields
                ForEach(allContactFields.indices, id: \.self) { index in
                    let field = allContactFields[index]
                    ContactFieldInfoRow(field: field, openURL: openURL)
                    
                    if index < allContactFields.count - 1 || hasLegacyFields {
                        Divider()
                            .padding(.leading, Design.Spacing.xLarge + Design.CardSize.avatarSize)
                    }
                }
                
                // Legacy fallback: show legacy email/phone if no new fields of that type
                if contact.phoneNumbers.isEmpty && !contact.phone.isEmpty {
                    ContactInfoRow(
                        icon: "phone.fill",
                        value: contact.phone,
                        label: "Cell",
                        action: { openURL("tel:\(contact.phone)") }
                    )
                    
                    if !contact.email.isEmpty && contact.emailAddresses.isEmpty {
                        Divider()
                            .padding(.leading, Design.Spacing.xLarge + Design.CardSize.avatarSize)
                    }
                }
                
                if contact.emailAddresses.isEmpty && !contact.email.isEmpty {
                    ContactInfoRow(
                        icon: "envelope.fill",
                        value: contact.email,
                        label: "Email",
                        action: { openURL("mailto:\(contact.email)") }
                    )
                }
            }
            .background(Color.AppBackground.card)
            .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
        }
    }
}

// MARK: - Contact Field Info Row

private struct ContactFieldInfoRow: View {
    let field: ContactField
    let openURL: (String) -> Void
    
    var body: some View {
        Button {
            if let url = field.buildURL() {
                UIApplication.shared.open(url)
            }
        } label: {
            HStack(alignment: .top, spacing: Design.Spacing.medium) {
                // Icon circle
                field.iconImage()
                    .font(.body)
                    .foregroundStyle(Color.white)
                    .frame(width: Design.CardSize.avatarSize, height: Design.CardSize.avatarSize)
                    .background(Color.CardPalette.coral)
                    .clipShape(.circle)
                
                // Text
                VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) {
                    Text(field.displayValue)
                        .font(.body)
                        .foregroundStyle(Color.Text.primary)
                        .multilineTextAlignment(.leading)
                    
                    Text(field.title.isEmpty ? field.displayName : field.title)
                        .font(.caption)
                        .foregroundStyle(Color.Text.tertiary)
                }
                
                Spacer()
            }
            .padding(Design.Spacing.medium)
        }
        .buttonStyle(.plain)
    }
}

// MARK: - Contact Info Row

private struct ContactInfoRow: View {
    let icon: String
    let value: String
    let label: String
    let action: () -> Void
    
    var body: some View {
        Button(action: action) {
            HStack(spacing: Design.Spacing.medium) {
                // Icon circle
                Image(systemName: icon)
                    .font(.body)
                    .foregroundStyle(Color.white)
                    .frame(width: Design.CardSize.avatarSize, height: Design.CardSize.avatarSize)
                    .background(Color.CardPalette.coral)
                    .clipShape(.circle)
                
                // Text
                VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) {
                    Text(value)
                        .font(.body)
                        .foregroundStyle(Color.Text.primary)
                    Text(label)
                        .font(.caption)
                        .foregroundStyle(Color.Text.tertiary)
                }
                
                Spacer()
            }
            .padding(Design.Spacing.medium)
        }
        .buttonStyle(.plain)
    }
}

// MARK: - Notes Empty State

private struct NotesEmptyState: View {
    var body: some View {
        VStack(spacing: Design.Spacing.medium) {
            Image(systemName: "note.text")
                .font(.system(size: Design.BaseFontSize.display))
                .foregroundStyle(Color.CardPalette.coral.opacity(Design.Opacity.medium))
            
            Text("Write down a memorable reminder about your contact")
                .font(.subheadline)
                .foregroundStyle(Color.Text.tertiary)
                .multilineTextAlignment(.center)
        }
        .frame(maxWidth: .infinity)
        .padding(.vertical, Design.Spacing.xLarge)
        .background(Color.AppBackground.card)
        .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
    }
}

// MARK: - Bottom Action Bar

private struct BottomActionBar: View {
    let onMore: () -> Void
    let onAddTag: () -> Void
    let onAddNote: () -> Void
    
    var body: some View {
        HStack(spacing: Design.Spacing.medium) {
            Button(action: onMore) {
                Text("More...")
                    .font(.subheadline)
                    .bold()
                    .foregroundStyle(Color.Text.primary)
                    .frame(maxWidth: .infinity)
                    .padding(.vertical, Design.Spacing.medium)
                    .background(Color.AppBackground.card)
                    .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
            }
            
            Button(action: onAddTag) {
                Text("Add tag")
                    .font(.subheadline)
                    .bold()
                    .foregroundStyle(Color.AppText.inverted)
                    .frame(maxWidth: .infinity)
                    .padding(.vertical, Design.Spacing.medium)
                    .background(Color.Text.primary)
                    .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
            }
            
            Button(action: onAddNote) {
                Text("Add note")
                    .font(.subheadline)
                    .bold()
                    .foregroundStyle(Color.AppText.inverted)
                    .frame(maxWidth: .infinity)
                    .padding(.vertical, Design.Spacing.medium)
                    .background(Color.Text.primary)
                    .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
            }
        }
        .padding(.horizontal, Design.Spacing.large)
        .padding(.vertical, Design.Spacing.medium)
        .background(Color.AppBackground.secondary)
    }
}

// MARK: - Add Note Sheet

private struct AddNoteSheet: View {
    @Environment(\.dismiss) private var dismiss
    @Binding var notes: String
    @State private var editedNotes: String = ""
    
    var body: some View {
        NavigationStack {
            TextEditor(text: $editedNotes)
                .padding(Design.Spacing.medium)
                .navigationTitle(String.localized("Notes"))
                .navigationBarTitleDisplayMode(.inline)
                .toolbar {
                    ToolbarItem(placement: .cancellationAction) {
                        Button(String.localized("Cancel")) {
                            dismiss()
                        }
                    }
                    ToolbarItem(placement: .confirmationAction) {
                        Button(String.localized("Save")) {
                            notes = editedNotes
                            dismiss()
                        }
                        .bold()
                    }
                }
                .onAppear {
                    editedNotes = notes
                }
        }
    }
}

#Preview {
    NavigationStack {
        ContactDetailView(
            contact: Contact(
                name: "Heidi Bruce",
                role: "Designer",
                company: "Apple",
                notes: "",
                tags: "",
                email: "heidi.h.bruce@gmail.com",
                phone: "2145328862"
            )
        )
        .environment(AppState(modelContext: try! ModelContainer(for: BusinessCard.self, Contact.self).mainContext))
    }
}
