{
  "openapi": "3.1.0",
  "info": {
    "title": "Family Pickleball API",
    "description": "Public REST API for Family Pickleball — browse sessions, check availability, complete checkout, manage waivers, and chat with PickleBot. Note: the API uses 'programs' internally but these are called 'sessions' in client-facing contexts.",
    "version": "1.0.0",
    "contact": {
      "name": "Coach Tobin",
      "email": "tobin@familypickleball.org",
      "url": "https://familypickleball.org"
    }
  },
  "servers": [
    { "url": "https://familypickleball.org/api/v1", "description": "Production" },
    { "url": "http://localhost:3000/api/v1", "description": "Development" }
  ],
  "paths": {
    "/programs": {
      "get": {
        "operationId": "listSessions",
        "summary": "List active sessions (internally called 'programs')",
        "description": "Returns all active sessions available for purchase. Client-facing terminology is 'sessions'; the API endpoint uses 'programs' for historical reasons.",
        "x-agent-hint": "Start here. Browse available sessions. Use 'segment' to filter by audience.",
        "parameters": [
          { "name": "type", "in": "query", "schema": { "type": "string", "enum": ["class", "clinic", "camp", "private", "drill", "liveball", "league", "tournament", "social"] }, "description": "Filter by session type" },
          { "name": "segment", "in": "query", "schema": { "type": "string", "enum": ["junior", "adult", "senior", "adaptive", "family"] }, "description": "Filter by audience segment" }
        ],
        "responses": {
          "200": { "description": "List of active sessions" }
        }
      }
    },
    "/packages": {
      "get": {
        "operationId": "listPackages",
        "summary": "List available packages",
        "description": "Returns all available session packages for purchase.",
        "responses": {
          "200": { "description": "List of packages" }
        }
      }
    },
    "/availability/slots": {
      "get": {
        "operationId": "getAvailableSlots",
        "summary": "Get available time slots for a given date and session type",
        "x-agent-hint": "Check this before booking to find open time slots.",
        "parameters": [
          { "name": "date", "in": "query", "required": true, "schema": { "type": "string", "format": "date" }, "description": "Date in YYYY-MM-DD format" },
          { "name": "type", "in": "query", "required": true, "schema": { "type": "string", "enum": ["private", "drill"] }, "description": "Session type to check availability for" }
        ],
        "responses": {
          "200": { "description": "List of available time slots" }
        }
      }
    },
    "/pricing": {
      "get": {
        "operationId": "getPricing",
        "summary": "Get pricing information",
        "description": "Returns current pricing for all session types and packages.",
        "x-agent-hint": "Use this to answer pricing questions. Returns categories with items.",
        "responses": {
          "200": { "description": "Pricing information" }
        }
      }
    },
    "/checkout": {
      "post": {
        "operationId": "completeCheckout",
        "summary": "Complete a checkout",
        "description": "Process a full checkout with selected items, client information, and payment method.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["items", "client_name", "client_email", "client_phone", "payment_method"],
                "properties": {
                  "items": {
                    "type": "array",
                    "items": { "type": "object" },
                    "description": "Array of items being purchased (sessions, packages)"
                  },
                  "client_name": { "type": "string", "description": "Client full name" },
                  "client_email": { "type": "string", "format": "email", "description": "Client email address" },
                  "client_phone": { "type": "string", "description": "Client phone number" },
                  "payment_method": {
                    "type": "string",
                    "enum": ["venmo", "zelle", "card", "rcoc"],
                    "description": "Payment method: Venmo (@Tobin_Wazzan), Zelle (949-339-4077), Card (Stripe), or RCOC"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Checkout completed successfully" }
        }
      }
    },
    "/book": {
      "post": {
        "operationId": "bookSession",
        "summary": "Book a session in one call (designed for AI agents)",
        "description": "Single-call booking: creates client if needed, checks waiver, creates payment request, sends confirmation. No cart or browser session required.",
        "x-agent-hint": "This is the preferred endpoint for AI agents. One call handles everything.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["client_name", "client_email"],
                "properties": {
                  "session_type": { "type": "string", "enum": ["private", "drill", "liveball", "class", "clinic", "camp", "social"], "description": "Type of session to book" },
                  "date": { "type": "string", "format": "date", "description": "Preferred date (YYYY-MM-DD)" },
                  "time": { "type": "string", "description": "Preferred time (HH:MM)" },
                  "client_name": { "type": "string", "description": "Client full name" },
                  "client_email": { "type": "string", "format": "email", "description": "Client email" },
                  "client_phone": { "type": "string", "description": "Client phone (optional)" },
                  "payment_method": { "type": "string", "enum": ["venmo", "zelle", "card", "rcoc"], "description": "Payment method" },
                  "availability_slot_id": { "type": "string", "description": "Specific slot ID from /availability/slots (optional)" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Booking created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "booking_id": { "type": "string" },
                    "session": { "type": "string" },
                    "date": { "type": "string" },
                    "time": { "type": "string" },
                    "payment_method": { "type": "string" },
                    "payment_url": { "type": "string", "description": "Stripe checkout URL (card payments only)" },
                    "waiver_status": { "type": "string", "enum": ["signed", "pending"] },
                    "waiver_url": { "type": "string", "description": "URL to sign waiver (if pending)" },
                    "message": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/venues": {
      "get": {
        "operationId": "listVenues",
        "summary": "List active venues",
        "description": "Returns all active pickleball venues with addresses and coordinates.",
        "responses": { "200": { "description": "List of venues" } }
      }
    },
    "/schedule": {
      "get": {
        "operationId": "getSchedule",
        "summary": "Get public session schedule",
        "parameters": [
          { "name": "start", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "Start date" },
          { "name": "end", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "End date" }
        ],
        "responses": { "200": { "description": "Schedule of upcoming sessions" } }
      }
    },
    "/clients/lookup": {
      "post": {
        "operationId": "lookupClient",
        "summary": "Find a client by email",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email"],
                "properties": {
                  "email": { "type": "string", "format": "email", "description": "Client email address" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Client found" },
          "404": { "description": "Client not found" }
        }
      }
    },
    "/clients/register": {
      "post": {
        "operationId": "registerClient",
        "summary": "Register a new client",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["full_name", "email"],
                "properties": {
                  "full_name": { "type": "string" },
                  "email": { "type": "string", "format": "email" },
                  "phone": { "type": "string", "description": "Optional" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Client registered (or existing client found)" }
        }
      }
    },
    "/waivers/check": {
      "post": {
        "operationId": "checkWaiverStatus",
        "summary": "Check waiver status for a client",
        "description": "Check if a client has a valid signed waiver. Waiver covers liability, city waivers, photo consent, privacy policy, and terms & conditions.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email"],
                "properties": {
                  "email": { "type": "string", "format": "email", "description": "Client email address" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Waiver status returned (signed, pending, expired, or none)" }
        }
      }
    },
    "/coupons/validate": {
      "post": {
        "operationId": "validateCoupon",
        "summary": "Validate a coupon code",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["code"],
                "properties": {
                  "code": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Coupon is valid with discount details" },
          "404": { "description": "Coupon not found or expired" }
        }
      }
    },
    "/attendance/mark": {
      "post": {
        "operationId": "markAttendance",
        "summary": "Mark attendance for a session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["session_id", "client_id"],
                "properties": {
                  "session_id": { "type": "string", "description": "Session ID" },
                  "client_id": { "type": "string", "description": "Client ID" },
                  "present": { "type": "boolean", "description": "Whether the client was present" },
                  "notes": { "type": "string", "description": "Optional notes" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Attendance marked" }
        }
      }
    },
    "/picklebot": {
      "post": {
        "operationId": "chatWithPickleBot",
        "summary": "Chat with PickleBot AI assistant",
        "description": "Ask about sessions, pricing, scheduling, policies, or get personalized recommendations.",
        "x-agent-hint": "Delegate questions you cannot answer to PickleBot. It knows all about Family Pickleball.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["message"],
                "properties": {
                  "message": { "type": "string", "description": "The user's question or message" },
                  "history": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "role": { "type": "string", "enum": ["user", "assistant"] },
                        "content": { "type": "string" }
                      }
                    },
                    "description": "Previous conversation messages for context"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PickleBot response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reply": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
