import SwiftUI
import Bedrock

/// Sheet for adding or editing a contact field value
struct ContactFieldEditorSheet: View {
    @Environment(\.dismiss) private var dismiss
    
    let fieldType: ContactFieldType
    let initialValue: String
    let initialTitle: String
    let onSave: (String, String) -> Void
    let onDelete: (() -> Void)?
    
    @State private var value: String
    @State private var title: String
    @State private var postalAddress: PostalAddress
    
    init(
        fieldType: ContactFieldType,
        initialValue: String = "",
        initialTitle: String = "",
        onSave: @escaping (String, String) -> Void,
        onDelete: (() -> Void)? = nil
    ) {
        self.fieldType = fieldType
        self.initialValue = initialValue
        self.initialTitle = initialTitle
        self.onSave = onSave
        self.onDelete = onDelete
        _value = State(initialValue: initialValue)
        _title = State(initialValue: initialTitle)
        
        // Parse postal address if this is an address field
        if fieldType.id == "address" {
            if let parsed = PostalAddress.decode(from: initialValue), parsed.hasValue {
                _postalAddress = State(initialValue: parsed)
            } else {
                _postalAddress = State(initialValue: PostalAddress())
            }
        } else {
            _postalAddress = State(initialValue: PostalAddress())
        }
    }
    
    private var isAddressField: Bool {
        fieldType.id == "address"
    }
    
    private var isValid: Bool {
        if isAddressField {
            return postalAddress.hasValue
        }
        return !value.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
    }
    
    private var isEditing: Bool {
        !initialValue.isEmpty
    }
    
    var body: some View {
        NavigationStack {
            VStack(spacing: 0) {
                // Header with icon
                FieldHeaderView(fieldType: fieldType)
                
                Divider()
                
                // Form content
                VStack(alignment: .leading, spacing: Design.Spacing.xLarge) {
                    // Value field - different for address vs other fields
                    if isAddressField {
                        AddressEditorView(address: $postalAddress)
                    } else {
                        VStack(alignment: .leading, spacing: Design.Spacing.small) {
                            Text(fieldType.valueLabel)
                                .font(.subheadline)
                                .foregroundStyle(Color.Text.primary)
                            
                            TextField(fieldType.valuePlaceholder, text: $value)
                                .keyboardType(fieldType.keyboardType)
                                .textInputAutocapitalization(fieldType.autocapitalization)
                                .textContentType(textContentType)
                            
                            Divider()
                        }
                    }
                    
                    // Title field
                    VStack(alignment: .leading, spacing: Design.Spacing.small) {
                        Text("Title (optional)")
                            .font(.subheadline)
                            .foregroundStyle(Color.Text.primary)
                        
                        TextField(String(localized: "e.g. Work, Personal"), text: $title)
                        
                        Divider()
                        
                        // Suggestions
                        if !fieldType.titleSuggestions.isEmpty {
                            VStack(alignment: .leading, spacing: Design.Spacing.small) {
                                Text("Here are some suggestions for your title:")
                                    .font(.caption)
                                    .foregroundStyle(Color.Text.secondary)
                                
                                FlowLayout(spacing: Design.Spacing.small) {
                                    ForEach(fieldType.titleSuggestions, id: \.self) { suggestion in
                                        SuggestionChip(text: suggestion) {
                                            title = suggestion
                                        }
                                    }
                                }
                            }
                        }
                    }
                    
                    Spacer()
                    
                    // Delete button for editing
                    if isEditing, let onDelete {
                        Button(role: .destructive) {
                            onDelete()
                            dismiss()
                        } label: {
                            HStack {
                                Spacer()
                                Label("Delete Field", systemImage: "trash")
                                Spacer()
                            }
                            .padding(Design.Spacing.medium)
                            .background(Color.Accent.red.opacity(Design.Opacity.subtle))
                            .clipShape(.rect(cornerRadius: Design.CornerRadius.medium))
                        }
                        .buttonStyle(.plain)
                        .foregroundStyle(Color.Accent.red)
                    }
                }
                .padding(Design.Spacing.large)
            }
            .background(Color.AppBackground.base)
            .navigationTitle(isEditing ? "Edit \(fieldType.displayName)" : "Add \(fieldType.displayName)")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button {
                        dismiss()
                    } label: {
                        Image(systemName: "chevron.left")
                    }
                }
                
                ToolbarItem(placement: .confirmationAction) {
                    Button("Save") {
                        if isAddressField {
                            // Save postal address as JSON
                            onSave(postalAddress.encode(), title)
                        } else {
                            onSave(value.trimmingCharacters(in: .whitespacesAndNewlines), title)
                        }
                        dismiss()
                    }
                    .disabled(!isValid)
                }
            }
        }
    }
    
    private var textContentType: UITextContentType? {
        switch fieldType.id {
        case "phone": return .telephoneNumber
        case "email": return .emailAddress
        case "website": return .URL
        case "address": return .fullStreetAddress
        default: return .URL
        }
    }
}

// MARK: - Field Header

private struct FieldHeaderView: View {
    let fieldType: ContactFieldType
    
    var body: some View {
        HStack(spacing: Design.Spacing.medium) {
            Circle()
                .fill(fieldType.iconColor)
                .frame(width: Design.CardSize.avatarSize, height: Design.CardSize.avatarSize)
                .overlay(
                    fieldType.iconImage()
                        .font(.title3)
                        .foregroundStyle(.white)
                )
            
            Text(fieldType.displayName)
                .font(.headline)
                .foregroundStyle(Color.Text.primary)
            
            Spacer()
        }
        .padding(Design.Spacing.large)
        .background(Color.AppBackground.elevated)
    }
}

// MARK: - Suggestion Chip

private struct SuggestionChip: View {
    let text: String
    let action: () -> Void
    
    var body: some View {
        Button(action: action) {
            Text(text)
                .font(.subheadline)
                .padding(.horizontal, Design.Spacing.medium)
                .padding(.vertical, Design.Spacing.small)
                .background(Color.AppBackground.elevated)
                .clipShape(.capsule)
                .overlay(
                    Capsule()
                        .stroke(Color.Text.secondary.opacity(Design.Opacity.light), lineWidth: Design.LineWidth.thin)
                )
        }
        .buttonStyle(.plain)
    }
}

// MARK: - Flow Layout

private struct FlowLayout: Layout {
    var spacing: CGFloat = 8
    
    func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
        let result = layout(subviews: subviews, proposal: proposal)
        return result.size
    }
    
    func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
        let result = layout(subviews: subviews, proposal: proposal)
        
        for (index, position) in result.positions.enumerated() {
            subviews[index].place(at: CGPoint(x: bounds.minX + position.x, y: bounds.minY + position.y), proposal: .unspecified)
        }
    }
    
    private func layout(subviews: Subviews, proposal: ProposedViewSize) -> (size: CGSize, positions: [CGPoint]) {
        let maxWidth = proposal.width ?? .infinity
        var positions: [CGPoint] = []
        var currentX: CGFloat = 0
        var currentY: CGFloat = 0
        var lineHeight: CGFloat = 0
        var maxX: CGFloat = 0
        
        for subview in subviews {
            let size = subview.sizeThatFits(.unspecified)
            
            if currentX + size.width > maxWidth && currentX > 0 {
                currentX = 0
                currentY += lineHeight + spacing
                lineHeight = 0
            }
            
            positions.append(CGPoint(x: currentX, y: currentY))
            lineHeight = max(lineHeight, size.height)
            currentX += size.width + spacing
            maxX = max(maxX, currentX)
        }
        
        return (CGSize(width: maxX, height: currentY + lineHeight), positions)
    }
}

#Preview("Add Email") {
    ContactFieldEditorSheet(fieldType: .email) { value, title in
        print("Saved: \(value), \(title)")
    }
}

#Preview("Edit LinkedIn") {
    ContactFieldEditorSheet(
        fieldType: .linkedIn,
        initialValue: "linkedin.com/in/mattbruce",
        initialTitle: "Connect with me"
    ) { value, title in
        print("Saved: \(value), \(title)")
    } onDelete: {
        print("Deleted")
    }
}

#Preview("Add Address") {
    ContactFieldEditorSheet(fieldType: .address) { value, title in
        print("Saved address: \(value), title: \(title)")
    }
}

#Preview("Edit Address") {
    let existingAddress = PostalAddress(
        street: "6565 Headquarters Dr",
        city: "Plano",
        state: "TX",
        postalCode: "75024"
    )
    
    ContactFieldEditorSheet(
        fieldType: .address,
        initialValue: existingAddress.encode(),
        initialTitle: "Work"
    ) { value, title in
        print("Saved: \(value), title: \(title)")
    } onDelete: {
        print("Deleted")
    }
}
