import SwiftUI
import ContactsUI
import Contacts

// MARK: - UIViewControllerRepresentable wrapper

/// Wraps CNContactPickerViewController — no NSContactsUsageDescription needed,
/// the system picker runs in its own process and manages its own access.
struct ContactPickerView: UIViewControllerRepresentable {
    let onSelect: (CNContact) -> Void

    func makeUIViewController(context: Context) -> CNContactPickerViewController {
        let picker = CNContactPickerViewController()
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIViewController(_ uiViewController: CNContactPickerViewController, context: Context) {}

    func makeCoordinator() -> Coordinator { Coordinator(onSelect: onSelect) }

    final class Coordinator: NSObject, CNContactPickerDelegate {
        let onSelect: (CNContact) -> Void
        init(onSelect: @escaping (CNContact) -> Void) { self.onSelect = onSelect }

        func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
            onSelect(contact)
        }
    }
}

// MARK: - Mapping helper

struct ContactImport {
    let name: String
    let occupation: String
    let location: String
    let birthday: Date?
    let photoData: Data?

    /// Maps a CNContact to the fields used by AddPersonView.
    /// All fields are best-effort; missing data yields empty strings / nil.
    static func from(_ contact: CNContact) -> ContactImport {
        // Full name
        let parts = [contact.givenName, contact.familyName].filter { !$0.isEmpty }
        let name = parts.joined(separator: " ")

        // Occupation: prefer job title, fall back to org name
        let occupation: String
        if !contact.jobTitle.isEmpty {
            occupation = contact.jobTitle
        } else if !contact.organizationName.isEmpty {
            occupation = contact.organizationName
        } else {
            occupation = ""
        }

        // Location: city (+ country if different from obvious)
        let location: String
        if let postal = contact.postalAddresses.first?.value {
            let city = postal.city
            let country = postal.country
            location = [city, country].filter { !$0.isEmpty }.joined(separator: ", ")
        } else {
            location = ""
        }

        // Birthday
        var birthdayDate: Date? = nil
        if let components = contact.birthday {
            // Some contacts store only month+day (year == nil or year == 1)
            var resolved = components
            if resolved.year == nil || resolved.year == 1 {
                resolved.year = Calendar.current.component(.year, from: Date())
            }
            birthdayDate = Calendar.current.date(from: resolved)
        }

        // Photo: prefer thumbnail (smaller), fall back to full image resized
        let photoData: Data?
        if let thumbnail = contact.thumbnailImageData {
            photoData = thumbnail
        } else if let fullData = contact.imageData,
                  let resized = UIImage(data: fullData)?.resizedForAvatar() {
            photoData = resized.jpegData(compressionQuality: 0.8)
        } else {
            photoData = nil
        }

        return ContactImport(
            name: name,
            occupation: occupation,
            location: location,
            birthday: birthdayDate,
            photoData: photoData
        )
    }
}

// MARK: - UIImage helper

extension UIImage {
    /// Downscales the image so the longer side is at most `maxSide` points.
    func resizedForAvatar(maxSide: CGFloat = 400) -> UIImage? {
        let scale = min(maxSide / size.width, maxSide / size.height)
        guard scale < 1 else { return self }
        let newSize = CGSize(width: (size.width * scale).rounded(), height: (size.height * scale).rounded())
        return UIGraphicsImageRenderer(size: newSize).image { _ in
            draw(in: CGRect(origin: .zero, size: newSize))
        }
    }
}
