Nightmare Debate

Open in bitrigDownload Code
```swift
import SwiftUI
import FoundationModels

@main
struct NightmareDebateApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State private var languageModel = SystemLanguageModel.default
    @State private var halloweenArgument: String = ""
    @State private var christmasArgument: String = ""
    @State private var isGeneratingHalloween = false
    @State private var isGeneratingChristmas = false
    @AppStorage("halloweenWins") private var halloweenWins = 0
    @AppStorage("christmasWins") private var christmasWins = 0
    @State private var currentRoundWinner: String?
    
    var bothArgumentsGenerated: Bool {
        !halloweenArgument.isEmpty && !christmasArgument.isEmpty
    }
    
    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(spacing: 30) {
                    VStack(spacing: 12) {
                        Text("🎃 🎬 🎄")
                            .font(.system(size: 60))
                        
                        Text("The Nightmare Before Christmas")
                            .font(.title2.bold())
                            .multilineTextAlignment(.center)
                        
                        Text("Halloween or Christmas movie? You decide.")
                            .font(.title3)
                            .foregroundStyle(.secondary)
                            .multilineTextAlignment(.center)
                            .padding(.horizontal)
                    }
                    .padding(.top, 20)
                    
                    if (halloweenWins > 0) || (christmasWins > 0) {
                        HStack(spacing: 30) {
                            VStack(spacing: 4) {
                                Text("🎃")
                                    .font(.title2)
                                Text("\(halloweenWins)")
                                    .font(.title.bold())
                                    .foregroundStyle(.orange)
                                Text("wins")
                                    .font(.caption)
                                    .foregroundStyle(.secondary)
                            }
                            
                            Text("VS")
                                .font(.headline.bold())
                                .foregroundStyle(.secondary)
                            
                            VStack(spacing: 4) {
                                Text("🎄")
                                    .font(.title2)
                                Text("\(christmasWins)")
                                    .font(.title.bold())
                                    .foregroundStyle(.green)
                                Text("wins")
                                    .font(.caption)
                                    .foregroundStyle(.secondary)
                            }
                        }
                        .padding()
                        .background(Color(.systemGray6))
                        .clipShape(RoundedRectangle(cornerRadius: 12))
                    }
                    
                    if #available(iOS 26.0, *) {
                        switch languageModel.availability {
                        case .available:
                            VStack(spacing: 20) {
                                ArgumentCard(
                                    title: "Halloween Movie",
                                    icon: "🎃",
                                    color: .orange,
                                    argument: halloweenArgument,
                                    isGenerating: isGeneratingHalloween,
                                    showVoteButton: bothArgumentsGenerated && (currentRoundWinner == nil),
                                    isWinner: currentRoundWinner == "halloween",
                                    onGenerate: {
                                        generateHalloweenArgument()
                                    },
                                    onVote: {
                                        voteForHalloween()
                                    }
                                )
                                
                                ArgumentCard(
                                    title: "Christmas Movie",
                                    icon: "🎄",
                                    color: .green,
                                    argument: christmasArgument,
                                    isGenerating: isGeneratingChristmas,
                                    showVoteButton: bothArgumentsGenerated && (currentRoundWinner == nil),
                                    isWinner: currentRoundWinner == "christmas",
                                    onGenerate: {
                                        generateChristmasArgument()
                                    },
                                    onVote: {
                                        voteForChristmas()
                                    }
                                )
                            }
                            .padding(.horizontal)
                            
                            if currentRoundWinner != nil {
                                Button(action: startNewRound) {
                                    HStack {
                                        Image(systemName: "arrow.clockwise")
                                        Text("New Round")
                                    }
                                    .font(.headline)
                                    .foregroundStyle(.white)
                                    .frame(maxWidth: .infinity)
                                    .padding()
                                    .background(Color.blue.gradient)
                                    .clipShape(RoundedRectangle(cornerRadius: 12))
                                }
                                .padding(.horizontal)
                            }
                            
                        case .unavailable:
                            VStack(spacing: 16) {
                                Image(systemName: "brain.fill")
                                    .font(.system(size: 60))
                                    .foregroundStyle(.secondary)
                                
                                Text("AI Not Available")
                                    .font(.headline)
                                
                                Text("The on-device AI model is not available on this device.")
                                    .font(.subheadline)
                                    .foregroundStyle(.secondary)
                                    .multilineTextAlignment(.center)
                            }
                            .padding()
                        }
                    } else {
                        VStack(spacing: 16) {
                            Image(systemName: "exclamationmark.triangle.fill")
                                .font(.system(size: 60))
                                .foregroundStyle(.orange)
                            
                            Text("iOS 26 Required")
                                .font(.headline)
                            
                            Text("This feature requires iOS 26 or later.")
                                .font(.subheadline)
                                .foregroundStyle(.secondary)
                        }
                        .padding()
                    }
                }
                .padding(.bottom, 30)
            }
            .navigationTitle("Movie Debate")
        }
    }
    
    @available(iOS 26.0, *)
    func generateHalloweenArgument() {
        isGeneratingHalloween = true
        halloweenArgument = ""
        currentRoundWinner = nil
        
        Task {
            do {
                let session = LanguageModelSession()
                let response = try await session.respond(to: "Write a persuasive 3-4 sentence argument for why The Nightmare Before Christmas is a Halloween movie, not a Christmas movie. Be compelling and cite specific elements from the film.")
                halloweenArgument = response.content
            } catch {
                halloweenArgument = "Failed to generate argument."
            }
            isGeneratingHalloween = false
        }
    }
    
    @available(iOS 26.0, *)
    func generateChristmasArgument() {
        isGeneratingChristmas = true
        christmasArgument = ""
        currentRoundWinner = nil
        
        Task {
            do {
                let session = LanguageModelSession()
                let response = try await session.respond(to: "Write a persuasive 3-4 sentence argument for why The Nightmare Before Christmas is a Christmas movie, not a Halloween movie. Be compelling and cite specific elements from the film.")
                christmasArgument = response.content
            } catch {
                christmasArgument = "Failed to generate argument."
            }
            isGeneratingChristmas = false
        }
    }
    
    func voteForHalloween() {
        currentRoundWinner = "halloween"
        halloweenWins += 1
    }
    
    func voteForChristmas() {
        currentRoundWinner = "christmas"
        christmasWins += 1
    }
    
    func startNewRound() {
        halloweenArgument = ""
        christmasArgument = ""
        currentRoundWinner = nil
    }
}

struct ArgumentCard: View {
    let title: String
    let icon: String
    let color: Color
    let argument: String
    let isGenerating: Bool
    let showVoteButton: Bool
    let isWinner: Bool
    let onGenerate: () -> Void
    let onVote: () -> Void
    
    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            HStack {
                Text(icon)
                    .font(.system(size: 40))
                
                Text(title)
                    .font(.title3.bold())
                    .foregroundStyle(.white)
                
                Spacer()
                
                if isWinner {
                    HStack(spacing: 4) {
                        Image(systemName: "crown.fill")
                        Text("Winner")
                    }
                    .font(.subheadline.bold())
                    .foregroundStyle(.yellow)
                }
            }
            
            if isGenerating {
                HStack {
                    ProgressView()
                        .tint(.white)
                    Text("Generating argument...")
                        .font(.subheadline)
                        .foregroundStyle(.white.opacity(0.8))
                }
                .frame(maxWidth: .infinity, alignment: .center)
                .padding(.vertical, 20)
            } else if argument.isEmpty {
                Button(action: onGenerate) {
                    HStack {
                        Image(systemName: "sparkles")
                        Text("Generate Argument")
                    }
                    .font(.headline)
                    .foregroundStyle(color)
                    .frame(maxWidth: .infinity)
                    .padding()
                    .background(Color.white)
                    .clipShape(RoundedRectangle(cornerRadius: 10))
                }
            } else {
                VStack(alignment: .leading, spacing: 12) {
                    Text(argument)
                        .font(.body)
                        .foregroundStyle(.white)
                        .fixedSize(horizontal: false, vertical: true)
                    
                    HStack(spacing: 12) {
                        if showVoteButton {
                            Button(action: onVote) {
                                HStack {
                                    Image(systemName: "hand.thumbsup.fill")
                                    Text("Pick This One")
                                }
                                .font(.subheadline.bold())
                                .foregroundStyle(color)
                                .frame(maxWidth: .infinity)
                                .padding(.horizontal, 16)
                                .padding(.vertical, 10)
                                .background(Color.white)
                                .clipShape(Capsule())
                            }
                            .sensoryFeedback(.success, trigger: isWinner)
                        }
                        
                        if !showVoteButton && !isWinner {
                            Button(action: onGenerate) {
                                HStack {
                                    Image(systemName: "arrow.clockwise")
                                    Text("Regenerate")
                                }
                                .font(.subheadline.bold())
                                .foregroundStyle(color)
                                .padding(.horizontal, 16)
                                .padding(.vertical, 8)
                                .background(Color.white)
                                .clipShape(Capsule())
                            }
                        }
                    }
                }
            }
        }
        .padding(20)
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(color.gradient)
        .clipShape(RoundedRectangle(cornerRadius: 16))
        .shadow(color: color.opacity(0.3), radius: 8, y: 4)
        .overlay(
            RoundedRectangle(cornerRadius: 16)
                .strokeBorder(Color.yellow, lineWidth: isWinner ? 3 : 0)
        )
    }
}
```