import SwiftUI
import UIKit

/// A native iOS camera picker presented from a hosting controller so it can
/// respect all supported interface orientations. Present with `.fullScreenCover()`.
struct CameraImagePicker: UIViewControllerRepresentable {
    @Environment(\.dismiss) private var dismiss
    let onImageCaptured: (UIImage) -> Void

    func makeUIViewController(context: Context) -> CameraHostViewController {
        let host = CameraHostViewController()
        host.onImageCaptured = { image in
            onImageCaptured(image)
            dismiss()
        }
        host.onCancel = {
            dismiss()
        }
        host.pickerDelegate = context.coordinator
        context.coordinator.onImageCaptured = { image in
            onImageCaptured(image)
            dismiss()
        }
        context.coordinator.onCancel = {
            dismiss()
        }
        return host
    }

    func updateUIViewController(_ uiViewController: CameraHostViewController, context: Context) {
        // No dynamic updates needed
    }

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

    class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        var onImageCaptured: ((UIImage) -> Void)?
        var onCancel: (() -> Void)?

        func imagePickerController(
            _ picker: UIImagePickerController,
            didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]
        ) {
            picker.dismiss(animated: true) {
                if let image = info[.originalImage] as? UIImage {
                    self.onImageCaptured?(image)
                } else {
                    self.onCancel?()
                }
            }
        }

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            picker.dismiss(animated: true) {
                self.onCancel?()
            }
        }
    }
}

// MARK: - Hosting VC to own presentation/orientation
final class CameraHostViewController: UIViewController {
    var onImageCaptured: ((UIImage) -> Void)?
    var onCancel: (() -> Void)?
    weak var pickerDelegate: (UIImagePickerControllerDelegate & UINavigationControllerDelegate)?

    private var didPresent = false

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        presentIfNeeded()
    }

    private func presentIfNeeded() {
        guard !didPresent, UIImagePickerController.isSourceTypeAvailable(.camera) else { return }
        didPresent = true

        let picker = UIImagePickerController()
        picker.delegate = pickerDelegate
        picker.sourceType = .camera
        picker.cameraCaptureMode = .photo
        picker.cameraDevice = .rear
        picker.allowsEditing = false
        picker.modalPresentationStyle = .fullScreen

        present(picker, animated: true)
    }

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        // Defer to app-supported orientations; returning .all allows rotation when permitted by the app
        return .all
    }

    override var shouldAutorotate: Bool {
        true
    }
}

// MARK: - Camera Availability Check
extension CameraImagePicker {
    static var isCameraAvailable: Bool {
        UIImagePickerController.isSourceTypeAvailable(.camera)
    }
}
