import SwiftUI
import PhotosUI
import Bedrock

/// A self-contained image editor flow.
/// Shows source picker first, then presents photo picker or camera as a full-screen cover.
/// The aspect ratio is determined by the imageType.
/// For logos, an additional LogoEditorSheet is shown after cropping.
struct ImageEditorFlow: View {
    @Environment(\.dismiss) private var dismiss
    
    let imageType: CardEditorView.ImageType
    let hasExistingImage: Bool
    let onComplete: (Data?) -> Void  // nil = cancelled/no change, Data = final cropped image
    
    private enum NextAction {
        case library
        case camera
    }
    
    @State private var nextAction: NextAction?
    @State private var showingFullScreenPicker = false
    @State private var showingFullScreenCamera = false
    
    private var aspectRatio: CropAspectRatio {
        imageType.cropAspectRatio
    }
    
    /// Only allow aspect ratio selection for logos
    private var allowAspectRatioSelection: Bool {
        imageType == .logo
    }
    
    /// Whether this is a logo image (needs extra editing step)
    private var isLogoImage: Bool {
        imageType == .logo
    }
    
    var body: some View {
        // Source picker is the base content of this sheet
        sourcePickerView
            .fullScreenCover(isPresented: $showingFullScreenPicker) {
                PhotoPickerFlow(
                    aspectRatio: aspectRatio,
                    allowAspectRatioSelection: allowAspectRatioSelection,
                    isLogoImage: isLogoImage,
                    onComplete: { imageData in
                        showingFullScreenPicker = false
                        if let imageData {
                            onComplete(imageData)
                        }
                        // If nil, we stay on source picker
                    }
                )
            }
            .fullScreenCover(isPresented: $showingFullScreenCamera) {
                CameraFlow(
                    aspectRatio: aspectRatio,
                    allowAspectRatioSelection: allowAspectRatioSelection,
                    isLogoImage: isLogoImage,
                    onComplete: { imageData in
                        showingFullScreenCamera = false
                        if let imageData {
                            onComplete(imageData)
                        }
                        // If nil, we stay on source picker
                    }
                )
            }
    }
    
    // MARK: - Source Picker
    
    private var sourcePickerView: some View {
        NavigationStack {
            VStack(spacing: 0) {
                VStack(spacing: 0) {
                    OptionRow(
                        icon: "photo.on.rectangle",
                        title: String.localized("Select from photo library")
                    ) {
                        showingFullScreenPicker = true
                    }
                    
                    Divider()
                        .padding(.leading, Design.Spacing.xLarge + Design.CardSize.socialIconSize)
                    
                    OptionRow(
                        icon: "camera",
                        title: String.localized("Take photo")
                    ) {
                        showingFullScreenCamera = true
                    }
                    
                    if hasExistingImage {
                        Divider()
                            .padding(.leading, Design.Spacing.xLarge + Design.CardSize.socialIconSize)
                        
                        OptionRow(
                            icon: "trash",
                            title: String.localized("Remove photo"),
                            isDestructive: true
                        ) {
                            onComplete(Data())
                        }
                    }
                }
                .background(Color.AppBackground.card)
                .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
                .padding(.horizontal, Design.Spacing.large)
                .padding(.top, Design.Spacing.medium)
                
                Spacer()
            }
            .background(Color.AppBackground.secondary)
            .navigationTitle(imageType.title)
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button {
                        onComplete(nil)
                    } label: {
                        Image(systemName: "xmark")
                            .font(.body.bold())
                            .foregroundStyle(Color.Text.primary)
                    }
                }
            }
        }
        .presentationDetents([.height(CGFloat((hasExistingImage ? 3 : 2) * 56 + 100))])
        .presentationDragIndicator(.visible)
    }
}

// MARK: - Photo Picker Flow (full screen)

private struct PhotoPickerFlow: View {
    let aspectRatio: CropAspectRatio
    let allowAspectRatioSelection: Bool
    let isLogoImage: Bool
    let onComplete: (Data?) -> Void
    
    @State private var selectedPhotoItem: PhotosPickerItem?
    @State private var imageData: Data?
    @State private var showingCropper = false
    @State private var showingLogoEditor = false
    @State private var croppedLogoImage: UIImage?
    @State private var pickerID = UUID()
    
    var body: some View {
        NavigationStack {
            PhotosPicker(
                selection: $selectedPhotoItem,
                matching: .images,
                photoLibrary: .shared()
            ) {
                EmptyView()
            }
            .photosPickerStyle(.inline)
            .photosPickerDisabledCapabilities([.selectionActions])
            .ignoresSafeArea()
            .id(pickerID)
            .onChange(of: selectedPhotoItem) { _, newValue in
                guard let newValue else { return }
                Task { @MainActor in
                    if let data = try? await newValue.loadTransferable(type: Data.self) {
                        imageData = data
                        showingCropper = true
                    }
                }
            }
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button(String.localized("Cancel")) {
                        onComplete(nil)
                    }
                }
            }
        }
        .overlay {
            if showingCropper, let imageData {
                PhotoCropperSheet(
                    imageData: imageData,
                    aspectRatio: aspectRatio,
                    allowAspectRatioSelection: allowAspectRatioSelection,
                    shouldDismissOnComplete: false
                ) { croppedData in
                    if let croppedData {
                        // For logos, show the logo editor next
                        if isLogoImage, let uiImage = UIImage(data: croppedData) {
                            croppedLogoImage = uiImage
                            showingCropper = false
                            showingLogoEditor = true
                        } else {
                            onComplete(croppedData)
                        }
                    } else {
                        // Go back to picker
                        showingCropper = false
                        self.imageData = nil
                        self.selectedPhotoItem = nil
                        pickerID = UUID()
                    }
                }
                .transition(.move(edge: .trailing))
            }
            
            // Logo editor overlay
            if showingLogoEditor, let logoImage = croppedLogoImage {
                LogoEditorSheet(logoImage: logoImage) { finalData in
                    if let finalData {
                        onComplete(finalData)
                    } else {
                        // User cancelled logo editor, go back to picker
                        showingLogoEditor = false
                        croppedLogoImage = nil
                        self.imageData = nil
                        self.selectedPhotoItem = nil
                        pickerID = UUID()
                    }
                }
                .transition(.move(edge: .trailing))
            }
        }
        .animation(.easeInOut(duration: Design.Animation.quick), value: showingCropper)
        .animation(.easeInOut(duration: Design.Animation.quick), value: showingLogoEditor)
    }
}

// MARK: - Camera Flow (full screen)

private struct CameraFlow: View {
    let aspectRatio: CropAspectRatio
    let allowAspectRatioSelection: Bool
    let isLogoImage: Bool
    let onComplete: (Data?) -> Void
    
    @State private var capturedImageData: Data?
    @State private var showingCropper = false
    @State private var showingLogoEditor = false
    @State private var croppedLogoImage: UIImage?
    @State private var cameraID = UUID()  // For resetting camera after cancel
    
    var body: some View {
        ZStack {
            // Camera - only show when not cropping or editing
            if !showingCropper && !showingLogoEditor {
                CameraCaptureView(shouldDismissOnCapture: false) { imageData in
                    if let imageData {
                        capturedImageData = imageData
                        showingCropper = true
                    } else {
                        // User cancelled camera itself
                        onComplete(nil)
                    }
                }
                .id(cameraID)
                .ignoresSafeArea()
                .transition(.opacity)
            }
            
            // Cropper overlay
            if showingCropper, let imageData = capturedImageData {
                PhotoCropperSheet(
                    imageData: imageData,
                    aspectRatio: aspectRatio,
                    allowAspectRatioSelection: allowAspectRatioSelection,
                    shouldDismissOnComplete: false
                ) { croppedData in
                    if let croppedData {
                        // For logos, show the logo editor next
                        if isLogoImage, let uiImage = UIImage(data: croppedData) {
                            croppedLogoImage = uiImage
                            showingCropper = false
                            showingLogoEditor = true
                        } else {
                            onComplete(croppedData)
                        }
                    } else {
                        // User cancelled cropper - go back to camera for retake
                        showingCropper = false
                        capturedImageData = nil
                        cameraID = UUID()  // Reset camera
                    }
                }
                .transition(.move(edge: .trailing))
            }
            
            // Logo editor overlay
            if showingLogoEditor, let logoImage = croppedLogoImage {
                LogoEditorSheet(logoImage: logoImage) { finalData in
                    if let finalData {
                        onComplete(finalData)
                    } else {
                        // User cancelled logo editor, go back to camera
                        showingLogoEditor = false
                        croppedLogoImage = nil
                        capturedImageData = nil
                        cameraID = UUID()
                    }
                }
                .transition(.move(edge: .trailing))
            }
        }
        .animation(.easeInOut(duration: Design.Animation.quick), value: showingCropper)
        .animation(.easeInOut(duration: Design.Animation.quick), value: showingLogoEditor)
    }
}

// MARK: - Option Row

private struct OptionRow: View {
    let icon: String
    let title: String
    var isDestructive: Bool = false
    let action: () -> Void
    
    var body: some View {
        Button(action: action) {
            HStack(spacing: Design.Spacing.medium) {
                Image(systemName: icon)
                    .font(.body)
                    .foregroundStyle(isDestructive ? Color.red : Color.Text.secondary)
                    .frame(width: Design.CardSize.socialIconSize)
                
                Text(title)
                    .font(.body)
                    .foregroundStyle(isDestructive ? Color.red : Color.Text.primary)
                
                Spacer()
            }
            .padding(.horizontal, Design.Spacing.large)
            .padding(.vertical, Design.Spacing.medium)
            .contentShape(.rect)
        }
        .buttonStyle(.plain)
    }
}

#Preview {
    Text("Tap to edit")
        .sheet(isPresented: .constant(true)) {
            ImageEditorFlow(
                imageType: .profile,
                hasExistingImage: false
            ) { data in
                print(data != nil ? "Got image" : "Cancelled")
            }
        }
}
