import { env } from "../config/env.js";

const bearerSecurity = [{ bearerAuth: [] }];

export const openApiDocument = {
  openapi: "3.0.3",
  info: {
    title: "Rental System API",
    version: "1.0.0",
    description:
      "REST API do zarządzania wynajmem sprzętu IT, osią czasu rezerwacji, użytkownikami i stanem urządzeń."
  },
  servers: [
    {
      url: `${env.API_BASE_URL}/api`,
      description: "Current API base URL"
    }
  ],
  tags: [
    { name: "Auth" },
    { name: "Timeline" },
    { name: "Bookings" },
    { name: "Equipment Categories" },
    { name: "Equipment Items" },
    { name: "Stats" },
    { name: "Users" },
    { name: "Statuses" }
  ],
  paths: {
    "/auth/login": {
      post: {
        tags: ["Auth"],
        summary: "Log in to the system",
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/AuthLoginRequest" },
              example: {
                email: "admin@rental.local",
                password: "Admin12345!"
              }
            }
          }
        },
        responses: {
          "200": {
            description: "Successful login",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/AuthSession" }
              }
            }
          },
          "401": {
            description: "Invalid credentials",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/auth/me": {
      get: {
        tags: ["Auth"],
        summary: "Return authenticated user",
        security: bearerSecurity,
        responses: {
          "200": {
            description: "Authenticated user data",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    user: { $ref: "#/components/schemas/AuthUser" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/auth/preferences": {
      get: {
        tags: ["Auth"],
        summary: "Return saved timeline and equipment ordering preferences for the authenticated user",
        security: bearerSecurity,
        responses: {
          "200": {
            description: "User preferences",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/UserPreferences" }
                  }
                }
              }
            }
          }
        }
      },
      patch: {
        tags: ["Auth"],
        summary: "Update saved ordering preferences for the authenticated user",
        security: bearerSecurity,
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/UserPreferencesPatchRequest" }
            }
          }
        },
        responses: {
          "200": {
            description: "Updated user preferences",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/UserPreferences" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/timeline": {
      get: {
        tags: ["Timeline"],
        summary: "Get rental timeline grouped by equipment category",
        security: bearerSecurity,
        parameters: [
          { in: "query", name: "from", schema: { type: "string", format: "date" } },
          { in: "query", name: "to", schema: { type: "string", format: "date" } },
          { in: "query", name: "categoryIds", schema: { type: "string" }, description: "Comma-separated category ids" },
          { in: "query", name: "status", schema: { type: "string", enum: ["all", "active", "service", "retired"] } },
          { in: "query", name: "search", schema: { type: "string" } },
          { in: "query", name: "customerName", schema: { type: "string" } },
          { in: "query", name: "includeInactive", schema: { type: "boolean" } }
        ],
        responses: {
          "200": {
            description: "Timeline view",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/TimelineResponse" }
              }
            }
          }
        }
      }
    },
    "/stats": {
      get: {
        tags: ["Stats"],
        summary: "Get admin revenue and activity statistics",
        security: bearerSecurity,
        parameters: [
          { in: "query", name: "from", schema: { type: "string", format: "date" } },
          { in: "query", name: "to", schema: { type: "string", format: "date" } }
        ],
        responses: {
          "200": {
            description: "Statistics payload",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/StatsResponse" }
                  }
                }
              }
            }
          },
          "403": {
            description: "Admin role required",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/stats/clicks": {
      post: {
        tags: ["Stats"],
        summary: "Batch-write click activity for the authenticated user",
        security: bearerSecurity,
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/UserClicksRequest" },
              example: { count: 12 }
            }
          }
        },
        responses: {
          "204": {
            description: "Clicks recorded"
          }
        }
      }
    },
    "/equipment-categories": {
      get: {
        tags: ["Equipment Categories"],
        summary: "List equipment categories",
        security: bearerSecurity,
        responses: {
          "200": {
            description: "Categories list",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: {
                      type: "array",
                      items: { $ref: "#/components/schemas/EquipmentCategory" }
                    }
                  }
                }
              }
            }
          }
        }
      },
      post: {
        tags: ["Equipment Categories"],
        summary: "Create equipment category",
        security: bearerSecurity,
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/EquipmentCategoryRequest" },
              example: { name: "Laptop 17\"" }
            }
          }
        },
        responses: {
          "201": {
            description: "Category created",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/EquipmentCategory" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/equipment-categories/{id}": {
      patch: {
        tags: ["Equipment Categories"],
        summary: "Update equipment category",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/EquipmentCategoryRequest" }
            }
          }
        },
        responses: {
          "200": {
            description: "Updated category",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/EquipmentCategory" }
                  }
                }
              }
            }
          }
        }
      },
      delete: {
        tags: ["Equipment Categories"],
        summary: "Delete equipment category",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        responses: {
          "204": { description: "Category deleted" },
          "409": {
            description: "Category still has items assigned",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/equipment-items": {
      get: {
        tags: ["Equipment Items"],
        summary: "List equipment items",
        security: bearerSecurity,
        parameters: [
          { in: "query", name: "categoryId", schema: { type: "string", format: "uuid" } },
          { in: "query", name: "status", schema: { type: "string", enum: ["all", "active", "service", "retired"] } },
          { in: "query", name: "search", schema: { type: "string" } },
          { in: "query", name: "includeInactive", schema: { type: "boolean" } }
        ],
        responses: {
          "200": {
            description: "Items list",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: {
                      type: "array",
                      items: { $ref: "#/components/schemas/EquipmentItem" }
                    }
                  }
                }
              }
            }
          }
        }
      },
      post: {
        tags: ["Equipment Items"],
        summary: "Create equipment item",
        security: bearerSecurity,
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/EquipmentItemRequest" },
              example: {
                categoryId: "8a52ec3a-1a5f-4a3a-9f2c-5af328f2ac8d",
                name: "Dell Latitude 15 D",
                serialNumber: "DL15-004",
                assetTag: "L15-004",
                status: "active",
                notes: "Nowy egzemplarz",
                isVisibleOnTimeline: true
              }
            }
          }
        },
        responses: {
          "201": {
            description: "Created item",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/EquipmentItem" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/equipment-items/{id}": {
      patch: {
        tags: ["Equipment Items"],
        summary: "Update equipment item",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/EquipmentItemPatchRequest" }
            }
          }
        },
        responses: {
          "200": {
            description: "Updated item",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/EquipmentItem" }
                  }
                }
              }
            }
          }
        }
      },
      delete: {
        tags: ["Equipment Items"],
        summary: "Delete equipment item",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        responses: {
          "204": { description: "Item deleted" },
          "409": {
            description: "Nie mogę usunąć urządzenia z historią wynajmu. Spróbuj po prostu wyłączyć urządzenie.",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/bookings": {
      get: {
        tags: ["Bookings"],
        summary: "List bookings",
        security: bearerSecurity,
        parameters: [
          { in: "query", name: "itemId", schema: { type: "string", format: "uuid" } },
          { in: "query", name: "categoryId", schema: { type: "string", format: "uuid" } },
          { in: "query", name: "customerName", schema: { type: "string" } },
          { in: "query", name: "from", schema: { type: "string", format: "date" } },
          { in: "query", name: "to", schema: { type: "string", format: "date" } }
        ],
        responses: {
          "200": {
            description: "Bookings list",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: {
                      type: "array",
                      items: { $ref: "#/components/schemas/RentalBooking" }
                    }
                  }
                }
              }
            }
          }
        }
      },
      post: {
        tags: ["Bookings"],
        summary: "Create booking for one or many equipment items",
        security: bearerSecurity,
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/RentalBookingCreateRequest" },
              example: {
                equipmentItemIds: ["8a52ec3a-1a5f-4a3a-9f2c-5af328f2ac8d", "9db8c5a1-68ea-480f-aea7-e6283fa2476f"],
                customerName: "Acme Events",
                orderNumber: null,
                projectNumber: null,
                projectName: "Roadshow Q3",
                notes: "Dostawa dzień wcześniej",
                startDate: "2026-05-02",
                endDate: "2026-05-07",
                dayRate: 150,
                totalPrice: null,
                startTime: "09:00",
                endTime: "17:00",
                useSuggestedItemRates: false
              }
            }
          }
        },
        responses: {
          "201": {
            description: "Created bookings",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: {
                      type: "array",
                      items: { $ref: "#/components/schemas/RentalBooking" }
                    }
                  }
                }
              }
            }
          },
          "409": {
            description: "Booking conflict or inactive device",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/bookings/{id}/scope": {
      patch: {
        tags: ["Bookings"],
        summary: "Expand, reduce, or move one project booking scope across multiple equipment items",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/RentalBookingScopePatchRequest" }
            }
          }
        },
        responses: {
          "200": {
            description: "Updated project booking scope",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: {
                      type: "array",
                      items: { $ref: "#/components/schemas/RentalBooking" }
                    }
                  }
                }
              }
            }
          },
          "409": {
            description: "One of the selected equipment items already overlaps with another booking",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/bookings/{id}/detach": {
      patch: {
        tags: ["Bookings"],
        summary: "Detach one equipment item from a shared project booking so it can be edited independently",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        responses: {
          "200": {
            description: "Detached booking",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/RentalBooking" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/bookings/{id}": {
      get: {
        tags: ["Bookings"],
        summary: "Get booking details",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        responses: {
          "200": {
            description: "Booking details",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/RentalBooking" }
                  }
                }
              }
            }
          }
        }
      },
      patch: {
        tags: ["Bookings"],
        summary: "Update booking",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/RentalBookingUpdateRequest" }
            }
          }
        },
        responses: {
          "200": {
            description: "Updated booking",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/RentalBooking" }
                  }
                }
              }
            }
          },
          "409": {
            description: "Updated booking overlaps with another booking",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      },
      delete: {
        tags: ["Bookings"],
        summary: "Delete booking",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        responses: {
          "204": { description: "Booking deleted" }
        }
      }
    },
    "/users": {
      get: {
        tags: ["Users"],
        summary: "List users",
        security: bearerSecurity,
        responses: {
          "200": {
            description: "Users list",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: {
                      type: "array",
                      items: { $ref: "#/components/schemas/User" }
                    }
                  }
                }
              }
            }
          }
        }
      },
      post: {
        tags: ["Users"],
        summary: "Create user",
        security: bearerSecurity,
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/UserCreateRequest" }
            }
          }
        },
        responses: {
          "201": {
            description: "Created user",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/User" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/users/{id}": {
      patch: {
        tags: ["Users"],
        summary: "Update user",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/UserUpdateRequest" }
            }
          }
        },
        responses: {
          "200": {
            description: "Updated user",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: { $ref: "#/components/schemas/User" }
                  }
                }
              }
            }
          }
        }
      },
      delete: {
        tags: ["Users"],
        summary: "Delete user",
        security: bearerSecurity,
        parameters: [{ in: "path", name: "id", required: true, schema: { type: "string", format: "uuid" } }],
        responses: {
          "204": { description: "User deleted" },
          "409": {
            description: "Cannot remove the last active admin",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/device-statuses": {
      get: {
        tags: ["Statuses"],
        summary: "List supported equipment statuses",
        security: bearerSecurity,
        responses: {
          "200": {
            description: "Status options",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    data: {
                      type: "array",
                      items: { $ref: "#/components/schemas/DeviceStatusOption" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  components: {
    securitySchemes: {
      bearerAuth: {
        type: "http",
        scheme: "bearer",
        bearerFormat: "JWT"
      }
    },
    schemas: {
      ErrorResponse: {
        type: "object",
        properties: {
          error: { type: "string", example: "Booking conflict detected" },
          details: {
            type: "object",
            nullable: true
          }
        }
      },
      AuthLoginRequest: {
        type: "object",
        required: ["email", "password"],
        properties: {
          email: { type: "string", format: "email" },
          password: { type: "string", format: "password" }
        }
      },
      AuthUser: {
        type: "object",
        required: ["id", "name", "email", "role", "isActive"],
        properties: {
          id: { type: "string", format: "uuid" },
          name: { type: "string" },
          email: { type: "string", format: "email" },
          role: { type: "string", enum: ["admin", "operator", "viewer", "technik"] },
          isActive: { type: "boolean" }
        }
      },
      AuthSession: {
        type: "object",
        required: ["token", "user"],
        properties: {
          token: { type: "string", example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." },
          user: { $ref: "#/components/schemas/AuthUser" }
        }
      },
      UserPreferences: {
        type: "object",
        properties: {
          equipmentCategoryOrder: {
            type: "array",
            items: { type: "string", format: "uuid" }
          },
          equipmentItemOrder: {
            type: "array",
            items: { type: "string", format: "uuid" }
          },
          timelineIncludeInactive: { type: "boolean" },
          equipmentIncludeInactive: { type: "boolean" }
        }
      },
      UserPreferencesPatchRequest: {
        type: "object",
        properties: {
          equipmentCategoryOrder: {
            type: "array",
            items: { type: "string", format: "uuid" }
          },
          equipmentItemOrder: {
            type: "array",
            items: { type: "string", format: "uuid" }
          },
          timelineIncludeInactive: { type: "boolean" },
          equipmentIncludeInactive: { type: "boolean" }
        }
      },
      EquipmentCategory: {
        type: "object",
        properties: {
          id: { type: "string", format: "uuid" },
          name: { type: "string" },
          itemCount: { type: "integer" },
          activeItemCount: { type: "integer" },
          serviceItemCount: { type: "integer" },
          retiredItemCount: { type: "integer" },
          createdAt: { type: "string", format: "date-time" },
          updatedAt: { type: "string", format: "date-time" }
        }
      },
      EquipmentCategoryRequest: {
        type: "object",
        required: ["name"],
        properties: {
          name: { type: "string", minLength: 2 }
        }
      },
      EquipmentItem: {
        type: "object",
        properties: {
          id: { type: "string", format: "uuid" },
          categoryId: { type: "string", format: "uuid" },
          categoryName: { type: "string" },
          name: { type: "string" },
          shortName: { type: "string", nullable: true },
          serialNumber: { type: "string", nullable: true },
          assetTag: { type: "string", nullable: true },
          suggestedDayRate: { type: "number", nullable: true, example: 150 },
          status: { type: "string", enum: ["active", "service", "retired"] },
          notes: { type: "string", nullable: true },
          isVisibleOnTimeline: { type: "boolean" },
          createdAt: { type: "string", format: "date-time" },
          updatedAt: { type: "string", format: "date-time" }
        }
      },
      EquipmentItemRequest: {
        type: "object",
        required: ["categoryId", "name", "status", "isVisibleOnTimeline"],
        properties: {
          categoryId: { type: "string", format: "uuid" },
          name: { type: "string" },
          shortName: { type: "string", nullable: true },
          serialNumber: { type: "string", nullable: true },
          assetTag: { type: "string", nullable: true },
          suggestedDayRate: { type: "number", nullable: true, example: 150 },
          status: { type: "string", enum: ["active", "service", "retired"] },
          notes: { type: "string", nullable: true },
          isVisibleOnTimeline: { type: "boolean" }
        }
      },
      EquipmentItemPatchRequest: {
        allOf: [{ $ref: "#/components/schemas/EquipmentItemRequest" }]
      },
      RentalBooking: {
        type: "object",
        properties: {
          id: { type: "string", format: "uuid" },
          equipmentItemId: { type: "string", format: "uuid" },
          customerName: { type: "string" },
          orderNumber: {
            type: "string",
            nullable: true,
            description: "Optional manual order number. When omitted on create or cleared on update, the system generates one automatically."
          },
          projectNumber: {
            type: "string",
            nullable: true,
            description: "Project identifier shared by bookings that belong to the same multi-device task. When omitted, the system generates one automatically."
          },
          projectName: { type: "string", nullable: true },
          notes: { type: "string", nullable: true },
          startDate: { type: "string", format: "date" },
          endDate: { type: "string", format: "date" },
          startTime: { type: "string", nullable: true, example: "09:00" },
          endTime: { type: "string", nullable: true, example: "17:00" },
          dayRate: { type: "number", nullable: true, example: 150 },
          totalPrice: { type: "number", nullable: true, example: 900 },
          createdBy: { type: "string", format: "uuid", nullable: true },
          createdByName: { type: "string", nullable: true },
          createdAt: { type: "string", format: "date-time" },
          updatedAt: { type: "string", format: "date-time" }
        }
      },
      RentalBookingCreateRequest: {
        type: "object",
        required: ["equipmentItemIds", "customerName", "startDate", "endDate"],
        properties: {
          equipmentItemIds: {
            type: "array",
            items: { type: "string", format: "uuid" }
          },
          customerName: { type: "string" },
          orderNumber: {
            type: "string",
            nullable: true,
            description: "Leave empty to generate an automatic order number."
          },
          projectNumber: {
            type: "string",
            nullable: true,
            description: "Leave empty to generate an automatic project number shared across all created bookings."
          },
          projectName: { type: "string", nullable: true },
          notes: { type: "string", nullable: true },
          startDate: { type: "string", format: "date" },
          endDate: { type: "string", format: "date" },
          dayRate: {
            type: "number",
            nullable: true,
            description: "Daily rate. If provided without totalPrice, the API calculates totalPrice as day count × dayRate."
          },
          totalPrice: {
            type: "number",
            nullable: true,
            description: "Optional manual total price override."
          },
          startTime: { type: "string", nullable: true, example: "09:00" },
          endTime: { type: "string", nullable: true, example: "17:00" },
          useSuggestedItemRates: {
            type: "boolean",
            default: false,
            description: "When true and many equipment items are selected, the API applies each item's suggestedDayRate."
          },
          allowConflict: { type: "boolean", default: false }
        }
      },
      RentalBookingUpdateRequest: {
        type: "object",
        required: ["equipmentItemId", "customerName", "startDate", "endDate"],
        properties: {
          equipmentItemId: { type: "string", format: "uuid" },
          customerName: { type: "string" },
          orderNumber: {
            type: "string",
            nullable: true,
            description: "Provide a manual number or leave empty to generate a new automatic one."
          },
          projectNumber: {
            type: "string",
            nullable: true,
            description: "Provide a manual project number or leave empty to preserve the current one or generate a new automatic one."
          },
          projectName: { type: "string", nullable: true },
          notes: { type: "string", nullable: true },
          startDate: { type: "string", format: "date" },
          endDate: { type: "string", format: "date" },
          dayRate: {
            type: "number",
            nullable: true,
            description: "Daily rate. If provided without totalPrice, the API recalculates totalPrice as day count × dayRate."
          },
          totalPrice: {
            type: "number",
            nullable: true,
            description: "Optional manual total price override."
          },
          startTime: { type: "string", nullable: true, example: "09:00" },
          endTime: { type: "string", nullable: true, example: "17:00" },
          allowConflict: { type: "boolean", default: false }
        }
      },
      RentalBookingScopePatchRequest: {
        type: "object",
        required: ["equipmentItemIds"],
        properties: {
          equipmentItemIds: {
            type: "array",
            items: { type: "string", format: "uuid" }
          },
          startDate: {
            type: "string",
            format: "date",
            description: "Optional new shared start date for the whole project scope."
          },
          endDate: {
            type: "string",
            format: "date",
            description: "Optional new shared end date for the whole project scope."
          },
          allowConflict: { type: "boolean", default: false }
        }
      },
      User: {
        type: "object",
        properties: {
          id: { type: "string", format: "uuid" },
          name: { type: "string" },
          email: { type: "string", format: "email" },
          role: { type: "string", enum: ["admin", "operator", "viewer", "technik"] },
          isActive: { type: "boolean" },
          createdAt: { type: "string", format: "date-time" },
          updatedAt: { type: "string", format: "date-time" }
        }
      },
      UserCreateRequest: {
        type: "object",
        required: ["name", "email", "password", "role", "isActive"],
        properties: {
          name: { type: "string" },
          email: { type: "string", format: "email" },
          password: { type: "string", minLength: 6 },
          role: { type: "string", enum: ["admin", "operator", "viewer", "technik"] },
          isActive: { type: "boolean" }
        }
      },
      UserUpdateRequest: {
        type: "object",
        properties: {
          name: { type: "string" },
          email: { type: "string", format: "email" },
          password: { type: "string", minLength: 6 },
          role: { type: "string", enum: ["admin", "operator", "viewer", "technik"] },
          isActive: { type: "boolean" }
        }
      },
      DeviceStatusOption: {
        type: "object",
        properties: {
          value: { type: "string", enum: ["active", "service", "retired"] },
          label: { type: "string" }
        }
      },
      RevenueByProductStat: {
        type: "object",
        properties: {
          categoryId: { type: "string", format: "uuid" },
          categoryName: { type: "string" },
          productKey: { type: "string" },
          productName: { type: "string" },
          productShortName: { type: "string", nullable: true },
          bookingCount: { type: "integer" },
          revenue: { type: "number" },
          lifetimeRevenue: { type: "number" }
        }
      },
      RevenueByCategoryStat: {
        type: "object",
        properties: {
          categoryId: { type: "string", format: "uuid" },
          categoryName: { type: "string" },
          bookingCount: { type: "integer" },
          revenue: { type: "number" },
          lifetimeRevenue: { type: "number" }
        }
      },
      RevenueByCustomerStat: {
        type: "object",
        properties: {
          customerName: { type: "string" },
          bookingCount: { type: "integer" },
          revenue: { type: "number" }
        }
      },
      UserClickStat: {
        type: "object",
        properties: {
          userId: { type: "string", format: "uuid" },
          userName: { type: "string" },
          clickDate: { type: "string", format: "date" },
          clickCount: { type: "integer" }
        }
      },
      UserClicksRequest: {
        type: "object",
        required: ["count"],
        properties: {
          count: { type: "integer", minimum: 1, maximum: 500 }
        }
      },
      StatsResponse: {
        type: "object",
        properties: {
          from: { type: "string", format: "date" },
          to: { type: "string", format: "date" },
          totalRevenue: { type: "number" },
          revenueByProduct: {
            type: "array",
            items: { $ref: "#/components/schemas/RevenueByProductStat" }
          },
          revenueByCategory: {
            type: "array",
            items: { $ref: "#/components/schemas/RevenueByCategoryStat" }
          },
          revenueByCustomer: {
            type: "array",
            items: { $ref: "#/components/schemas/RevenueByCustomerStat" }
          },
          userClicks: {
            type: "array",
            items: { $ref: "#/components/schemas/UserClickStat" }
          }
        }
      },
      TimelineResponse: {
        type: "object",
        properties: {
          range: {
            type: "object",
            properties: {
              from: { type: "string", format: "date" },
              to: { type: "string", format: "date" },
              dayCount: { type: "integer" }
            }
          },
          filters: {
            type: "object",
            properties: {
              from: { type: "string", format: "date" },
              to: { type: "string", format: "date" },
              categoryIds: {
                type: "array",
                items: { type: "string", format: "uuid" }
              },
              status: { type: "string", enum: ["all", "active", "service", "retired"] },
              search: { type: "string" },
              customerName: { type: "string" },
              includeInactive: { type: "boolean" }
            }
          },
          groups: {
            type: "array",
            items: {
              type: "object",
              properties: {
                categoryId: { type: "string", format: "uuid" },
                categoryName: { type: "string" },
                totalItems: { type: "integer" },
                visibleItems: { type: "integer" },
                items: {
                  type: "array",
                  items: {
                    allOf: [
                      { $ref: "#/components/schemas/EquipmentItem" },
                      {
                        type: "object",
                        properties: {
                          bookings: {
                            type: "array",
                            items: { $ref: "#/components/schemas/RentalBooking" }
                          }
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        example: {
          range: {
            from: "2026-04-15",
            to: "2026-05-26",
            dayCount: 42
          },
          filters: {
            from: "2026-04-15",
            to: "2026-05-26",
            categoryIds: [],
            status: "all",
            search: "",
            customerName: "",
            includeInactive: false
          },
          groups: [
            {
              categoryId: "7cf1d55a-7ad7-40b0-a2d8-d8cf6b526621",
              categoryName: "Laptop 14\"",
              totalItems: 2,
              visibleItems: 2,
              items: [
                {
                  id: "3ec5be1f-35f2-4933-92c1-4af32b5c5677",
                  categoryId: "7cf1d55a-7ad7-40b0-a2d8-d8cf6b526621",
                  categoryName: "Laptop 14\"",
                  name: "Dell Latitude 14 A",
                  serialNumber: "DL14-001",
                  assetTag: "L14-001",
                  status: "active",
                  notes: null,
                  isVisibleOnTimeline: true,
                  createdAt: "2026-04-21T09:00:00.000Z",
                  updatedAt: "2026-04-21T09:00:00.000Z",
                  bookings: [
                    {
                      id: "6bfa14b5-f3dc-48c8-a783-083a40d3eb69",
                      equipmentItemId: "3ec5be1f-35f2-4933-92c1-4af32b5c5677",
                      customerName: "Acme Events",
                      orderNumber: "ZAM-1001",
                      projectName: "Roadshow Q2",
                      notes: "Seed demo reservation",
                      startDate: "2026-04-19",
                      endDate: "2026-04-25",
                      createdBy: "4fb136ae-81b4-458a-8ee0-a772d70e490f",
                      createdByName: "Katarzyna Operator",
                      createdAt: "2026-04-21T09:01:00.000Z",
                      updatedAt: "2026-04-21T09:01:00.000Z"
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    }
  }
};
