{
  "openapi": "3.1.0",
  "info": {
    "title": "InmoCMS Public API",
    "version": "1.0.0",
    "description": "API para registrar demandantes y ofertantes externos en InmoCMS."
  },
  "servers": [{ "url": "/", "description": "Servidor actual" }],
  "tags": [{ "name": "Autenticacion" }, { "name": "Clientes" }],
  "paths": {
    "/api/v1/auth/token": {
      "post": {
        "tags": ["Autenticacion"],
        "summary": "Obtener un JWT",
        "operationId": "issueToken",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Credentials" } } }
        },
        "responses": {
          "200": { "description": "Token emitido", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Token" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/TooManyRequests" }
        }
      }
    },
    "/api/v1/clientes": {
      "post": {
        "tags": ["Clientes"],
        "summary": "Dar de alta un cliente",
        "description": "Crea un cliente en la base de datos de la inmobiliaria vinculada a la credencial y, segun tipo_cliente, su interes de busqueda o el inmueble ofertado. Limite: 14 peticiones por minuto; el intento 15 bloquea la credencial durante 60 segundos. Se recomienda enviar Idempotency-Key en cada lead.",
        "operationId": "createCliente",
        "security": [{ "bearerAuth": [] }],
        "parameters": [{
          "in": "header",
          "name": "Idempotency-Key",
          "required": false,
          "description": "Identificador unico del lead (8-100 caracteres). Repetirlo devuelve el alta original sin duplicarla.",
          "schema": { "type": "string", "minLength": 8, "maxLength": 100 },
          "example": "whatsapp-982371"
        }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  { "$ref": "#/components/schemas/Demandante" },
                  { "$ref": "#/components/schemas/Ofertante" }
                ],
                "discriminator": { "propertyName": "tipo_cliente" }
              },
              "examples": {
                "demandante": { "$ref": "#/components/examples/Demandante" },
                "ofertante": { "$ref": "#/components/examples/Ofertante" }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Cliente creado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatedLead" } } } },
          "200": { "description": "Peticion idempotente repetida; se devuelve el alta original", "headers": { "Idempotent-Replayed": { "schema": { "type": "string", "const": "true" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/TooManyRequests" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" }
    },
    "schemas": {
      "Credentials": {
        "type": "object", "required": ["client_id", "client_secret"],
        "properties": { "client_id": { "type": "string" }, "client_secret": { "type": "string", "format": "password" } }
      },
      "Token": {
        "type": "object", "required": ["access_token", "token_type", "expires_in"],
        "properties": { "access_token": { "type": "string" }, "token_type": { "type": "string", "const": "Bearer" }, "expires_in": { "type": "integer", "example": 3600 } }
      },
      "ClienteBase": {
        "type": "object", "required": ["tipo_cliente", "nombre", "origen"],
        "properties": {
          "tipo_cliente": { "type": "string", "enum": ["demandante", "ofertante"] },
          "nombre": { "type": "string", "maxLength": 100 },
          "telefono": { "type": ["string", "null"], "maxLength": 32, "description": "Telefono o email: al menos uno de los dos es obligatorio." },
          "email": { "type": ["string", "null"], "format": "email", "maxLength": 100 },
          "origen": { "type": "string", "maxLength": 200, "examples": ["WhatsApp", "Idealista", "Email"] },
          "notas": { "type": ["string", "null"] },
          "referencia_piso": { "type": ["string", "null"], "description": "Referencia del anuncio concreto, si existe." }
        }
      },
      "Demandante": {
        "allOf": [
          { "$ref": "#/components/schemas/ClienteBase" },
          { "type": "object", "required": ["tipo_cliente", "zonas_interes"], "properties": {
            "tipo_cliente": { "const": "demandante" },
            "zonas_interes": { "type": "array", "maxItems": 20, "items": { "type": "string", "maxLength": 100 } },
            "presupuesto_orientativo": { "type": ["number", "null"], "minimum": 0 }
          } }
        ]
      },
      "Ofertante": {
        "allOf": [
          { "$ref": "#/components/schemas/ClienteBase" },
          { "type": "object", "required": ["tipo_cliente", "inmueble"], "properties": {
            "tipo_cliente": { "const": "ofertante" },
            "inmueble": { "$ref": "#/components/schemas/Inmueble" }
          } }
        ]
      },
      "Inmueble": {
        "type": "object", "required": ["direccion_zona", "tipo_operacion"],
        "properties": {
          "direccion_zona": { "type": "string", "maxLength": 250 },
          "tipo_operacion": { "type": "string", "enum": ["venta", "alquiler"] },
          "tipo_inmueble": { "type": ["string", "null"], "examples": ["piso", "casa", "chalet", "local"] },
          "metros_cuadrados": { "type": ["number", "null"], "minimum": 0 },
          "habitaciones": { "type": ["integer", "null"], "minimum": 0 },
          "banos": { "type": ["integer", "null"], "minimum": 0 },
          "precio_orientativo": { "type": ["number", "null"], "minimum": 0 },
          "estado_descripcion": { "type": ["string", "null"], "examples": ["Reformado", "A reformar"] }
        }
      },
      "CreatedLead": {
        "type": "object", "properties": {
          "message": { "type": "string" },
          "data": { "type": "object", "properties": {
            "lead_id": { "type": "integer" }, "cliente_id": { "type": "integer" },
            "inmueble_id": { "type": ["integer", "null"] }, "tipo_cliente": { "type": "string" },
            "created_at": { "type": "string", "format": "date-time" }
          } }
        }
      }
    },
    "examples": {
      "Demandante": { "value": { "tipo_cliente": "demandante", "nombre": "Ana Garcia", "telefono": "+34600111222", "email": "ana@example.com", "zonas_interes": ["Centro", "Chamberi"], "presupuesto_orientativo": 350000, "referencia_piso": "REF-2026-104", "origen": "WhatsApp" } },
      "Ofertante": { "value": { "tipo_cliente": "ofertante", "nombre": "Carlos Perez", "telefono": "+34600999888", "email": "carlos@example.com", "origen": "Email", "inmueble": { "direccion_zona": "Calle Mayor 10, Madrid", "tipo_operacion": "venta", "tipo_inmueble": "piso", "metros_cuadrados": 92, "habitaciones": 3, "banos": 2, "precio_orientativo": 420000, "estado_descripcion": "Reformado, exterior" } } }
    },
    "responses": {
      "Unauthorized": { "description": "Credenciales o token no validos" },
      "ValidationError": { "description": "Error de validacion" },
      "TooManyRequests": { "description": "Limite de 14 peticiones superado. La credencial queda bloqueada 60 segundos.", "headers": { "Retry-After": { "schema": { "type": "integer", "example": 60 } }, "X-RateLimit-Limit": { "schema": { "type": "integer", "const": 14 } }, "X-RateLimit-Remaining": { "schema": { "type": "integer", "const": 0 } } } }
    }
  }
}
