openapi: 3.0.0
info:
  title: API de Registro de Ofertas (Anatel PoC)
  version: "1.0.0"
  description: |-
    API para registrar e consultar ofertas de telecomunicações, baseada nas especificações da Anatel.
    Esta é uma Prova de Conceito (PoC) que utiliza um arquivo JSON para persistência de dados.
servers:
  - url: http://localhost:3000/api # Altere para o URL de produção se necessário
    description: Servidor de Desenvolvimento Local

tags:
  - name: Ofertas
    description: Operações relacionadas a ofertas de telecomunicações

paths:
  /ofertas:
    post:
      tags:
        - Ofertas
      summary: Registra uma nova oferta
      description: Valida e armazena uma nova oferta de telecomunicações no sistema.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OfertaInput'
      responses:
        '200': # Sua API está retornando 200 para POST bem-sucedido
          description: Oferta registrada com sucesso e código único gerado.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "Oferta registrada com sucesso e código único gerado."
                  codigoOferta:
                    type: string
                    description: Código numérico aleatório de 8 dígitos gerado para a oferta.
                    example: "12345678"
                  oferta:
                    $ref: '#/components/schemas/Oferta'
        '400':
          description: Erro de validação nos dados da oferta.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseValidation'
        '500':
          description: Erro interno do servidor.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseGeneric'
    get:
      tags:
        - Ofertas
      summary: Lista todas as ofertas registradas
      description: Retorna uma lista de todas as ofertas atualmente armazenadas no sistema.
      responses:
        '200':
          description: Lista de ofertas recuperada com sucesso.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "Ofertas recuperadas com sucesso."
                  totalOffers:
                    type: integer
                    format: int32
                    example: 10
                  offers:
                    type: array
                    items:
                      $ref: '#/components/schemas/Oferta'
        '500':
          description: Erro interno do servidor.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseGeneric'

components:
  schemas:
    OfertaBase: # Campos comuns entre Input e Output
      type: object
      properties:
        identificadorUnico:
          type: string
          maxLength: 255
          description: Identificador único da oferta fornecido pela prestadora.
          example: "PLANO_FIBRA_500MB_XYZ"
        tipoOferta:
          type: string
          enum: [Individual, Conjunta]
          description: Tipo da oferta.
          example: "Individual"
        nomeOferta:
          type: string
          maxLength: 100
          description: Nome comercial da oferta.
          example: "Plano Fibra Ótica 500 Mega"
        custoInicial:
          $ref: '#/components/schemas/CustoInicial'
        etiquetaOferta:
          type: string
          nullable: true
          description: Etiqueta interna da oferta (opcional).
          example: "PROMO_Q2_2025"
        linkSite:
          type: string
          format: url
          description: Link para a página da oferta no site da prestadora.
          example: "https://meuprovedor.com/ofertas/fibra500"
        dataInicioOferta:
          type: string
          # format: date # O formato DD/MM/AAAA não é padrão ISO 8601 para 'date'
          pattern: '^\d{2}/\d{2}/\d{4}$'
          description: Data de início da vigência da oferta (DD/MM/AAAA).
          example: "01/07/2025"
        dataFimOferta:
          type: string
          # format: date
          pattern: '^\d{2}/\d{2}/\d{4}$'
          nullable: true
          description: Data de fim da vigência da oferta (DD/MM/AAAA, opcional).
          example: "31/12/2025"
        fidelizacao:
          $ref: '#/components/schemas/Fidelizacao'
          nullable: true
        formasPagamento:
          type: array
          items:
            $ref: '#/components/schemas/FormaPagamento'
          minItems: 1
          description: Lista das formas de pagamento aceitas para a oferta.
        destaqueOferta:
          type: string
          nullable: true
          description: Informações de destaque da oferta (opcional).
          example: "Ideal para streaming em 4K e jogos online!"
        areasAbrangencia:
          type: array
          items:
            type: string # Ou pode ser number se os códigos IBGE forem numéricos
            description: Código IBGE do município ou '76' para Brasil ou código do estado.
            example: "3550308" # Exemplo de código IBGE de município
          minItems: 1
          description: Lista de códigos IBGE das áreas de abrangência da oferta.
        notasExtras:
          type: string
          nullable: true
          description: Notas ou observações adicionais sobre a oferta (opcional).
          example: "Consulte a viabilidade técnica para sua localidade."
        focoVenda:
          type: string
          enum: ["1", "0"]
          description: Indica se a oferta está com foco de venda ('1' para sim, '0' para não).
          example: "1"
        regOferta:
          type: string
          nullable: true
          description: Código de registro da oferta na Anatel (opcional).
          example: "ANATEL-001/2025-XYZ"
        modoEquipamento:
          type: string
          enum: ["1", "0"]
          description: Modo de disponibilização do equipamento ('1' para Comodato, '0' para Requer compra).
          example: "1"
        precoSemDescontos:
          type: number
          format: float # Ou double
          minimum: 0
          description: Preço mensal da oferta sem considerar descontos ou promoções.
          example: 199.90
        listaPromocoes:
          type: array
          items:
            $ref: '#/components/schemas/Promocao'
          nullable: true
          description: Lista de promoções associadas à oferta (opcional).
        beneficiosOfertaConjunta:
          type: string
          maxLength: 255
          nullable: true
          description: Descrição dos benefícios caso a oferta seja do tipo 'Conjunta'. Proibido para 'Individual'.
          example: "Desconto de R$20 na fatura ao contratar Internet + TV."
        STFC:
          type: object
          nullable: true
          description: Detalhes específicos para o serviço STFC (Telefonia Fixa), se aplicável.
          additionalProperties: true # Permite qualquer propriedade dentro deste objeto
          example: { minutosLocais: "Ilimitado", minutosNacionais: 500 }
        SMP:
          type: object
          nullable: true
          description: Detalhes específicos para o serviço SMP (Telefonia Móvel), se aplicável.
          additionalProperties: true
          example: { franquiaDados: "20GB", ligacoesOutrasOperadoras: "Ilimitadas" }
        SCM:
          type: object
          nullable: true
          description: Detalhes específicos para o serviço SCM (Banda Larga Fixa), se aplicável.
          additionalProperties: true
          example: { velocidadeDownload: "500 Mbps", velocidadeUpload: "250 Mbps", franquiaDados: "Ilimitada" }
        SeAC:
          type: object
          nullable: true
          description: Detalhes específicos para o serviço SeAC (TV por Assinatura), se aplicável.
          additionalProperties: true
          example: { quantidadeCanaisHD: 80, pontosExtras: 2 }

    OfertaInput:
      allOf:
        - $ref: '#/components/schemas/OfertaBase'
      # Campos obrigatórios específicos para o input (a maioria já está na OfertaBase)
      # A validação de 'required' é feita no nível das propriedades do OfertaBase
      # e nas validações condicionais da sua API (que não são totalmente expressáveis aqui)
      required:
        - identificadorUnico
        - tipoOferta
        - nomeOferta
        # custoInicial é condicionalmente obrigatório, descrito na API
        - linkSite
        - dataInicioOferta
        - formasPagamento
        - areasAbrangencia
        - focoVenda
        - modoEquipamento
        - precoSemDescontos
        # beneficiosOfertaConjunta é condicionalmente obrigatório

    Oferta: # O que é retornado pela API
      allOf:
        - $ref: '#/components/schemas/OfertaBase'
      properties:
        codigoOferta:
          type: string
          description: Código numérico aleatório de 8 dígitos gerado pela API para a oferta.
          example: "98765432"
          readOnly: true # Gerado pelo servidor

    CustoInicial:
      type: object
      properties:
        adesao:
          type: number
          format: float
          minimum: 0
          example: 50.00
        instalacao:
          type: number
          format: float
          minimum: 0
          example: 100.00
        equipamento:
          type: number
          format: float
          minimum: 0
          example: 0.00
      required:
        - adesao
        - instalacao
        - equipamento
      description: >
        Obrigatório para ofertas STFC, SCM, SeAC.
        Proibido para ofertas SMP.

    Fidelizacao:
      type: object
      description: Detalhes sobre a fidelização da oferta.
      properties:
        tempoMeses:
          type: integer
          format: int32
          minimum: 0
          example: 12
        multa:
          type: string
          example: "Valor proporcional aos meses restantes e benefícios concedidos."

    FormaPagamento:
      type: object
      properties:
        descontoPagamento:
          type: number
          format: float
          minimum: 0
          description: Valor do desconto aplicado para esta forma de pagamento.
          example: 10.00
        formaPagamento:
          type: string
          enum:
            - Boleto Bancário
            - Débito Automático
            - Cartão de Crédito
            - Conta Digital
            - Conta Digital + Débito Automático
            - Cartão de Débito
            - Dinheiro
            - PIX
          example: "Débito Automático"
      required:
        - descontoPagamento
        - formaPagamento

    Promocao:
      type: object
      properties:
        nomePromocao:
          type: string
          example: "Primeiros 3 meses com 50% de desconto"
        descricao:
          type: string
          example: "Pague R$99,95 nos primeiros 3 meses, após R$199,90."

    ErrorResponseValidation:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
          example: "Erros de validação encontrados:"
        errors:
          type: array
          items:
            type: string
          example: ["`identificadorUnico` é obrigatório e deve ser uma string não vazia de até 255 caracteres."]

    ErrorResponseGeneric:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
          example: "Erro interno do servidor ao processar dados."
        error:
          type: string
          example: "Detalhe específico do erro interno."