"/admin/media/item":
    post:
        tags: [Media]
        operationId: createMediaItem
        summary: Create a media item
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [title, cdn, cdnId]
                        properties:
                            title: { type: string }
                            cdn:
                                type: string
                                description: "CDN identifier (e.g. `cloudfront`, `bunny`)."
                            cdnId: { type: string }
                            type: { type: string, description: "`MediaType` value." }
                            isStereo: { type: boolean }
                            stereoPacking:
                                type: string
                                enum: [None, LeftRight, OverUnder]
                            stereoWidth:
                                type: string
                                enum: [Default, Half]
                            duration: { type: integer }
                            locationCodes:
                                type: array
                                items: { type: string }
                            audioFormats:
                                type: array
                                items: { type: string }
                            metaData:
                                type: object
                                additionalProperties: true
        responses:
            "200":
                description: Created media item.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/MediaItem.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]
    put:
        tags: [Media]
        operationId: updateMediaItem
        summary: Update a media item
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [id]
                        properties:
                            id: { type: string }
                            title: { type: string }
                            cdn: { type: string }
                            cdnId: { type: string }
                            type: { type: string }
                            isStereo: { type: boolean }
                            stereoPacking: { type: string }
                            stereoWidth: { type: string }
                            duration: { type: integer }
                            locationCodes:
                                type: array
                                items: { type: string }
                            audioFormats:
                                type: array
                                items: { type: string }
                            metaData:
                                type: object
                                additionalProperties: true
        responses:
            "200":
                description: Updated media item.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/MediaItem.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/items":
    get:
        tags: [Media]
        operationId: getMediaItems
        summary: List media items
        responses:
            "200":
                description: Array of media items.
                content:
                    application/json:
                        schema: { type: array, items: { $ref: "../components/schemas/MediaItem.yaml" } }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/item/{id}":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    get:
        tags: [Media]
        operationId: getMediaItem
        summary: Fetch a media item
        responses:
            "200":
                description: Media item.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/MediaItem.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Not found.
                content: { application/json: { schema: { $ref: "../admin-api.yaml#/components/schemas/Error" } } }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]
    delete:
        tags: [Media]
        operationId: deleteMediaItem
        summary: Delete a media item
        responses:
            "200":
                description: Deleted.
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Not found.
                content: { application/json: { schema: { $ref: "../admin-api.yaml#/components/schemas/Error" } } }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/cdn/{cdn}/{cdnId}":
    parameters:
        - in: path
          name: cdn
          required: true
          schema: { type: string }
          description: CDN name (e.g. `cloudfront`, `bunny`).
        - in: path
          name: cdnId
          required: true
          schema: { type: string }
          description: CDN-side identifier for the asset.
    get:
        tags: [Media]
        operationId: getCDNInfo
        summary: CDN info for a media asset
        responses:
            "200":
                description: CDN info payload — passthrough from the CDN provider, shape depends on `cdn`.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                cdn: { type: string }
                                cdnId: { type: string }
                                duration:
                                    type: integer
                                    description: Asset duration in milliseconds.
                                resolution: { type: string, description: "e.g. `1920x1080`." }
                                bitrate: { type: integer }
                                tracks:
                                    type: object
                                    properties:
                                        audio:
                                            type: array
                                            items: { type: string }
                                        subtitle:
                                            type: array
                                            items: { type: string }
                                raw:
                                    type: object
                                    additionalProperties: true
                                    description: Raw provider-specific payload.
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/schemas":
    get:
        tags: [Media]
        operationId: getMediaSchemas
        summary: Media schema enumerations
        responses:
            "200":
                description: |
                    Schema enumerations — `EntitlementClass`, `EntitlementStatus`,
                    `MediaType`, `ProductStatus`, etc. Keys are the enum names; values are
                    the string members.
                content:
                    application/json:
                        schema:
                            type: object
                            additionalProperties:
                                type: array
                                items: { type: string }
                            description: Each top-level key is an enum name; the value is the list of legal members.
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/query":
    post:
        tags: [Media]
        operationId: getMediaQuery
        summary: Run a media query
        description: |
            Runs a free-form media query — body shape is whatever the handler accepts
            today (filters by id list, bigMediaId list, status, etc.). Result is keyed
            by the entity type returned (`mediaItems`, `mediaProducts`, …).
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            ids:
                                type: array
                                items: { type: string }
                            bigMediaIds:
                                type: array
                                items: { type: string }
                            status:
                                type: string
                                description: "`ProductStatus` filter."
                            limit: { type: integer }
                            offset: { type: integer }
                        additionalProperties: true
        responses:
            "200":
                description: Query result.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                mediaItems:
                                    type: array
                                    items: { $ref: "../components/schemas/MediaItem.yaml" }
                                mediaProducts:
                                    type: array
                                    items: { $ref: "../components/schemas/MediaProduct.yaml" }
                                count: { type: integer }
                            additionalProperties: true
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/product":
    post:
        tags: [Media]
        operationId: createProduct
        summary: Create a media product
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [title]
                        properties:
                            title: { type: string }
                            description: { type: string }
                            bigMediaId: { type: string, description: Public id; auto-generated when blank. }
                            status: { type: string, description: "`ProductStatus` value." }
                            mediaItemIds:
                                type: array
                                items: { type: string }
                            entitlementClass: { type: string }
                            synchronizationInterval: { type: integer, minimum: 0, maximum: 30 }
                            locationCodes:
                                type: array
                                items: { type: string }
                            is3D: { type: boolean }
                            loops: { type: boolean }
                            duration: { type: integer }
                            marketingData:
                                type: object
                                additionalProperties: true
        responses:
            "200":
                description: Created product.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/MediaProduct.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]
    put:
        tags: [Media]
        operationId: updateProduct
        summary: Update a media product
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [id]
                        properties:
                            id: { type: string }
                            title: { type: string }
                            description: { type: string }
                            status: { type: string }
                            mediaItemIds:
                                type: array
                                items: { type: string }
                            entitlementClass: { type: string }
                            synchronizationInterval: { type: integer }
                            locationCodes:
                                type: array
                                items: { type: string }
                            is3D: { type: boolean }
                            loops: { type: boolean }
                            duration: { type: integer }
                            marketingData:
                                type: object
                                additionalProperties: true
        responses:
            "200":
                description: Updated product.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/MediaProduct.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/product/{id}":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    get:
        tags: [Media]
        operationId: getProduct
        summary: Fetch a media product
        responses:
            "200":
                description: Product record.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/MediaProduct.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Not found.
                content: { application/json: { schema: { $ref: "../admin-api.yaml#/components/schemas/Error" } } }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]
    delete:
        tags: [Media]
        operationId: deleteProduct
        summary: Delete a media product
        responses:
            "200":
                description: Product deleted.
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Not found.
                content: { application/json: { schema: { $ref: "../admin-api.yaml#/components/schemas/Error" } } }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/products":
    get:
        tags: [Media]
        operationId: getProducts
        summary: List media products
        responses:
            "200":
                description: Array of products.
                content:
                    application/json:
                        schema: { type: array, items: { $ref: "../components/schemas/MediaProduct.yaml" } }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/product/{id}/sku":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
          description: Product id.
    post:
        tags: [Media]
        operationId: createProductSKU
        summary: Create a SKU on a product
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            id: { type: string, description: Stripe / Oculus IAP SKU id. }
                            price: { type: number }
                            currency: { type: string, example: "USD" }
                            entitlementClass: { type: string }
                        additionalProperties: true
        responses:
            "200":
                description: Created SKU.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                id: { type: string }
                                price: { type: number }
                                currency: { type: string }
                                entitlementClass: { type: string }
                                productId: { type: string }
                                createdAt: { type: string, format: date-time }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/product/{id}/sku/{skuId}":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
        - in: path
          name: skuId
          required: true
          schema: { type: string }
    delete:
        tags: [Media]
        operationId: deleteProductSKU
        summary: Delete a SKU on a product
        responses:
            "200":
                description: SKU deleted.
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Not found.
                content: { application/json: { schema: { $ref: "../admin-api.yaml#/components/schemas/Error" } } }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/showings/{synchronizationInterval}/{past}/{future}":
    parameters:
        - in: path
          name: synchronizationInterval
          required: true
          schema: { type: string }
          description: Synchronization interval identifier.
        - in: path
          name: past
          required: true
          schema: { type: string }
          description: |
              How far back to look (e.g. number of intervals). Optional in the underlying
              route (`/showings/:synchronizationInterval{/:past}{/:future}`) — when omitted,
              defaults are applied server-side.
        - in: path
          name: future
          required: true
          schema: { type: string }
          description: How far forward to look. Optional in the underlying route.
    get:
        tags: [Media]
        operationId: getShowings
        summary: Media showings for a time window
        description: Returns scheduled media showings within the supplied time window. The trailing `past` and `future` segments are optional in the underlying route.
        responses:
            "200":
                description: Showings payload.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                synchronizationInterval: { type: string }
                                showings:
                                    type: array
                                    items:
                                        type: object
                                        properties:
                                            mediaProductId: { type: string }
                                            bigMediaId: { type: string }
                                            startTimestamp: { type: string, format: date-time }
                                            endTimestamp: { type: string, format: date-time }
                                            durationMs: { type: integer }
                                        additionalProperties: true
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/events/{productId}":
    parameters:
        - in: path
          name: productId
          required: true
          schema: { type: string }
    get:
        tags: [Media]
        operationId: getMediaSessionEvents
        summary: Media session events for a product
        description: Returns media session events (plays, completions, abandons) for a specific product.
        responses:
            "200":
                description: Events payload.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                productId: { type: string }
                                events:
                                    type: array
                                    items:
                                        type: object
                                        properties:
                                            id: { type: string }
                                            eventType:
                                                type: string
                                                description: "e.g. `play`, `complete`, `abandon`."
                                            bigscreenAccountId: { type: string }
                                            timestamp: { type: string, format: date-time }
                                            durationMs: { type: integer }
                                        additionalProperties: true
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/products/export":
    get:
        tags: [Media]
        operationId: exportMediaProductsTSV
        summary: Export media products as TSV
        description: Streams a TSV of all media products. Auth requirement is stricter than the default Admin-only — also accepts SuperUser.
        responses:
            "200":
                description: TSV stream.
                content:
                    text/tab-separated-values:
                        schema:
                            type: string
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [SuperUser, Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/entitlement":
    post:
        tags: [Media]
        operationId: adminCreateEntitlement
        summary: Create an entitlement
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [bigscreenAccountId, mediaProductId, entitlementClass]
                        properties:
                            bigscreenAccountId: { type: string }
                            mediaProductId: { type: string }
                            bigMediaId: { type: string }
                            entitlementClass: { type: string }
                            maxAllowedSessions: { type: integer }
                            activationTimestamp: { type: string, format: date-time }
                            expirationTimestamp: { type: string, format: date-time }
                        additionalProperties: true
        responses:
            "200":
                description: Created entitlement.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/Entitlement.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/entitlement/{id}":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    put:
        tags: [Media]
        operationId: adminUpdateEntitlement
        summary: Update an entitlement
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            status: { type: string }
                            expirationTimestamp: { type: string, format: date-time }
                            maxAllowedSessions: { type: integer }
                        additionalProperties: true
        responses:
            "200":
                description: Updated entitlement.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/Entitlement.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Not found.
                content: { application/json: { schema: { $ref: "../admin-api.yaml#/components/schemas/Error" } } }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]
    get:
        tags: [Media]
        operationId: getEntitlement
        summary: Fetch an entitlement
        responses:
            "200":
                description: Entitlement record.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/Entitlement.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Not found.
                content: { application/json: { schema: { $ref: "../admin-api.yaml#/components/schemas/Error" } } }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/entitlements/query":
    post:
        tags: [Media]
        operationId: searchEntitlements
        summary: Search entitlements
        description: Searches entitlements with a query body.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            bigscreenAccountId: { type: string }
                            mediaProductId: { type: string }
                            bigMediaId: { type: string }
                            entitlementClass: { type: string }
                            status: { type: string }
                            limit: { type: integer }
                            offset: { type: integer }
                        additionalProperties: true
        responses:
            "200":
                description: Matching entitlements.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                items:
                                    type: array
                                    items: { $ref: "../components/schemas/Entitlement.yaml" }
                                count: { type: integer }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/entitlements":
    get:
        tags: [Media]
        operationId: getEntitlements
        summary: List entitlements
        responses:
            "200":
                description: Array of entitlements.
                content:
                    application/json:
                        schema: { type: array, items: { $ref: "../components/schemas/Entitlement.yaml" } }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/entitlements/export":
    get:
        tags: [Media]
        operationId: exportEntitlementsCSV
        summary: Export entitlements as CSV
        description: Streams a CSV of every entitlement. SuperUser-only.
        responses:
            "200":
                description: CSV stream.
                content:
                    text/csv:
                        schema:
                            type: string
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [SuperUser]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/category":
    post:
        tags: [Media]
        operationId: adminCreateCategory
        summary: Create a category
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [title]
                        properties:
                            title: { type: string }
                            description: { type: string }
                            entitlementClass: { type: string }
                            isScheduled: { type: boolean }
                        additionalProperties: true
        responses:
            "200":
                description: Created category.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/MediaCategory.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]
    put:
        tags: [Media]
        operationId: adminUpdateCategory
        summary: Update a category
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [id]
                        properties:
                            id: { type: string }
                        additionalProperties: true
        responses:
            "200":
                description: Updated category.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/MediaCategory.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]
    get:
        tags: [Media]
        operationId: adminGetCategory
        summary: Fetch a single category
        description: Returns a single category. The id is supplied via query string.
        responses:
            "200":
                description: Category record.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/MediaCategory.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/categories":
    get:
        tags: [Media]
        operationId: adminGetCategories
        summary: List categories
        responses:
            "200":
                description: Array of categories.
                content:
                    application/json:
                        schema: { type: array, items: { $ref: "../components/schemas/MediaCategory.yaml" } }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/category/{id}":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    delete:
        tags: [Media]
        operationId: deleteModeratorCategory
        summary: Delete a category
        responses:
            "200":
                description: Category deleted.
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/collection":
    post:
        tags: [Media]
        operationId: adminCreateProductCollection
        summary: Create a product collection
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [name]
                        properties:
                            name: { type: string }
                            startTimestamp: { type: string, format: date-time }
                            endTimestamp: { type: string, format: date-time }
                            mediaProductIds:
                                type: array
                                items: { type: string }
                            isPublished: { type: boolean }
                        additionalProperties: true
        responses:
            "200":
                description: Created collection.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/ProductCollection.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]
    put:
        tags: [Media]
        operationId: adminUpdateProductCollection
        summary: Update a product collection
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [id]
                        properties:
                            id: { type: string }
                        additionalProperties: true
        responses:
            "200":
                description: Updated collection.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/ProductCollection.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/collections":
    get:
        tags: [Media]
        operationId: adminGetProductCollections
        summary: List product collections
        responses:
            "200":
                description: Array of collections.
                content:
                    application/json:
                        schema: { type: array, items: { $ref: "../components/schemas/ProductCollection.yaml" } }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/collection/{id}":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    get:
        tags: [Media]
        operationId: adminGetProductCollection
        summary: Fetch a product collection
        responses:
            "200":
                description: Collection record.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/ProductCollection.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Not found.
                content: { application/json: { schema: { $ref: "../admin-api.yaml#/components/schemas/Error" } } }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]
    delete:
        tags: [Media]
        operationId: deleteModeratorProductCollection
        summary: Delete a product collection
        responses:
            "200":
                description: Collection deleted.
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/coupons":
    post:
        tags: [Media]
        operationId: generateCoupons
        summary: Generate coupons
        description: Generates a batch of coupons.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            count: { type: integer, description: Number of coupons to mint. }
                            entitlementClass: { type: string }
                            bigMediaId: { type: string, description: Optional — restrict to a specific media product. }
                            expirationTimestamp: { type: string, format: date-time }
                        additionalProperties: true
        responses:
            "200":
                description: Generated coupons.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                coupons:
                                    type: array
                                    items: { $ref: "../components/schemas/Coupon.yaml" }
                                count: { type: integer }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]
    get:
        tags: [Media]
        operationId: getCoupons
        summary: List coupons
        responses:
            "200":
                description: Array of coupons.
                content:
                    application/json:
                        schema: { type: array, items: { $ref: "../components/schemas/Coupon.yaml" } }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/coupon":
    put:
        tags: [Media]
        operationId: updateCoupon
        summary: Update a coupon
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [id]
                        properties:
                            id: { type: string }
                            expirationTimestamp: { type: string, format: date-time }
                        additionalProperties: true
        responses:
            "200":
                description: Updated coupon.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/Coupon.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/coupon/{id}":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    get:
        tags: [Media]
        operationId: getCoupon
        summary: Fetch a coupon
        responses:
            "200":
                description: Coupon record.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/Coupon.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Not found.
                content: { application/json: { schema: { $ref: "../admin-api.yaml#/components/schemas/Error" } } }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]
    delete:
        tags: [Media]
        operationId: deleteCoupon
        summary: Delete a coupon
        responses:
            "200":
                description: Coupon deleted.
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:write", "admin:all"]

"/admin/media/rebuild/category/{id}":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    get:
        tags: [Media]
        operationId: rebuildCategoryTextures
        summary: Rebuild category textures
        description: Triggers a texture rebuild for the supplied category.
        responses:
            "200":
                description: Rebuild result.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                categoryId: { type: string }
                                texturesRebuilt: { type: integer }
                                durationMs: { type: integer }
                                errors:
                                    type: array
                                    items: { type: string }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]

"/admin/media/rebuild/skus":
    get:
        tags: [Media]
        operationId: rebuildProductSkus
        summary: Rebuild all product SKUs
        description: Triggers a rebuild of every product SKU.
        responses:
            "200":
                description: Rebuild result.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                productsProcessed: { type: integer }
                                skusRebuilt: { type: integer }
                                durationMs: { type: integer }
                                errors:
                                    type: array
                                    items: { type: string }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["media:read", "admin:all"]
