// This is your Prisma schema file,
// learn more about the docs: https://pris.ly/d/prisma-schema

// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init

generator client {
  provider      = "prisma-client-js"
  output        = "../generated/prisma/client"
  binaryTargets = ["native", "debian-openssl-1.1.x"]
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

// Enum para los roles de usuario en la aplicación
enum UserRole {
  ADMIN // Administrador con control total
  MANAGER // Gerente con permisos de gestión
  STAFF // Personal con permisos operativos
  VIEWER // Solo lectura
}

// Modelo para los usuarios de la aplicación
model User {
  id          String       @id @default(uuid())
  username    String       @unique // Nombre de usuario único para login
  name        String // Nombre completo del usuario
  email       String       @unique // Email único para el usuario
  password    String // Contraseña (debe ser hasheada)
  role        UserRole     @default(STAFF) // Rol del usuario, por defecto STAFF
  isActive    Boolean      @default(true) // Indica si la cuenta está activa
  createdAt   DateTime     @default(now()) // Fecha de creación del registro
  updatedAt   DateTime     @updatedAt // Fecha de última actualización del registro
  movements   Movement[] // Relación con los movimientos realizados por este usuario
  assignments Assignment[] // Relación con las asignaciones creadas por este usuario
}

// Enum para los departamentos de los destinatarios
enum RecipientDepartment {
  IT
  ENGINEERING // Cambiado de ING a ENGINEERING para mayor claridad
  LOGISTICS // Cambiado de LNG a LOGISTICS
  TRAFFIC
  DRIVER
  ADMINISTRATION
  SALES
  OTHER
}

// Modelo para los destinatarios de los ítems (personas o áreas a las que se asignan cosas)
model Recipient {
  id          String               @id @default(uuid())
  username    String               @unique // Nombre de usuario o identificador único del destinatario
  firstName   String // Nombre del destinatario
  lastName    String // Apellido del destinatario
  department  RecipientDepartment? // Departamento del destinatario, usando el enum
  email       String?              @unique // Email opcional del destinatario
  phone       String? // Teléfono opcional del destinatario
  isActive    Boolean              @default(true) // Indica si el destinatario está activo
  createdAt   DateTime             @default(now())
  updatedAt   DateTime             @updatedAt // Fecha de última actualización del registro
  assignments Assignment[] // Relación con las asignaciones de ítems a este destinatario
  movements   Movement[] // Relación con los movimientos de ítems relacionados con este destinatario

  @@index([lastName, firstName]) // Índice para búsquedas por nombre y apellido
  @@index([department]) // Nuevo índice para búsquedas por departamento
}

// Modelo para las categorías de ítems
model Category {
  id          String   @id @default(uuid())
  name        String   @unique // Nombre único de la categoría
  description String? // Descripción opcional de la categoría
  isActive    Boolean  @default(true) // Indica si la categoría está activa
  items       Item[] // Relación con los productos (ítems genéricos) de esta categoría
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt // Fecha de última actualización del registro

  @@index([name]) // Índice para búsquedas por nombre de categoría
}

// Enum para el estado de un ítem (ya sea Item o Asset)
enum ItemStatus {
  AVAILABLE // Disponible en stock
  ASSIGNED // Asignado a un destinatario
  RESERVED // Reservado para una asignación futura
  IN_REPAIR // En reparación
  BROKEN // Averiado e inutilizable
  STOLEN // Robado
  DISPOSED // Dado de baja/eliminado del inventario
}

// Modelo para ítems genéricos (sin número de serie individual, se gestionan por cantidad)
model Item {
  id          String       @id @default(uuid())
  name        String // Nombre del producto
  description String? // Descripción opcional del producto
  categoryId  String // ID de la categoría a la que pertenece el producto
  category    Category     @relation(fields: [categoryId], references: [id]) // Relación con la categoría
  stock       Int          @default(0) // Cantidad actual en stock
  minStock    Int? // Nivel mínimo de stock para alertas
  maxStock    Int? // Nivel máximo de stock deseado
  createdAt   DateTime     @default(now()) // Fecha de creación del registro
  updatedAt   DateTime     @updatedAt // Fecha de última actualización del registro
  deletedAt   DateTime? // Fecha de eliminación del registro
  movements   Movement[] // Relación con los movimientos de este producto
  assignments Assignment[] // Relación con las asignaciones de este producto (por cantidad)
  assets      Asset[] // Relación con los activos serializados que son de este tipo de producto

  @@index([categoryId]) // Índice para búsquedas por categoría
  @@index([name]) // Índice para búsquedas por nombre de producto
}

// Modelo para ítems serializados (activos individuales con número de serie único)
model Asset {
  id           String      @id @default(uuid())
  itemId       String? // ID del producto genérico al que pertenece este activo (opcional)
  item         Item?       @relation(fields: [itemId], references: [id]) // Relación con el producto genérico
  serialNumber String      @unique // Número de serie único y obligatorio para el activo
  deliveryNote String? // Número de albarán de entrega (opcional, puede ser para la entrada inicial)
  status       ItemStatus  @default(AVAILABLE) // Estado actual del activo individual
  notes        String? // Notas adicionales sobre el activo
  createdAt    DateTime    @default(now()) // Fecha de creación del registro
  updatedAt    DateTime    @updatedAt // Fecha de última actualización del registro
  movements    Movement[] // Relación con los movimientos de este activo
  assignment   Assignment? // Relación 1:1 con la asignación activa de este activo (un activo solo puede estar en una asignación activa)

  @@index([serialNumber]) // Índice para búsquedas por número de serie
  @@index([itemId]) // Índice para búsquedas por producto asociado
  @@index([status]) // Índice para búsquedas por estado del activo
}

// Modelo para registrar las asignaciones de ítems a destinatarios
model Assignment {
  id             String     @id @default(uuid())
  quantity       Int? // Cantidad asignada (solo si es un Item, para Asset sería 1 implícitamente)
  notes          String? // Notas sobre la asignación
  itemId         String? // ID del producto genérico asignado (si no es un activo serializado)
  item           Item?      @relation(fields: [itemId], references: [id]) // Relación con el producto
  assetId        String?    @unique // ID del activo serializado asignado (si es un activo, debe ser único para asignaciones activas)
  asset          Asset?     @relation(fields: [assetId], references: [id]) // Relación con el activo
  recipientId    String? // ID del destinatario de la asignación
  recipient      Recipient? @relation(fields: [recipientId], references: [id], onDelete: Cascade, onUpdate: Cascade) // Relación con el destinatario
  assignmentDate DateTime   @default(now()) // Fecha en que se realizó la asignación
  returnDate     DateTime? // Fecha en que se devolvió la asignación (si aplica)
  createdBy      String // ID del usuario que realizó la asignación
  createdUser    User       @relation(fields: [createdBy], references: [id]) // Relación con el usuario que creó la asignación
  createdAt      DateTime   @default(now()) // Fecha de creación del registro de asignación
  updatedAt      DateTime   @updatedAt // Fecha de última actualización del registro
  movement       Movement[] // Relación con los movimientos generados por esta asignación (ej. OUT, RETURN)

  // Índices para mejorar el rendimiento de las consultas
  @@index([itemId])
  @@index([assetId])
  @@index([recipientId])
  @@index([createdBy])
}

// Enum para los tipos de movimiento de stock
enum MovementType {
  IN // Entrada de stock (compra, fabricación)
  OUT // Salida de stock (venta, consumo)
  ASSIGNMENT // Movimiento asociado a una asignación
  RETURN // Movimiento asociado a la devolución de una asignación
  ADJUSTMENT // Ajuste de inventario (corrección, pérdida)
  DELETED // Eliminación de un ítem
}

// Modelo para el histórico de todos los movimientos de stock/activos
model Movement {
  id            String       @id @default(uuid())
  type          MovementType @default(IN) // Tipo de movimiento
  quantity      Int // Cantidad del movimiento (para Item, para Asset sería 1)
  details       String? // Detalles adicionales del movimiento
  notes         String? // Notas sobre el movimiento
  itemId        String? // ID del producto afectado (si es un Item)
  item          Item?        @relation(fields: [itemId], references: [id]) // Relación con el producto
  assetId       String? // ID del activo afectado (si es un Asset)
  asset         Asset?       @relation(fields: [assetId], references: [id]) // Relación con el activo
  previousStock Int? // Stock antes de este movimiento (solo para Item)
  newStock      Int? // Stock después de este movimiento (solo para Item)
  recipientId   String? // ID del destinatario relacionado con el movimiento (si aplica)
  recipient     Recipient?   @relation(fields: [recipientId], references: [id]) // Relación con el destinatario
  assignmentId  String? // ID de la asignación relacionada (si el movimiento es ASSIGNMENT o RETURN)
  assignment    Assignment?  @relation(fields: [assignmentId], references: [id]) // Relación con la asignación
  userId        String // ID del usuario que realizó el movimiento
  user          User         @relation(fields: [userId], references: [id]) // Relación con el usuario
  createdAt     DateTime     @default(now()) // Fecha en que se registró el movimiento

  // Índices para mejorar el rendimiento de las consultas
  @@index([itemId])
  @@index([assetId])
  @@index([recipientId])
  @@index([type])
  @@index([userId])
}
