import SwiftUI
import Bedrock

/// Represents a contact field that has been added
struct AddedContactField: Identifiable, Equatable {
    let id: UUID
    let fieldType: ContactFieldType
    var value: String
    var title: String
    
    init(id: UUID = UUID(), fieldType: ContactFieldType, value: String = "", title: String = "") {
        self.id = id
        self.fieldType = fieldType
        self.value = value
        self.title = title
    }
    
    static func == (lhs: AddedContactField, rhs: AddedContactField) -> Bool {
        lhs.id == rhs.id && lhs.value == rhs.value && lhs.title == rhs.title
    }
    
    /// Returns the display value for this field (formatted for addresses, raw for others)
    var displayValue: String {
        fieldType.formattedDisplayValue(value)
    }
    
    /// Returns a short display value suitable for single-line display in lists
    var shortDisplayValue: String {
        if fieldType.id == "address" {
            // For addresses, show single-line format in the list
            if let address = PostalAddress.decode(from: value), address.hasValue {
                return address.singleLineString
            }
        }
        return value
    }
}

/// Displays a vertical list of added contact fields with tap to edit and drag to reorder
struct AddedContactFieldsView: View {
    @Binding var fields: [AddedContactField]
    let onEdit: (AddedContactField) -> Void
    
    @State private var draggingField: AddedContactField?
    
    var body: some View {
        if fields.isEmpty {
            EmptyView()
        } else {
            VStack(spacing: 0) {
                ForEach(fields) { field in
                    FieldRow(
                        field: field,
                        onTap: { onEdit(field) },
                        onDelete: { deleteField(field) }
                    )
                    .draggable(field.id.uuidString) {
                        // Drag preview
                        FieldRowPreview(field: field)
                    }
                    .dropDestination(for: String.self) { items, _ in
                        guard let droppedId = items.first,
                              let droppedUUID = UUID(uuidString: droppedId),
                              let fromIndex = fields.firstIndex(where: { $0.id == droppedUUID }),
                              let toIndex = fields.firstIndex(where: { $0.id == field.id }),
                              fromIndex != toIndex else {
                            return false
                        }
                        withAnimation(.spring(duration: Design.Animation.quick)) {
                            let movedField = fields.remove(at: fromIndex)
                            fields.insert(movedField, at: toIndex)
                        }
                        return true
                    }
                    
                    if field.id != fields.last?.id {
                        Divider()
                            .padding(.leading, Design.CardSize.avatarSize + Design.Spacing.large + Design.Spacing.medium)
                    }
                }
            }
            .background(Color.AppBackground.elevated)
            .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
        }
    }
    
    private func deleteField(_ field: AddedContactField) {
        withAnimation {
            fields.removeAll { $0.id == field.id }
        }
    }
}

/// Preview shown while dragging a field
private struct FieldRowPreview: View {
    let field: AddedContactField
    
    var body: some View {
        HStack(spacing: Design.Spacing.medium) {
            Circle()
                .fill(field.fieldType.iconColor)
                .frame(width: Design.CardSize.avatarSize, height: Design.CardSize.avatarSize)
                .overlay(
                    field.fieldType.iconImage()
                        .font(.title3)
                        .foregroundStyle(.white)
                )
            
            VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) {
                Text(field.value.isEmpty ? field.fieldType.displayName : field.shortDisplayValue)
                    .font(.subheadline)
                    .foregroundStyle(Color.Text.primary)
                    .lineLimit(1)
                
                if !field.title.isEmpty {
                    Text(field.title)
                        .font(.caption)
                        .foregroundStyle(Color.Text.secondary)
                        .lineLimit(1)
                }
            }
        }
        .padding(Design.Spacing.medium)
        .background(Color.AppBackground.elevated)
        .clipShape(.rect(cornerRadius: Design.CornerRadius.medium))
        .shadow(radius: Design.Shadow.radiusMedium)
    }
}

/// A display row for a contact field - tap to edit, hold to drag
private struct FieldRow: View {
    let field: AddedContactField
    let onTap: () -> Void
    let onDelete: () -> Void
    
    var body: some View {
        HStack(spacing: Design.Spacing.medium) {
            // Drag handle
            Image(systemName: "line.3.horizontal")
                .font(.caption)
                .foregroundStyle(Color.Text.tertiary)
                .frame(width: Design.Spacing.large)
            
            // Icon
            Circle()
                .fill(field.fieldType.iconColor)
                .frame(width: Design.CardSize.avatarSize, height: Design.CardSize.avatarSize)
                .overlay(
                    field.fieldType.iconImage()
                        .font(.title3)
                        .foregroundStyle(.white)
                )
            
            // Content - tap to edit
            Button(action: onTap) {
                VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) {
                    Text(field.value.isEmpty ? field.fieldType.valuePlaceholder : field.shortDisplayValue)
                        .font(.subheadline)
                        .foregroundStyle(field.value.isEmpty ? Color.Text.secondary : Color.Text.primary)
                        .lineLimit(1)
                    
                    Text(field.title.isEmpty ? field.fieldType.displayName : field.title)
                        .font(.caption)
                        .foregroundStyle(Color.Text.secondary)
                        .lineLimit(1)
                }
                .frame(maxWidth: .infinity, alignment: .leading)
            }
            .buttonStyle(.plain)
            
            // Delete button
            Button(action: onDelete) {
                Image(systemName: "xmark.circle.fill")
                    .font(.title3)
                    .foregroundStyle(Color.Text.secondary)
            }
            .buttonStyle(.plain)
            .accessibilityLabel(String(localized: "Delete"))
            .accessibilityHint(String(localized: "Removes this field"))
        }
        .padding(Design.Spacing.medium)
        .contentShape(.rect)
    }
}

#Preview {
    @Previewable @State var fields: [AddedContactField] = {
        let address = PostalAddress(street: "6565 Headquarters Dr", city: "Plano", state: "TX", postalCode: "75024")
        return [
            AddedContactField(fieldType: .email, value: "matt@example.com", title: "Work"),
            AddedContactField(fieldType: .email, value: "personal@example.com", title: "Personal"),
            AddedContactField(fieldType: .phone, value: "+1 (555) 123-4567", title: "Cell"),
            AddedContactField(fieldType: .address, value: address.encode(), title: "Work"),
            AddedContactField(fieldType: .linkedIn, value: "linkedin.com/in/mattbruce", title: "Connect with me")
        ]
    }()
    
    ScrollView {
        AddedContactFieldsView(fields: $fields) { field in
            print("Edit: \(field.fieldType.displayName)")
        }
        .padding()
    }
    .background(Color.AppBackground.base)
}
