// Generated by Create API
// https://github.com/CreateAPI/CreateAPI

import Foundation

public struct BannerWebGraphicSchema: Codable, Equatable, Identifiable {
    public var bannerType: BannerType?
    public var campaignName: String?
    /// BannerCollapsedContentSchema
    public var collapsedContent: BannerCollapsedContentSchema?
    public var countries: [String]?
    public var endTime: Date?
    public var heroBackgroundAlignment: String?
    public var heroBackgroundAlignmentMobile: String?
    public var heroBackgroundColor: String?
    public var heroBackgroundImgUrl: String?
    public var heroBackgroundImgUrlMobile: String?
    public var heroBackgroundOverlay: String?
    public var heroBackgroundOverlayMobile: String?
    public var heroBackgroundVideoUrl: String?
    public var heroBackgroundVideoUrlMobile: String?
    public var id: String?
    /// BannerCtaSchema
    public var primaryCta: BannerCtaSchema?
    /// BannerCtaSchema
    public var secondaryCta: BannerCtaSchema?
    public var startTime: Date?
    public var subtitleText: LocalStringSchema?
    /// BannerTagSchema
    public var tag: BannerTagSchema?
    public var templateId: String?
    public var tiles: [Tile]?
    public var titleText: LocalStringSchema?
    public var type: `Type`?
    public var visible: Bool

    public struct BannerType: RawRepresentable, Codable, Equatable {
        public let rawValue: String

        public init(rawValue: String) {
            self.rawValue = rawValue
        }

        public static let modelPromo = Self(rawValue: "model_promo")
        public static let remixContest = Self(rawValue: "remix_contest")
    }

    public struct Tile: Codable, Equatable {
        public var object: Object?
        public var anyJSON: AnyJSON?

        public enum Object: Codable, Equatable {
            case bannerSongCardSchema(BannerSongCardSchema)
            case bannerGraphicCardSchema(BannerGraphicCardSchema)

            public init(from decoder: Decoder) throws {

                struct Discriminator: Decodable {
                    let type: String
                }

                let container = try decoder.singleValueContainer()
                let discriminatorValue = try container.decode(Discriminator.self).type

                switch discriminatorValue {
                case "song_card": self = .bannerSongCardSchema(try container.decode(BannerSongCardSchema.self))
                case "graphic_card": self = .bannerGraphicCardSchema(try container.decode(BannerGraphicCardSchema.self))

                default:
                    throw DecodingError.dataCorruptedError(
                        in: container,
                        debugDescription: "Discriminator value '\(discriminatorValue)' does not match any expected values (song_card, graphic_card)."
                    )
                }
            }

            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                switch self {
                case .bannerSongCardSchema(let value): try container.encode(value)
                case .bannerGraphicCardSchema(let value): try container.encode(value)
                }
            }
        }

        public init(object: Object? = nil, anyJSON: AnyJSON? = nil) {
            self.object = object
            self.anyJSON = anyJSON
        }

        public init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            self.object = try? container.decode(Object.self)
            self.anyJSON = try? container.decode(AnyJSON.self)
        }

        public func encode(to encoder: Encoder) throws {
            var container = encoder.singleValueContainer()
            if let value = object { try container.encode(value) }
            if let value = anyJSON { try container.encode(value) }
        }
    }

    /// Type
    public struct `Type`: RawRepresentable, Codable, Equatable {
        public let rawValue: String

        public init(rawValue: String) {
            self.rawValue = rawValue
        }

        public static let web = Self(rawValue: "web")
        public static let mobileWeb = Self(rawValue: "mobile-web")
    }

    public init(bannerType: BannerType? = nil, campaignName: String? = nil, collapsedContent: BannerCollapsedContentSchema? = nil, countries: [String]? = nil, endTime: Date? = nil, heroBackgroundAlignment: String? = nil, heroBackgroundAlignmentMobile: String? = nil, heroBackgroundColor: String? = nil, heroBackgroundImgUrl: String? = nil, heroBackgroundImgUrlMobile: String? = nil, heroBackgroundOverlay: String? = nil, heroBackgroundOverlayMobile: String? = nil, heroBackgroundVideoUrl: String? = nil, heroBackgroundVideoUrlMobile: String? = nil, id: String? = nil, primaryCta: BannerCtaSchema? = nil, secondaryCta: BannerCtaSchema? = nil, startTime: Date? = nil, subtitleText: LocalStringSchema? = nil, tag: BannerTagSchema? = nil, templateId: String? = nil, tiles: [Tile]? = nil, titleText: LocalStringSchema? = nil, type: `Type`? = nil, visible: Bool? = nil) {
        self.bannerType = bannerType
        self.campaignName = campaignName
        self.collapsedContent = collapsedContent
        self.countries = countries
        self.endTime = endTime
        self.heroBackgroundAlignment = heroBackgroundAlignment
        self.heroBackgroundAlignmentMobile = heroBackgroundAlignmentMobile
        self.heroBackgroundColor = heroBackgroundColor
        self.heroBackgroundImgUrl = heroBackgroundImgUrl
        self.heroBackgroundImgUrlMobile = heroBackgroundImgUrlMobile
        self.heroBackgroundOverlay = heroBackgroundOverlay
        self.heroBackgroundOverlayMobile = heroBackgroundOverlayMobile
        self.heroBackgroundVideoUrl = heroBackgroundVideoUrl
        self.heroBackgroundVideoUrlMobile = heroBackgroundVideoUrlMobile
        self.id = id
        self.primaryCta = primaryCta
        self.secondaryCta = secondaryCta
        self.startTime = startTime
        self.subtitleText = subtitleText
        self.tag = tag
        self.templateId = templateId
        self.tiles = tiles
        self.titleText = titleText
        self.type = type
        self.visible = visible ?? false
    }
}
