-- ============================================
-- rioCata - Sistema de Catación de Café
-- Schema de Base de Datos
-- ============================================

-- Habilitar extensiones necesarias
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- ============================================
-- TIPOS ENUMERADOS
-- ============================================

-- Tipo de defecto en la catación
CREATE TYPE defecto_tipo AS ENUM ('Mohoso', 'Fenólico', 'Papa');

-- ============================================
-- TABLAS
-- ============================================

-- Sesiones de catación
CREATE TABLE sesion (
  id              uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  codigo          text UNIQUE,                   -- opcional: código visible (ej. "S-2025-10-17-01")
  fecha           date NOT NULL,
  nombre          text,                          -- ej. "Mesa #3 Lotes Lavados"
  created_at      timestamptz NOT NULL DEFAULT now()
);

COMMENT ON TABLE sesion IS 'Sesiones de catación de café';
COMMENT ON COLUMN sesion.codigo IS 'Código único identificador de la sesión';
COMMENT ON COLUMN sesion.fecha IS 'Fecha en que se realiza la catación';
COMMENT ON COLUMN sesion.nombre IS 'Nombre descriptivo de la sesión';

-- Crear schema auth si no existe (antes de crear la tabla)
CREATE SCHEMA IF NOT EXISTS auth;

-- Tabla de usuarios (simula auth.users de Supabase para desarrollo local)
-- En producción se usaría directamente auth.users de Supabase
CREATE TABLE auth.users (
  id              uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  email           text UNIQUE NOT NULL,
  nombre          text,
  created_at      timestamptz NOT NULL DEFAULT now()
);

COMMENT ON TABLE auth.users IS 'Tabla de usuarios (simula auth.users de Supabase para desarrollo)';

-- Participantes (catadores) por sesión
CREATE TABLE sesion_participante (
  id              uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  sesion_id       uuid NOT NULL REFERENCES sesion(id) ON DELETE CASCADE,
  catador_id      uuid NOT NULL REFERENCES auth.users(id) ON DELETE RESTRICT,
  rol             text DEFAULT 'catador',        -- opcional: juez, invitado, etc.
  UNIQUE (sesion_id, catador_id)
);

COMMENT ON TABLE sesion_participante IS 'Relación de participantes (catadores) en sesiones de catación';
COMMENT ON COLUMN sesion_participante.rol IS 'Rol del participante: catador, juez, invitado, etc.';

-- Muestras pertenecen a una sesión
CREATE TABLE muestra (
  id              uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  sesion_id       uuid NOT NULL REFERENCES sesion(id) ON DELETE CASCADE,
  codigo          text NOT NULL,                 -- "Muestra 1", "A-101", etc.
  posicion        int,                           -- ej. orden físico en mesa
  UNIQUE (sesion_id, codigo)
);

COMMENT ON TABLE muestra IS 'Muestras de café a ser evaluadas en una sesión';
COMMENT ON COLUMN muestra.codigo IS 'Código identificador de la muestra dentro de la sesión';
COMMENT ON COLUMN muestra.posicion IS 'Orden físico de la muestra en la mesa de catación';

-- Evaluación de una muestra hecha por un participante específico de esa sesión
CREATE TABLE evaluacion (
  id                   uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  muestra_id           uuid NOT NULL REFERENCES muestra(id) ON DELETE CASCADE,
  sesion_participante_id uuid NOT NULL REFERENCES sesion_participante(id) ON DELETE CASCADE,

  -- JSONB según lo acordado
  intensidades         jsonb NOT NULL,           -- { fragancia: {descriptiva, afectiva}, ... }
  fragancia_aroma_notas jsonb DEFAULT '[]',      -- array de objetos [{categoria, subcategoria, notaEspecifica}]
  sabor_notas          jsonb DEFAULT '[]',       -- array de objetos

  -- Arrays según lo acordado
  tazas_no_uniformes   smallint[] DEFAULT '{}',  -- valores 1..5
  tazas_defectuosas    smallint[] DEFAULT '{}',  -- valores 1..5
  sensacion_en_boca    text[]     DEFAULT '{}',  -- Áspero, Suave, Aceitoso, Metálico, Astringente
  gustos_predominantes text[]     DEFAULT '{}',  -- 1..2 elementos entre Salado, Amargo, Ácido, Dulce, Umami

  defecto              defecto_tipo,             -- opcional
  otras_notas          text,
  puntaje_final        int,                      -- guardado por trigger

  created_at           timestamptz NOT NULL DEFAULT now(),
  updated_at           timestamptz NOT NULL DEFAULT now(),

  -- Una evaluación por participante por muestra
  UNIQUE (muestra_id, sesion_participante_id),

  -- Constraints de validez
  CHECK (tazas_no_uniformes   <@ ARRAY[1,2,3,4,5]::smallint[]),
  CHECK (tazas_defectuosas    <@ ARRAY[1,2,3,4,5]::smallint[]),

  CHECK (sensacion_en_boca    <@ ARRAY['Áspero','Suave','Aceitoso','Metálico','Astringente']::text[]),
  CHECK (gustos_predominantes <@ ARRAY['Salado','Amargo','Ácido','Dulce','Umami']::text[]),
  CHECK (COALESCE(array_length(gustos_predominantes,1),0) BETWEEN 0 AND 2),

  -- Validación de rangos en intensidades (descriptiva 1..15, afectiva 1..10)
  CHECK (NOT jsonb_path_exists(intensidades, '$.*.descriptiva ? (@ < 1 || @ > 15)')),
  CHECK (NOT jsonb_path_exists(intensidades, '$.*.afectiva   ? (@ < 1 || @ > 10)'))
);

COMMENT ON TABLE evaluacion IS 'Evaluaciones de muestras realizadas por catadores';
COMMENT ON COLUMN evaluacion.intensidades IS 'Intensidades descriptivas y afectivas de los 8 parámetros evaluados';
COMMENT ON COLUMN evaluacion.fragancia_aroma_notas IS 'Array de familias de fragancia/aroma (categoría, subcategoría, nota específica)';
COMMENT ON COLUMN evaluacion.sabor_notas IS 'Array de familias de sabor (categoría, subcategoría, nota específica)';
COMMENT ON COLUMN evaluacion.tazas_no_uniformes IS 'Números de taza (1-5) que no fueron uniformes';
COMMENT ON COLUMN evaluacion.tazas_defectuosas IS 'Números de taza (1-5) con defectos graves';
COMMENT ON COLUMN evaluacion.sensacion_en_boca IS 'Sensaciones táctiles: Áspero, Suave, Aceitoso, Metálico, Astringente';
COMMENT ON COLUMN evaluacion.gustos_predominantes IS 'Gustos básicos predominantes (1-2): Salado, Amargo, Ácido, Dulce, Umami';
COMMENT ON COLUMN evaluacion.defecto IS 'Tipo de defecto identificado si aplica';
COMMENT ON COLUMN evaluacion.otras_notas IS 'Notas adicionales del catador en texto libre';
COMMENT ON COLUMN evaluacion.puntaje_final IS 'Suma de los valores afectivos (calculado automáticamente por trigger)';
