import SwiftUI
import Bedrock
import AVFoundation
import Photos
import Contacts

struct OnboardingView: View {
    let onComplete: () -> Void

    @State private var stepIndex = 0
    @State private var cameraStatus: OnboardingPermissionStatus = .notRequested
    @State private var photosStatus: OnboardingPermissionStatus = .notRequested
    @State private var contactsStatus: OnboardingPermissionStatus = .notRequested

    private let totalSteps = 3
    private let appName = BundleAppMetadataProvider().appName

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

                VStack(spacing: Design.Spacing.large) {
                    progressHeader

                    Group {
                        switch stepIndex {
                        case 0:
                            welcomeStep
                        case 1:
                            permissionsStep
                        default:
                            activationStep
                        }
                    }

                    Spacer(minLength: 0)

                    primaryAction
                }
                .padding(.horizontal, Design.Spacing.large)
                .padding(.top, Design.Spacing.large)
                .padding(.bottom, Design.Spacing.xLarge)
            }
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    if stepIndex < totalSteps - 1 {
                        Button(String.localized("Skip")) {
                            onComplete()
                        }
                    }
                }
            }
            .onAppear {
                refreshPermissionStatuses()
            }
        }
    }

    private var progressHeader: some View {
        VStack(alignment: .leading, spacing: Design.Spacing.small) {
            Text(String.localized("Step %d of %d", stepIndex + 1, totalSteps))
                .typography(.caption)
                .foregroundStyle(Color.Text.secondary)

            ProgressView(value: Double(stepIndex + 1), total: Double(totalSteps))
                .tint(Color.Accent.red)
        }
    }

    private var welcomeStep: some View {
        VStack(alignment: .leading, spacing: Design.Spacing.large) {
            Image(systemName: "person.crop.rectangle.stack.fill")
                .typography(.title)
                .foregroundStyle(Color.Accent.red)

            VStack(alignment: .leading, spacing: Design.Spacing.small) {
                Text("Welcome to \(appName)")
                    .typography(.title)
                    .bold()
                    .foregroundStyle(Color.Text.primary)

                Text("Create one polished card, then share it anywhere in seconds.")
                    .typography(.body)
                    .foregroundStyle(Color.Text.secondary)
            }

            onboardingFeature(
                icon: "rectangle.stack.badge.plus",
                title: "Create once",
                subtitle: "Build a professional card with your branding and contact links."
            )

            onboardingFeature(
                icon: "qrcode",
                title: "Share instantly",
                subtitle: "Use QR, text, email, or App Clip links so people can save your details fast."
            )

            onboardingFeature(
                icon: "person.2",
                title: "Track follow-ups",
                subtitle: "Keep important contacts organized and set reminders from one place."
            )
        }
        .frame(maxWidth: .infinity, alignment: .leading)
    }

    private var permissionsStep: some View {
        VStack(alignment: .leading, spacing: Design.Spacing.large) {
            VStack(alignment: .leading, spacing: Design.Spacing.small) {
                Text("Enable the essentials")
                    .typography(.title2)
                    .bold()
                    .foregroundStyle(Color.Text.primary)

                Text("We ask only when it directly improves card sharing and profile quality.")
                    .typography(.body)
                    .foregroundStyle(Color.Text.secondary)
            }

            permissionRow(
                title: "Camera",
                icon: "camera.fill",
                reason: "Needed to scan QR cards and capture profile, cover, or logo photos.",
                status: cameraStatus,
                action: { requestCameraPermission() }
            )

            permissionRow(
                title: "Photos",
                icon: "photo.on.rectangle.angled",
                reason: "Needed to pick profile, cover, and logo images from your library.",
                status: photosStatus,
                action: { requestPhotosPermission() }
            )

            permissionRow(
                title: "Contacts",
                icon: "person.crop.circle.badge.plus",
                reason: "Needed when saving shared cards to your Apple Contacts.",
                status: contactsStatus,
                action: { requestContactsPermission() }
            )
        }
        .frame(maxWidth: .infinity, alignment: .leading)
    }

    private var activationStep: some View {
        VStack(alignment: .leading, spacing: Design.Spacing.large) {
            Image(systemName: "checkmark.seal.fill")
                .typography(.title)
                .foregroundStyle(Color.Accent.mint)

            VStack(alignment: .leading, spacing: Design.Spacing.small) {
                Text("You are ready to share")
                    .typography(.title2)
                    .bold()
                    .foregroundStyle(Color.Text.primary)

                Text("Next step: create your first card. Once it is saved, you can start sharing immediately.")
                    .typography(.body)
                    .foregroundStyle(Color.Text.secondary)
            }

            VStack(alignment: .leading, spacing: Design.Spacing.small) {
                onboardingChecklistItem("Add your name, role, and company")
                onboardingChecklistItem("Choose a photo or logo")
                onboardingChecklistItem("Share your card with one tap")
            }
        }
        .frame(maxWidth: .infinity, alignment: .leading)
    }

    @ViewBuilder
    private var primaryAction: some View {
        if stepIndex < totalSteps - 1 {
            PrimaryActionButton(
                title: String.localized("Continue"),
                systemImage: "arrow.right"
            ) {
                withAnimation(.easeInOut(duration: 0.2)) {
                    stepIndex += 1
                }
            }
        } else {
            PrimaryActionButton(
                title: String.localized("Create My First Card"),
                systemImage: "sparkles"
            ) {
                onComplete()
            }
        }
    }

    private func onboardingFeature(icon: String, title: String, subtitle: String) -> some View {
        HStack(alignment: .top, spacing: Design.Spacing.medium) {
            Image(systemName: icon)
                .foregroundStyle(Color.Accent.red)
                .frame(width: Design.IconSize.medium)

            VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) {
                Text(title)
                    .typography(.bodyEmphasis)
                    .foregroundStyle(Color.Text.primary)

                Text(subtitle)
                    .typography(.caption)
                    .foregroundStyle(Color.Text.secondary)
            }
        }
        .padding(Design.Spacing.medium)
        .background(Color.AppBackground.elevated)
        .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
    }

    private func onboardingChecklistItem(_ text: String) -> some View {
        HStack(spacing: Design.Spacing.small) {
            Image(systemName: "checkmark.circle.fill")
                .foregroundStyle(Color.Accent.mint)
            Text(text)
                .typography(.body)
                .foregroundStyle(Color.Text.primary)
        }
    }

    private func permissionRow(
        title: String,
        icon: String,
        reason: String,
        status: OnboardingPermissionStatus,
        action: @escaping () -> Void
    ) -> some View {
        VStack(alignment: .leading, spacing: Design.Spacing.small) {
            HStack(spacing: Design.Spacing.small) {
                Image(systemName: icon)
                    .foregroundStyle(Color.Accent.red)
                Text(title)
                    .typography(.bodyEmphasis)
                    .foregroundStyle(Color.Text.primary)
                Spacer()
                permissionStatusPill(status)
            }

            Text(reason)
                .typography(.caption)
                .foregroundStyle(Color.Text.secondary)

            if status != .allowed {
                Button(status == .denied ? "Open Settings" : "Allow Now") {
                    if status == .denied {
                        openSettings()
                    } else {
                        action()
                    }
                }
                .buttonStyle(.borderedProminent)
                .tint(Color.Accent.red)
                .controlSize(.small)
            }
        }
        .padding(Design.Spacing.medium)
        .background(Color.AppBackground.elevated)
        .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
    }

    private func permissionStatusPill(_ status: OnboardingPermissionStatus) -> some View {
        Text(status.title)
            .typography(.caption2)
            .foregroundStyle(status.tint)
            .padding(.horizontal, Design.Spacing.small)
            .padding(.vertical, Design.Spacing.xxSmall)
            .background(status.tint.opacity(0.14))
            .clipShape(.capsule)
    }

    private func openSettings() {
        guard let url = URL(string: UIApplication.openSettingsURLString) else { return }
        UIApplication.shared.open(url)
    }

    private func refreshPermissionStatuses() {
        cameraStatus = mapCameraStatus(AVCaptureDevice.authorizationStatus(for: .video))
        photosStatus = mapPhotosStatus(PHPhotoLibrary.authorizationStatus(for: .readWrite))
        contactsStatus = mapContactsStatus(CNContactStore.authorizationStatus(for: .contacts))
    }

    private func requestCameraPermission() {
        AVCaptureDevice.requestAccess(for: .video) { _ in
            Task { @MainActor in
                refreshPermissionStatuses()
            }
        }
    }

    private func requestPhotosPermission() {
        PHPhotoLibrary.requestAuthorization(for: .readWrite) { _ in
            Task { @MainActor in
                refreshPermissionStatuses()
            }
        }
    }

    private func requestContactsPermission() {
        CNContactStore().requestAccess(for: .contacts) { _, _ in
            Task { @MainActor in
                refreshPermissionStatuses()
            }
        }
    }

    private func mapCameraStatus(_ status: AVAuthorizationStatus) -> OnboardingPermissionStatus {
        switch status {
        case .authorized:
            .allowed
        case .notDetermined:
            .notRequested
        case .denied, .restricted:
            .denied
        @unknown default:
            .notRequested
        }
    }

    private func mapPhotosStatus(_ status: PHAuthorizationStatus) -> OnboardingPermissionStatus {
        switch status {
        case .authorized, .limited:
            .allowed
        case .notDetermined:
            .notRequested
        case .denied, .restricted:
            .denied
        @unknown default:
            .notRequested
        }
    }

    private func mapContactsStatus(_ status: CNAuthorizationStatus) -> OnboardingPermissionStatus {
        switch status {
        case .authorized:
            .allowed
        case .notDetermined:
            .notRequested
        case .denied, .restricted:
            .denied
        @unknown default:
            .notRequested
        }
    }
}

private enum OnboardingPermissionStatus {
    case notRequested
    case allowed
    case denied

    var title: String {
        switch self {
        case .notRequested: "Not enabled"
        case .allowed: "Enabled"
        case .denied: "Blocked"
        }
    }

    var tint: Color {
        switch self {
        case .notRequested: .orange
        case .allowed: Color.Accent.mint
        case .denied: Color.Accent.red
        }
    }
}

#Preview {
    OnboardingView(onComplete: {})
}
