//
//  RouteDescriptionGenerator.swift
//  SportsTime
//
//  On-device AI route description generation using Foundation Models
//

import Foundation
import FoundationModels

/// Generates human-readable route descriptions using on-device AI
@MainActor
@Observable
final class RouteDescriptionGenerator {
    static let shared = RouteDescriptionGenerator()

    private(set) var isAvailable = false
    private var session: LanguageModelSession?

    // Cache generated descriptions by option ID
    private var cache: [UUID: String] = [:]

    private init() {
        checkAvailability()
    }

    private func checkAvailability() {
        // TEMPORARILY DISABLED: Foundation Models crashes in iOS 26.2 Simulator
        // due to NLLanguageRecognizer.processString: assertion failure in Collection.suffix(from:)
        // TODO: Re-enable when Apple fixes the Foundation Models framework
        isAvailable = false
        return

        // Original code (disabled):
        // switch SystemLanguageModel.default.availability {
        // case .available:
        //     isAvailable = true
        //     session = LanguageModelSession(instructions: """
        //         You are a travel copywriter creating exciting, brief descriptions for sports road trips.
        //         Write in an enthusiastic but concise style. Focus on the adventure and variety of the trip.
        //         Keep descriptions to 1-2 short sentences maximum.
        //         """)
        // case .unavailable:
        //     isAvailable = false
        // }
    }

    /// Generate a brief, exciting description for a route option
    func generateDescription(for option: RouteDescriptionInput) async -> String? {
        // Check cache first
        if let cached = cache[option.id] {
            return cached
        }

        guard isAvailable, let session = session else {
            return nil
        }

        let prompt = buildPrompt(for: option)

        do {
            let response = try await session.respond(
                to: prompt,
                generating: RouteDescription.self
            )

            let description = response.content.description
            cache[option.id] = description
            return description

        } catch LanguageModelSession.GenerationError.guardrailViolation {
            return nil
        } catch LanguageModelSession.GenerationError.exceededContextWindowSize {
            // Reset session if context exceeded
            self.session = LanguageModelSession(instructions: """
                You are a travel copywriter creating exciting, brief descriptions for sports road trips.
                Write in an enthusiastic but concise style. Focus on the adventure and variety of the trip.
                Keep descriptions to 1-2 short sentences maximum.
                """)
            return nil
        } catch {
            return nil
        }
    }

    private func buildPrompt(for option: RouteDescriptionInput) -> String {
        let citiesText = option.cities.joined(separator: ", ")
        let sportsText = option.sports.isEmpty ? "sports" : option.sports.joined(separator: ", ")

        var details = [String]()
        details.append("\(option.totalGames) games")
        details.append("\(option.cities.count) cities: \(citiesText)")

        if option.totalMiles > 0 {
            details.append("\(Int(option.totalMiles)) miles")
        }
        if option.totalDrivingHours > 0 {
            details.append("\(String(format: "%.1f", option.totalDrivingHours)) hours driving")
        }

        return """
            Write a brief, exciting 1-sentence description for this sports road trip:
            - Route: \(citiesText)
            - Sports: \(sportsText)
            - Details: \(details.joined(separator: ", "))

            Make it sound like an adventure. Be concise.
            """
    }

    /// Clear the cache (e.g., when starting a new trip search)
    func clearCache() {
        cache.removeAll()
    }
}

// MARK: - Generable Types

@Generable
struct RouteDescription {
    @Guide(description: "A brief, exciting 1-2 sentence description of the road trip route")
    let description: String
}

// MARK: - Input Model

struct RouteDescriptionInput: Identifiable {
    let id: UUID
    let cities: [String]
    let sports: [String]
    let totalGames: Int
    let totalMiles: Double
    let totalDrivingHours: Double

    init(from option: ItineraryOption, games: [String: RichGame]) {
        self.id = option.id
        self.cities = Array(NSOrderedSet(array: option.stops.map { $0.city })) as? [String] ?? []

        // Extract sports from games
        let gameIds = option.stops.flatMap { $0.games }
        let sportSet = Set(gameIds.compactMap { games[$0]?.game.sport.rawValue })
        self.sports = Array(sportSet)

        self.totalGames = option.totalGames
        self.totalMiles = option.totalDistanceMiles
        self.totalDrivingHours = option.totalDrivingHours
    }
}
