-- =============================================================
-- ARCHIVO: 19-product-attributes.sql
-- DESCRIPCION: Atributos de productos (color, talla, material)
-- VERSION: 1.0.0
-- PROYECTO: ERP-Core V2
-- FECHA: 2026-01-24
-- =============================================================

-- =====================
-- TABLA: product_attributes
-- Atributos configurables de productos
-- =====================
CREATE TABLE IF NOT EXISTS products.product_attributes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,

    -- Identificacion
    code VARCHAR(50) NOT NULL,
    name VARCHAR(100) NOT NULL,
    description TEXT,

    -- Tipo de visualizacion
    display_type VARCHAR(20) DEFAULT 'radio', -- radio, select, color, pills

    -- Estado
    is_active BOOLEAN DEFAULT TRUE,
    sort_order INTEGER DEFAULT 0,

    -- Metadata
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_by UUID REFERENCES auth.users(id),

    UNIQUE(tenant_id, code)
);

-- Indices para product_attributes
CREATE INDEX IF NOT EXISTS idx_product_attributes_tenant ON products.product_attributes(tenant_id);
CREATE INDEX IF NOT EXISTS idx_product_attributes_code ON products.product_attributes(code);
CREATE INDEX IF NOT EXISTS idx_product_attributes_active ON products.product_attributes(is_active) WHERE is_active = TRUE;

-- =====================
-- TABLA: product_attribute_values
-- Valores posibles para cada atributo
-- =====================
CREATE TABLE IF NOT EXISTS products.product_attribute_values (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    attribute_id UUID NOT NULL REFERENCES products.product_attributes(id) ON DELETE CASCADE,

    -- Identificacion
    code VARCHAR(50),
    name VARCHAR(100) NOT NULL,

    -- Visualizacion
    html_color VARCHAR(20),      -- Para atributos de tipo color (#FF0000)
    image_url VARCHAR(500),      -- Imagen del valor

    -- Estado
    is_active BOOLEAN DEFAULT TRUE,
    sort_order INTEGER DEFAULT 0,

    -- Metadata
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

-- Indices para product_attribute_values
CREATE INDEX IF NOT EXISTS idx_product_attribute_values_attribute ON products.product_attribute_values(attribute_id);
CREATE INDEX IF NOT EXISTS idx_product_attribute_values_active ON products.product_attribute_values(is_active) WHERE is_active = TRUE;

-- =====================
-- TABLA: product_variants
-- Variantes de productos (combinaciones de atributos)
-- =====================
CREATE TABLE IF NOT EXISTS products.product_variants (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    product_id UUID NOT NULL REFERENCES products.products(id) ON DELETE CASCADE,
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,

    -- Identificacion
    sku VARCHAR(50) NOT NULL,
    barcode VARCHAR(50),
    name VARCHAR(200) NOT NULL,      -- Nombre de la variante (ej: "Camisa Azul - Talla M")

    -- Precios (override del producto base)
    price_extra DECIMAL(15, 4) DEFAULT 0,    -- Ajuste de precio sobre el producto base
    cost_extra DECIMAL(15, 4) DEFAULT 0,     -- Ajuste de costo sobre el producto base

    -- Inventario
    stock_qty DECIMAL(15, 4) DEFAULT 0,

    -- Imagen
    image_url VARCHAR(500),

    -- Estado
    is_active BOOLEAN DEFAULT TRUE,

    -- Metadata
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_by UUID REFERENCES auth.users(id),

    UNIQUE(tenant_id, sku)
);

-- Indices para product_variants
CREATE INDEX IF NOT EXISTS idx_product_variants_product ON products.product_variants(product_id);
CREATE INDEX IF NOT EXISTS idx_product_variants_tenant ON products.product_variants(tenant_id);
CREATE INDEX IF NOT EXISTS idx_product_variants_sku ON products.product_variants(sku);
CREATE INDEX IF NOT EXISTS idx_product_variants_barcode ON products.product_variants(barcode);
CREATE INDEX IF NOT EXISTS idx_product_variants_active ON products.product_variants(is_active) WHERE is_active = TRUE;

-- =====================
-- TABLA: product_variant_attributes
-- Relacion M:N entre variantes y valores de atributos
-- =====================
CREATE TABLE IF NOT EXISTS products.product_variant_attributes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    variant_id UUID NOT NULL REFERENCES products.product_variants(id) ON DELETE CASCADE,
    attribute_value_id UUID NOT NULL REFERENCES products.product_attribute_values(id) ON DELETE CASCADE,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    UNIQUE(variant_id, attribute_value_id)
);

-- Indices para product_variant_attributes
CREATE INDEX IF NOT EXISTS idx_product_variant_attributes_variant ON products.product_variant_attributes(variant_id);
CREATE INDEX IF NOT EXISTS idx_product_variant_attributes_value ON products.product_variant_attributes(attribute_value_id);

-- =====================
-- COMENTARIOS
-- =====================
COMMENT ON TABLE products.product_attributes IS 'Definicion de atributos de productos (color, talla, material, etc.)';
COMMENT ON COLUMN products.product_attributes.display_type IS 'Tipo de visualizacion: radio (botones radio), select (dropdown), color (muestra de colores), pills (etiquetas)';

COMMENT ON TABLE products.product_attribute_values IS 'Valores posibles para cada atributo (ej: Rojo, Verde, Azul para atributo Color)';
COMMENT ON COLUMN products.product_attribute_values.html_color IS 'Color HTML para visualizar en UI (#FF0000)';

COMMENT ON TABLE products.product_variants IS 'Variantes de productos generadas a partir de combinaciones de atributos';
COMMENT ON COLUMN products.product_variants.price_extra IS 'Ajuste de precio sobre el precio base del producto';
COMMENT ON COLUMN products.product_variants.cost_extra IS 'Ajuste de costo sobre el costo base del producto';

COMMENT ON TABLE products.product_variant_attributes IS 'Tabla de union entre variantes y valores de atributos';

-- =====================
-- RLS (Row Level Security)
-- =====================
ALTER TABLE products.product_attributes ENABLE ROW LEVEL SECURITY;
ALTER TABLE products.product_attribute_values ENABLE ROW LEVEL SECURITY;
ALTER TABLE products.product_variants ENABLE ROW LEVEL SECURITY;
ALTER TABLE products.product_variant_attributes ENABLE ROW LEVEL SECURITY;

-- Politicas RLS para product_attributes
DROP POLICY IF EXISTS product_attributes_tenant_isolation ON products.product_attributes;
CREATE POLICY product_attributes_tenant_isolation ON products.product_attributes
    FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

-- Politicas RLS para product_variants
DROP POLICY IF EXISTS product_variants_tenant_isolation ON products.product_variants;
CREATE POLICY product_variants_tenant_isolation ON products.product_variants
    FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

-- Politicas RLS para product_attribute_values (via JOIN con attribute)
DROP POLICY IF EXISTS product_attribute_values_tenant_isolation ON products.product_attribute_values;
CREATE POLICY product_attribute_values_tenant_isolation ON products.product_attribute_values
    FOR ALL USING (
        attribute_id IN (
            SELECT id FROM products.product_attributes
            WHERE tenant_id = current_setting('app.current_tenant_id', true)::uuid
        )
    );

-- Politicas RLS para product_variant_attributes (via JOIN con variant)
DROP POLICY IF EXISTS product_variant_attributes_tenant_isolation ON products.product_variant_attributes;
CREATE POLICY product_variant_attributes_tenant_isolation ON products.product_variant_attributes
    FOR ALL USING (
        variant_id IN (
            SELECT id FROM products.product_variants
            WHERE tenant_id = current_setting('app.current_tenant_id', true)::uuid
        )
    );
