openapi: 3.0.3
info:
  title: Hyr Min Maskin Machine Rental API
  description: |
    API för maskinuthyrning i Storstockholm - minigrävare, kompaktlastare och dumprar.
    
    ## Live API Endpoints
    - GET /functions/v1/machines-api - Alla maskiner (JSON)
    - GET /functions/v1/machines-api?type=excavator - Filtrera på typ
    - GET /functions/v1/machines-api?id=volvo-11 - Specifik maskin
    - GET /functions/v1/machines-api?action=availability - Realtidstillgänglighet per maskin
    - GET /functions/v1/machines-api?action=availability&startDate=2026-04-01&endDate=2026-04-30 - Tillgänglighet för datumintervall
    - POST /functions/v1/calculate-transport - Beräkna transportkostnad
    - POST /functions/v1/machine-advisor - AI-rådgivning med bildanalys
    
    ## Machine Types
    - excavator: Mini excavators (1.2-2.7 ton)
    - loader: Compact wheel loaders (1.3-2.8 ton)  
    - dumper: Track dumpers (0.4-1.8 ton)
    
    ## AI Image Analysis (NEW)
    The AI Machine Expert can analyze uploaded property photos to assess:
    - Access width (gate openings, passages)
    - Terrain conditions (slope, soil type)
    - Potential obstacles (trees, utilities, structures)
    - Project scope and machine requirements
    
    ## Knowledge Resources
    - /tips - AI-reviewed operation guides (Swedish, English, Polish)
    - /earthwork-guide - Comprehensive project guides with municipal resources
  version: 2.2.0
  contact:
    name: Hyr Min Maskin
    url: https://hyrminmaskin.se
    email: bokning@hyrminmaskin.se

servers:
  - url: https://tiqggnjqdqudzyqdstsu.supabase.co
    description: Production API
  - url: https://hyrminmaskin.se
    description: Website

paths:
  /functions/v1/machines-api:
    get:
      operationId: getMachines
      summary: Hämta maskiner för uthyrning
      description: |
        Returnerar lista över tillgängliga maskiner med priser och specifikationer.
        Alla priser är i SEK inklusive moms.
      parameters:
        - name: type
          in: query
          description: Filtrera på maskintyp
          schema:
            type: string
            enum: [excavator, loader, dumper]
        - name: id
          in: query
          description: Hämta specifik maskin via ID
          schema:
            type: string
          examples:
            excavator:
              value: volvo-11
              summary: Volvo EC27D 2.7 ton
            loader:
              value: kramer-18
              summary: Kramer 5035
            dumper:
              value: messersi-14-2
              summary: Messersi TC150
        - name: minWeight
          in: query
          description: Minsta vikt i kg
          schema:
            type: integer
        - name: maxWeight
          in: query
          description: Maximal vikt i kg
          schema:
            type: integer
        - name: maxPrice
          in: query
          description: Maxpris per dag i SEK
          schema:
            type: integer
        - name: action
          in: query
          description: "Använd 'availability' för att hämta realtidstillgänglighet"
          schema:
            type: string
            enum: [availability]
        - name: startDate
          in: query
          description: Startdatum för tillgänglighet (YYYY-MM-DD)
          schema:
            type: string
            format: date
        - name: endDate
          in: query
          description: Slutdatum för tillgänglighet (YYYY-MM-DD)
          schema:
            type: string
            format: date
        - name: machine
          in: query
          description: WebReserv produkt-ID för specifik maskin
          schema:
            type: string
      responses:
        '200':
          description: Lista över maskiner eller tillgänglighetsdata
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/MachineListResponse'
                  - $ref: '#/components/schemas/AvailabilityResponse'
              example:
                success: true
                count: 11
                data:
                  - id: yanmar-1ton
                    name: Yanmar ViO12
                    type: excavator
                    weight: "1.2 ton"
                    weightKg: 1175
                    diggingDepthMm: 1780
                    dailyPriceSEK: 1699
                    vatIncluded: true
                meta:
                  provider: Hyr Min Maskin
                  location: Stockholm, Sweden

  /functions/v1/calculate-transport:
    post:
      operationId: calculateTransport
      summary: Beräkna transportkostnad med degressiv prissättning
      description: |
        Marknadens enda helautomatiska transportkalkylator för maskinuthyrning.
        Använder Google Maps realtidsdata och proprietär degressiv prissättning.
        
        Degressiv prissättningsmodell:
        - 0-15 km: Ordinarie pris per kilometer
        - 15-25 km: 15% rabatt på kilometerpriset
        - Över 25 km: 25% rabatt på kilometerpriset
        
        Prisberäkning inkluderar:
        - Total körsträcka (tur och retur för leverans + hämtning = 4 resor)
        - Körtid med lastning/lossning
        - Vägavgifter
        - Maskinspecifik prissättning (lastbil vs släp)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - destinationAddress
              properties:
                destinationAddress:
                  type: string
                  description: Fullständig leveransadress
                machineId:
                  type: string
                  description: Maskin-ID för maskinspecifik prissättning
            example:
              destinationAddress: "Strandvägen 1, Stockholm"
              machineId: "volvo-11"
      responses:
        '200':
          description: Transportpris med fullständig kostnadsuppdelning
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransportQuote'
              example:
                oneWayDistanceKm: 15.2
                oneWayDurationMinutes: 22
                totalDistanceKm: 60.8
                totalDurationMinutes: 88
                priceExclVat: 1840
                vat: 460
                priceInclVat: 2300
                minimumApplied: false
                breakdown:
                  distanceCost: 1520
                  timeCost: 320
                  fullPriceKm: 15
                  tier1DiscountedKm: 0.2
                  tier2DiscountedKm: 0
                  discountRate: 0.15
                  discountRate2: 0.25
                  breakpointKm: 15
                  breakpointKm2: 25
                  pricePerKm: 25

  /fleet:
    get:
      operationId: browseFleet
      summary: Bläddra bland maskiner (webbsida)
      description: HTML-sida med alla maskiner, bilder och priser
      responses:
        '200':
          description: Fleet page
          content:
            text/html:
              schema:
                type: string

  /machine/{machineId}:
    get:
      operationId: getMachineDetails
      summary: Maskindetaljer (webbsida)
      parameters:
        - name: machineId
          in: path
          required: true
          schema:
            type: string
          examples:
            excavator:
              value: volvo-11
              summary: Volvo EC27D
            loader:
              value: kramer-18
              summary: Kramer 5035
      responses:
        '200':
          description: Machine detail page
          content:
            text/html:
              schema:
                type: string

  /booking:
    get:
      operationId: openBooking
      summary: Öppna bokningskalendern
      responses:
        '200':
          description: Booking calendar
          content:
            text/html:
              schema:
                type: string

  /earthwork-guide:
    get:
      operationId: getEarthworkGuide
      summary: Guide för markarbeten
      description: Steg-för-steg guider för pool, dränering, grund, fiber mm.
      responses:
        '200':
          description: Earthwork guide
          content:
            text/html:
              schema:
                type: string

  /tips:
    get:
      operationId: getOperationGuide
      summary: Körinstruktioner för grävmaskiner
      description: Instruktioner för spakstyrning, säkerhet mm på svenska, engelska och polska.
      responses:
        '200':
          description: Operation guide
          content:
            text/html:
              schema:
                type: string

  /project-designer:
    get:
      operationId: openProjectDesigner
      summary: AI Projektplanerare (webbsida)
      description: |
        Interaktiv AI-driven projektplanerare. Ladda upp en bild av din tomt och
        få en komplett projektplan med materialval, volymberäkningar (m³),
        maskinrekommendationer och fotorealistisk efter-bild.
        
        Stödda projekttyper: Pool, Attefallshus, Garage, Trädgård, Dränering/VA, Altan.
      responses:
        '200':
          description: Project Designer page
          content:
            text/html:
              schema:
                type: string

  /functions/v1/project-designer:
    post:
      operationId: generateProjectPlan
      summary: AI-driven projektplanering med bildanalys
      description: |
        Genererar en komplett projektplan baserad på:
        - Uppladdad bild av tomten (valfritt)
        - Projekttyp (pool, attefallshus, garage, trädgård, dränering, altan)
        - Materialval och stil
        - Dimensioner (längd, bredd, djup)
        
        Returnerar maskinrekommendationer, volymberäkningar, och kan generera
        fotorealistiska efter-bilder.
        
        **Språkstöd:** Svenska, Engelska, Polska
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - action
                - projectType
              properties:
                action:
                  type: string
                  enum: [generate-plan, generate-after-image, analyze-image]
                  description: Vilken åtgärd som ska utföras
                projectType:
                  type: string
                  enum: [pool, attefall, garden, garage, trenching, deck]
                material:
                  type: string
                  description: Sammanfattning av materialval
                size:
                  type: string
                  description: "Dimensioner, t.ex. '4m × 3m × 1.5m (18.0 m³)'"
                style:
                  type: string
                  enum: [modern, scandi, rustic]
                language:
                  type: string
                  enum: [sv, en, pl]
                imageBase64:
                  type: string
                  description: Base64-kodad bild av tomten
            examples:
              poolPlan:
                summary: Generera poolplan
                value:
                  action: generate-plan
                  projectType: pool
                  material: "Pooltyp: Glasfiber, Sarg: Skiffer"
                  size: "8m × 4m × 1.5m (48.0 m³)"
                  style: modern
                  language: sv
      responses:
        '200':
          description: Projektplan med maskinrekommendationer
          content:
            application/json:
              schema:
                type: object
                properties:
                  plan:
                    type: string
                    description: Fullständig projektplan i text
                  recommendedMachines:
                    type: array
                    items:
                      type: string
                    description: Lista med rekommenderade maskin-ID:n

  /functions/v1/machine-advisor:
    post:
      operationId: getAIAdvice
      summary: AI-rådgivning med bildanalys
      description: |
        Multimodal AI som kan analysera text och bilder för maskinrekommendationer.
        
        **Bildanalys-funktioner:**
        - Bedömer åtkomst (grindöppningar, passager, hinder)
        - Analyserar terräng (lutning, marktyp, vegetation)
        - Identifierar potentiella utmaningar (ledningar, träd, konstruktioner)
        - Rekommenderar maskiner baserat på visuell bedömning
        
        **Språkstöd:** Svenska, Engelska, Polska
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - messages
              properties:
                messages:
                  type: array
                  description: Konversationshistorik med text och/eller bilder
                  items:
                    type: object
                    properties:
                      role:
                        type: string
                        enum: [user, assistant]
                      content:
                        oneOf:
                          - type: string
                            description: Textmeddelande
                          - type: array
                            description: Multimodalt meddelande med text och bild
                            items:
                              oneOf:
                                - type: object
                                  properties:
                                    type:
                                      type: string
                                      enum: [text]
                                    text:
                                      type: string
                                - type: object
                                  properties:
                                    type:
                                      type: string
                                      enum: [image_url]
                                    image_url:
                                      type: object
                                      properties:
                                        url:
                                          type: string
                                          description: Base64-kodad bild (data:image/jpeg;base64,...)
            examples:
              textOnly:
                summary: Endast textfråga
                value:
                  messages:
                    - role: user
                      content: "Vilken grävmaskin behöver jag för poolgrävning?"
              withImage:
                summary: Med bildanalys
                value:
                  messages:
                    - role: user
                      content:
                        - type: text
                          text: "Analysera min tomt och rekommendera maskiner"
                        - type: image_url
                          image_url:
                            url: "data:image/jpeg;base64,/9j/4AAQ..."
      responses:
        '200':
          description: AI-svar (streaming SSE)
          content:
            text/event-stream:
              schema:
                type: string

components:
  schemas:
    Machine:
      type: object
      properties:
        id:
          type: string
          description: Unikt maskin-ID
        name:
          type: string
          description: Modellnamn
        type:
          type: string
          enum: [excavator, loader, dumper]
        weight:
          type: string
          description: Vikt (t.ex. "1.2 ton")
        weightKg:
          type: integer
          description: Vikt i kg
        diggingDepthMm:
          type: integer
          description: Max grävdjup i mm (grävmaskiner)
        liftCapacityKg:
          type: integer
          description: Lyftkapacitet i kg (lastare)
        capacityKg:
          type: integer
          description: Lastkapacitet i kg (dumprar)
        dailyPriceSEK:
          type: integer
          description: Pris per dag i SEK
        multiDayPriceSEK:
          type: integer
          description: Rabatterat pris vid fler dagar
        vatIncluded:
          type: boolean
          description: Moms inkluderad
        features:
          type: array
          items:
            type: string
        accessories:
          type: array
          items:
            type: string
        bookingUrl:
          type: string
          format: uri

    MachineListResponse:
      type: object
      properties:
        success:
          type: boolean
        count:
          type: integer
        data:
          type: array
          items:
            $ref: '#/components/schemas/Machine'
        meta:
          type: object
          properties:
            provider:
              type: string
            location:
              type: string
            contact:
              type: object
            lastUpdated:
              type: string
              format: date-time

    TransportQuote:
      type: object
      description: Resultat från transportkalkylatorn med degressiv prissättning
      properties:
        oneWayDistanceKm:
          type: number
          description: Enkel sträcka i km
        oneWayDurationMinutes:
          type: number
          description: Enkel körtid i minuter
        totalDistanceKm:
          type: number
          description: Total sträcka (4 resor) i km
        totalDurationMinutes:
          type: number
          description: Total tid inkl lastning i minuter
        priceExclVat:
          type: number
          description: Pris exkl moms (SEK)
        vat:
          type: number
          description: Moms (25%)
        priceInclVat:
          type: number
          description: Totalpris inkl moms (SEK)
        minimumApplied:
          type: boolean
          description: Om minimumavgift tillämpats
        breakdown:
          type: object
          description: Detaljerad kostnadsuppdelning med degressiv rabatt
          properties:
            distanceCost:
              type: number
            timeCost:
              type: number
            fullPriceKm:
              type: number
              description: Kilometer med ordinarie pris
            tier1DiscountedKm:
              type: number
              description: Kilometer med 15% rabatt (15-25 km)
            tier2DiscountedKm:
              type: number
              description: Kilometer med 25% rabatt (>25 km)
            discountRate:
              type: number
              description: Rabattsats nivå 1 (0.15)
            discountRate2:
              type: number
              description: Rabattsats nivå 2 (0.25)
            breakpointKm:
              type: number
              description: Brytpunkt 1 (15 km)
            breakpointKm2:
              type: number
              description: Brytpunkt 2 (25 km)
            pricePerKm:
              type: number
              description: Baspris per km

    AvailabilityResponse:
      type: object
      description: Realtidstillgänglighet per maskin, synkad varje timme 07-23 CET
      properties:
        success:
          type: boolean
        availability:
          type: object
          description: Tillgänglighet grupperad per maskin (WebReserv produkt-ID)
          additionalProperties:
            type: object
            properties:
              machine_name:
                type: string
              dates:
                type: array
                items:
                  type: object
                  properties:
                    date:
                      type: string
                      format: date
                    status:
                      type: string
                      enum: [available, sold_out, no_info]
        dateRange:
          type: object
          properties:
            startDate:
              type: string
              format: date
            endDate:
              type: string
              format: date
        lastSync:
          type: object
          properties:
            synced_at:
              type: string
              format: date-time
            status:
              type: string