//
//  CreateImageParameters.swift
//  SwiftOpenAI
//
//  Created by James Rochabrun on 4/24/25.
//

import Foundation

/// 'Create Image':
/// https://platform.openai.com/docs/api-reference/images/create
public struct CreateImageParameters: Encodable {
  /// Creates a new instance of CreateImageParameters
  /// - Parameters:
  ///   - prompt: A text description of the desired image(s)
  ///   - background: Transparency setting for the background (gpt-image-1 only)
  ///   - model: The model to use for image generation
  ///   - moderation: Content moderation level (gpt-image-1 only)
  ///   - n: Number of images to generate (1-10)
  ///   - outputCompression: Compression level for images (gpt-image-1 only)
  ///   - outputFormat: Format for generated images (gpt-image-1 only)
  ///   - quality: Quality of generated images
  ///   - responseFormat: Format for response (url or b64_json)
  ///   - size: Size of generated images
  ///   - style: Style of generated images (dall-e-3 only)
  ///   - user: Unique identifier for end-user
  public init(
    prompt: String,
    background: CreateImageParameters.Background? = nil,
    model: CreateImageParameters.Model? = nil,
    moderation: CreateImageParameters.Moderation? = nil,
    n: Int? = nil,
    outputCompression: Int? = nil,
    outputFormat: CreateImageParameters.OutputFormat? = nil,
    quality: CreateImageParameters.Quality? = nil,
    responseFormat: CreateImageParameters.ResponseFormat? = nil,
    size: String? = nil,
    style: CreateImageParameters.Style? = nil,
    user: String? = nil)
  {
    self.prompt = prompt
    self.background = background
    self.model = model
    self.moderation = moderation
    self.n = n
    self.outputCompression = outputCompression
    self.outputFormat = outputFormat
    self.quality = quality
    self.responseFormat = responseFormat
    self.size = size
    self.style = style
    self.user = user
  }

  /// Background transparency options for gpt-image-1
  public enum Background: String, Encodable {
    case auto
    case opaque
    case transparent
  }

  /// Available models for image generation
  public enum Model: String, Encodable {
    case dallE2 = "dall-e-2"
    case dallE3 = "dall-e-3"
    case gptImage1 = "gpt-image-1"
  }

  /// Content moderation level for gpt-image-1
  public enum Moderation: String, Encodable {
    case auto
    case low
  }

  /// Output format options for gpt-image-1
  public enum OutputFormat: String, Encodable {
    case jpeg
    case png
    case webp
  }

  /// Quality options for generated images
  public enum Quality: String, Encodable {
    /// Automatically select the best quality for the given model
    case auto

    /// Supported for gpt-image-1
    case high, medium, low

    /// Supported for dall-e-3
    case hd, standard
  }

  /// Response format options
  public enum ResponseFormat: String, Encodable {
    case b64JSON = "b64_json"
    case url
  }

  /// Style options for dall-e-3
  public enum Style: String, Encodable {
    case vivid
    case natural
  }

  /// A text description of the desired image(s).
  /// The maximum length is 32000 characters for `gpt-image-1`, 1000 characters for `dall-e-2` and 4000 characters for `dall-e-3`.
  public let prompt: String

  // MARK: - Optional properties

  /// Allows to set transparency for the background of the generated image(s).
  /// This parameter is only supported for `gpt-image-1`.
  /// Must be one of `transparent`, `opaque` or `auto` (default value).
  /// When `auto` is used, the model will automatically determine the best background for the image.
  /// If `transparent`, the output format needs to support transparency, so it should be set to either `png` (default value) or `webp`.
  public let background: Background?

  /// The model to use for image generation. One of `dall-e-2`, `dall-e-3`, or `gpt-image-1`.
  /// Defaults to `dall-e-2` unless a parameter specific to `gpt-image-1` is used.
  public let model: Model?

  /// Control the content-moderation level for images generated by `gpt-image-1`.
  /// Must be either low for less restrictive filtering or auto (default value).
  public let moderation: Moderation?

  /// The number of images to generate. Must be between 1 and 10. For `dall-e-3`, only `n=1` is supported.
  /// Defaults to `1`
  public let n: Int?

  /// The compression level (0-100%) for the generated images.
  /// This parameter is only supported for `gpt-image-1` with the `webp` or `jpeg` output formats, and defaults to 100.
  public let outputCompression: Int?

  /// The format in which the generated images are returned.
  /// This parameter is only supported for `gpt-image-1`.
  /// Must be one of `png`, `jpeg`, or `webp`.
  public let outputFormat: OutputFormat?

  /// The quality of the image that will be generated.
  /// - `auto` (default value) will automatically select the best quality for the given model.
  /// - `high`, `medium` and `low` are supported for gpt-image-1.
  /// - `hd` and `standard` are supported for dall-e-3.
  /// - `standard` is the only option for dall-e-2.
  public let quality: Quality?

  /// The format in which generated images with dall-e-2 and dall-e-3 are returned.
  /// Must be one of `url` or `b64_json`.
  /// URLs are only valid for 60 minutes after the image has been generated.
  /// This parameter isn't supported for `gpt-image-1` which will always return base64-encoded images.
  public let responseFormat: ResponseFormat?

  /// The size of the generated images.
  /// - For gpt-image-1, one of `1024x1024`, `1536x1024` (landscape), `1024x1536` (portrait), or `auto` (default value)
  /// - For dall-e-3, one of `1024x1024`, `1792x1024`, or `1024x1792`
  /// - For dall-e-2, one of `256x256`, `512x512`, or `1024x1024`
  public let size: String?

  /// The style of the generated images.
  /// This parameter is only supported for `dall-e-3`.
  /// Must be one of `vivid` or `natural`.
  /// Vivid causes the model to lean towards generating hyper-real and dramatic images.
  /// Natural causes the model to produce more natural, less hyper-real looking images.
  public let style: Style?

  /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse.
  public let user: String?

  enum CodingKeys: String, CodingKey {
    case prompt
    case background
    case model
    case moderation
    case n
    case outputCompression = "output_compression"
    case outputFormat = "output_format"
    case quality
    case responseFormat = "response_format"
    case size
    case style
    case user
  }
}
