paths:
  /merchants/ip-whitelist:
    get:
      summary: Get all IP whitelists for merchant
      tags: [Merchants]
      security:
        - bearerAuth: []
      responses:
        '200':
          description: List of IP whitelists
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          format: uuid
                        ipAddress:
                          type: string
                          example: "192.168.1.100"
                        description:
                          type: string
                          example: "Office Network"

    post:
      summary: Add a new IP to whitelist
      tags: [Merchants]
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ipAddress:
                  type: string
                  example: "203.0.113.45"
                description:
                  type: string
                  example: "Remote Developer VPN"
      responses:
        '201':
          description: IP whitelist added
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "IP Address added to whitelist successfully"
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid

  /merchants/ip-whitelist/{id}:
    delete:
      summary: Delete an IP from whitelist
      tags: [Merchants]
      security:
        - bearerAuth: []
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: IP whitelist deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "IP address removed from whitelist"

  /merchants/pricing:
    get:
      summary: Get service pricings
      tags: [Merchants]
      security:
        - bearerAuth: []
      responses:
        '200':
          description: List of service pricings
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        serviceType:
                          type: string
                          example: "Transfer"
                        fee:
                          type: number
                          example: 20
                        type:
                          type: string
                          example: "fixed"

  /merchants/rates:
    get:
      summary: Get exchange rates
      description: >-
        Returns configured exchange rates. Without `targetCurrency`, returns an array of every
        rate configured for `baseCurrency` (defaults to NGN). With both `baseCurrency` and
        `targetCurrency`, returns a single rate object instead of an array. `platformRate`
        already includes the platform's margin and is what's actually used for swaps —
        `liveRate` is the raw upstream rate before margin.
      tags: [Merchants]
      security:
        - bearerAuth: []
      parameters:
        - in: query
          name: baseCurrency
          schema:
            type: string
            default: NGN
          example: "NGN"
        - in: query
          name: targetCurrency
          schema:
            type: string
          example: "USD"
      responses:
        '200':
          description: Exchange rate(s)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          format: uuid
                        baseCurrency:
                          type: string
                          example: "NGN"
                        targetCurrency:
                          type: string
                          example: "USD"
                        liveRate:
                          type: number
                          example: 1620.50
                        platformRate:
                          type: number
                          example: 1635.50
                        rateSource:
                          type: string
                          example: "wewire"
                        margin:
                          type: number
                          example: 15
                        marginOperation:
                          type: string
                          enum: [add, subtract]
                          example: "add"
                        updatedAt:
                          type: string
                          format: date-time

  /merchants/wallets:
    get:
      summary: List the merchant's wallet balances
      description: >-
        Returns the merchant's native NGN balance plus any other currency wallets that have
        been enabled for merchants by an admin (see `/admin/currencies/{code}/virtual-account-status`).
        A wallet's `status` is `active` or `inactive` — inactive wallets keep their balance but
        can't be swapped into or out of.
      tags: [Merchants]
      security:
        - bearerAuth: []
      responses:
        '200':
          description: List of wallets
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        currency:
                          type: string
                          example: "USD"
                        balance:
                          type: number
                          example: 120.50
                        status:
                          type: string
                          enum: [active, inactive]
                          example: "active"
                        updatedAt:
                          type: string
                          format: date-time

  /merchants/wallets/swap:
    post:
      summary: Swap between the merchant's own currency wallets
      description: >-
        `amount` is denominated in `targetCurrency` — e.g. `{ baseCurrency: "NGN", targetCurrency:
        "USD", amount: 100 }` converts NGN into exactly 100 USD, debiting the computed NGN cost
        (at the admin-configured platform rate) from the NGN wallet. Swapping the reverse direction
        requires the admin to have separately configured that direction's exchange rate — it is
        not automatically inverted. Both currencies must have `virtualAccountStatus: active`
        (NGN is always allowed).
      tags: [Merchants]
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [baseCurrency, targetCurrency, amount]
              properties:
                baseCurrency:
                  type: string
                  example: "NGN"
                targetCurrency:
                  type: string
                  example: "USD"
                amount:
                  type: number
                  description: Amount of targetCurrency to receive
                  example: 100
      responses:
        '200':
          description: Swap completed
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "Swapped 162550.00 NGN for 100 USD."
                  data:
                    type: object
                    properties:
                      baseCurrency:
                        type: string
                        example: "NGN"
                      targetCurrency:
                        type: string
                        example: "USD"
                      amountReceived:
                        type: number
                        example: 100
                      amountDebited:
                        type: number
                        example: 162550.00
                      platformRate:
                        type: number
                        example: 1625.50
        '400':
          description: >-
            Validation error — same currency on both sides, currency not available/enabled for
            wallets, wallet inactive, or no exchange rate configured for that exact direction.
        '422':
          description: Insufficient balance in the base currency wallet.
