import PhotosUI
import SwiftUI
import VisionKit

/// Root view of the "Scannen" tab (see `App/MainTabView.swift`). Offers two
/// entry points into the scan flow — the system document camera and a photo
/// library fallback — uploads whichever image the user provides for AI
/// extraction via `ScanViewModel`, then pushes `ReceiptReviewView` with the
/// result.
struct ScanTabView: View {
    @StateObject private var viewModel = ScanViewModel()

    @State private var isShowingCamera = false
    @State private var cameraUnsupportedAlertPresented = false
    @State private var photoPickerItem: PhotosPickerItem?

    @State private var extractedReceipt: Receipt?
    @State private var isShowingReview = false

    var body: some View {
        NavigationStack {
            ZStack {
                Color.zenithBg.ignoresSafeArea()

                VStack(spacing: ZenithSpacing.md) {
                    Spacer()

                    Image(systemName: "camera.viewfinder")
                        .font(.system(size: 64))
                        .foregroundStyle(.zenithSubtle)

                    Text("Beleg scannen")
                        .zenithHeadlineLgStyle()

                    Text("Fotografiere einen Beleg oder wähle ein vorhandenes Foto aus deiner Fotomediathek.")
                        .zenithBodySmStyle()
                        .multilineTextAlignment(.center)
                        .padding(.horizontal, ZenithSpacing.md)

                    VStack(spacing: ZenithSpacing.xs) {
                        Button {
                            startCamera()
                        } label: {
                            Label("Kamera", systemImage: "camera")
                                .frame(maxWidth: .infinity)
                        }
                        .buttonStyle(.zenithPrimary)
                        .disabled(viewModel.isUploading)

                        PhotosPicker(selection: $photoPickerItem, matching: .images) {
                            Label("Aus Fotos wählen", systemImage: "photo.on.rectangle")
                                .frame(maxWidth: .infinity)
                        }
                        .buttonStyle(.zenithSecondary)
                        .disabled(viewModel.isUploading)
                    }
                    .padding(.horizontal, ZenithSpacing.md)
                    .padding(.top, ZenithSpacing.xs)

                    if viewModel.isUploading {
                        ProgressView("Beleg wird analysiert …")
                            .tint(.zenithBlack)
                            .zenithBodySmStyle()
                            .padding(.top, ZenithSpacing.xs)
                    }

                    if let errorMessage = viewModel.errorMessage {
                        Text(errorMessage)
                            .zenithBodySmStyle(color: .zenithError)
                            .multilineTextAlignment(.center)
                            .padding(.horizontal, ZenithSpacing.md)
                            .padding(.top, ZenithSpacing.unit)
                    }

                    Spacer()
                    Spacer()
                }
            }
            .navigationTitle("Scannen")
            .fullScreenCover(isPresented: $isShowingCamera) {
                DocumentCameraView { image in
                    isShowingCamera = false
                    guard let image else { return }
                    Task { await processImage(image) }
                }
                .ignoresSafeArea()
            }
            .onChange(of: photoPickerItem) { _, newItem in
                guard let newItem else { return }
                Task {
                    await handlePickedPhoto(newItem)
                    photoPickerItem = nil
                }
            }
            .alert("Kamera nicht verfügbar", isPresented: $cameraUnsupportedAlertPresented) {
                Button("OK", role: .cancel) {}
            } message: {
                Text("Die Dokumentenkamera wird auf diesem Gerät nicht unterstützt. Bitte wähle stattdessen ein Foto aus deiner Fotomediathek.")
            }
            .navigationDestination(isPresented: $isShowingReview) {
                if let extractedReceipt {
                    ReceiptReviewView(receipt: extractedReceipt)
                }
            }
        }
    }

    private func startCamera() {
        if VNDocumentCameraViewController.isSupported {
            isShowingCamera = true
        } else {
            cameraUnsupportedAlertPresented = true
        }
    }

    private func handlePickedPhoto(_ item: PhotosPickerItem) async {
        do {
            guard let data = try await item.loadTransferable(type: Data.self),
                  let image = UIImage(data: data) else {
                viewModel.errorMessage = "Foto konnte nicht geladen werden."
                return
            }
            await processImage(image)
        } catch {
            viewModel.errorMessage = "Foto konnte nicht geladen werden."
        }
    }

    private func processImage(_ image: UIImage) async {
        if let receipt = await viewModel.uploadAndExtract(image: image) {
            extractedReceipt = receipt
            isShowingReview = true
        }
    }
}
