import SwiftUI
import FoundationModels
import Observation

@Observable class ApplicationData {
   var response: AttributedString = ""
   var prompt: String = ""

   @ObservationIgnored var session: LanguageModelSession

   static let shared: ApplicationData = ApplicationData()
   private init() {
      let instructions = "Determine the city the user is talking about, and return information about it"
      session = LanguageModelSession(instructions: instructions)
   }
   func sendPrompt() async {
      do {
         let citySchema = try createSchema(max: 3)
         let answer = try await session.respond(to: prompt, schema: citySchema)

         let city = try answer.content.value(String.self, forProperty: "city")
         let country = try answer.content.value(String.self, forProperty: "country")
         let language = try answer.content.value(String.self, forProperty: "language")
         let currency = try answer.content.value(String.self, forProperty: "currency")
         let attractions = try answer.content.value([String].self, forProperty: "attractions")

         var message = "City: \(city)\n"
         message += "Country: \(country)\n"
         message += "Language: \(language)\n"
         message += "Currency: \(currency)\n"
         message += "Attractions: \(attractions.joined(separator: ", "))\n"

         var newResponse = AttributedString("\(message)\n\n")
         newResponse.font = .system(size: 16, weight: .regular)
         response.append(newResponse)
      } catch {
         response.append(AttributedString("Error accessing the model: \(error)\n\n"))
      }
      prompt = ""
   }
   func createSchema(max: Int) throws -> GenerationSchema {
      let type = DynamicGenerationSchema(
          name: "CityResponse",
          properties: [
            DynamicGenerationSchema.Property(name: "city", description: "The name of the city", schema: DynamicGenerationSchema(type: String.self)),
            DynamicGenerationSchema.Property(name: "country", description: "The name of the country the city belongs to", schema: DynamicGenerationSchema(type: String.self)),
            DynamicGenerationSchema.Property(name: "language", description: "The main language spoken in the city", schema: DynamicGenerationSchema(type: String.self)),
            DynamicGenerationSchema.Property(name: "currency", description: "The currency used in the city", schema: DynamicGenerationSchema(type: String.self)),
            DynamicGenerationSchema.Property(name: "attractions", description: "A list of attractions in the city", schema: DynamicGenerationSchema (arrayOf: DynamicGenerationSchema(type: String.self), minimumElements: max, maximumElements: max))
          ]
      )
      let schema = try GenerationSchema(root: type, dependencies: [])
      return schema
   }
}