openapi: 3.0.0
security:
  - BearerAuth: []

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

tags:
  - name: Promos
    description: API endpoints for managing promotional codes

paths:
  /api/promos:
    get:
      summary: Get all promos
      tags: [Promos]
      security:
        - BearerAuth: []
      responses:
        200:
          description: A list of all promos
        401:
          description: Unauthorized
        404:
          description: No promos found

    post:
      summary: Create a new promo
      tags: [Promos]
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - code
                - name
                - discountType
                - discountValue
                - validFrom
                - validTo
              properties:
                code:
                  type: string
                  example: "SAVE20"
                  description: Unique promo code (3-20 characters, uppercase letters and numbers only)
                name:
                  type: string
                  example: "20% Off Sale"
                  description: Name of the promotion
                description:
                  type: string
                  example: "Get 20% off on all orders"
                  description: Description of the promotion
                discountType:
                  type: string
                  enum: [percentage, fixed]
                  example: "percentage"
                  description: Type of discount (percentage or fixed)
                discountValue:
                  type: number
                  example: 20.0
                  description: Discount value (percentage or fixed amount)
                minOrderAmount:
                  type: number
                  example: 50.0
                  description: Minimum order amount required to use this promo
                maxDiscount:
                  type: number
                  example: 100.0
                  description: Maximum discount amount (for percentage discounts)
                validFrom:
                  type: string
                  format: date-time
                  example: "2024-01-01T00:00:00Z"
                  description: Start date and time of the promotion
                validTo:
                  type: string
                  format: date-time
                  example: "2024-12-31T23:59:59Z"
                  description: End date and time of the promotion
                usageLimit:
                  type: integer
                  example: 100
                  description: Maximum number of times this promo can be used
      responses:
        201:
          description: Promo created successfully
        400:
          description: Bad request (validation error or duplicate code)
        401:
          description: Unauthorized
        403:
          description: Forbidden (admin access required)

  /api/promos/active:
    get:
      summary: Get active promos
      tags: [Promos]
      description: Returns all currently active promos that are within their validity period
      responses:
        200:
          description: A list of active promos

  /api/promos/{id}:
    get:
      summary: Get a promo by ID
      tags: [Promos]
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The ID of the promo
      responses:
        200:
          description: A promo object
        401:
          description: Unauthorized
        404:
          description: Promo not found

    put:
      summary: Update a promo by ID
      tags: [Promos]
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The ID of the promo
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                  example: "SAVE25"
                  description: Promo code
                name:
                  type: string
                  example: "25% Off Sale"
                  description: Name of the promotion
                description:
                  type: string
                  example: "Get 25% off on all orders"
                  description: Description of the promotion
                discountType:
                  type: string
                  enum: [percentage, fixed]
                  example: "percentage"
                  description: Type of discount
                discountValue:
                  type: number
                  example: 25.0
                  description: Discount value
                minOrderAmount:
                  type: number
                  example: 50.0
                  description: Minimum order amount
                maxDiscount:
                  type: number
                  example: 150.0
                  description: Maximum discount amount
                validFrom:
                  type: string
                  format: date-time
                  example: "2024-01-01T00:00:00Z"
                  description: Start date and time
                validTo:
                  type: string
                  format: date-time
                  example: "2024-12-31T23:59:59Z"
                  description: End date and time
                usageLimit:
                  type: integer
                  example: 200
                  description: Maximum usage limit
      responses:
        200:
          description: Promo updated successfully
        400:
          description: Bad request
        401:
          description: Unauthorized
        403:
          description: Forbidden (admin access required)
        404:
          description: Promo not found

    delete:
      summary: Delete a promo by ID
      tags: [Promos]
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The ID of the promo
      responses:
        200:
          description: Promo deleted successfully
        401:
          description: Unauthorized
        403:
          description: Forbidden (admin access required)
        404:
          description: Promo not found

  /api/promos/code/{code}:
    get:
      summary: Get a promo by code
      tags: [Promos]
      description: Validates and returns a promo code (checks if active, valid dates, and usage limit)
      parameters:
        - name: code
          in: path
          required: true
          schema:
            type: string
          description: The promo code
          example: "SAVE20"
      responses:
        200:
          description: Valid promo code
        400:
          description: Promo is not valid (not active, expired, or usage limit reached)
        404:
          description: Promo not found

  /api/promos/{id}/status:
    patch:
      summary: Update promo status manually
      tags: [Promos]
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The ID of the promo
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: boolean
                  example: true
      responses:
        200:
          description: Promo status updated successfully
        400:
          description: Bad request
        401:
          description: Unauthorized
        403:
          description: Forbidden (admin access required)
        404:
          description: Promo not found