-- Migration: Banner Consent Tables
-- Für @breakpilot/consent-sdk
-- DSGVO/TTDSG-konforme Speicherung von Cookie-Einwilligungen

-- ========================================
-- Banner Consents (anonyme Einwilligungen)
-- ========================================

CREATE TABLE IF NOT EXISTS banner_consents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    site_id VARCHAR(50) NOT NULL,
    device_fingerprint VARCHAR(64) NOT NULL,
    user_id VARCHAR(100),  -- Optional: Für eingeloggte Nutzer

    -- Consent-Daten
    categories JSONB NOT NULL DEFAULT '{}',  -- { "analytics": true, "marketing": false }
    vendors JSONB DEFAULT '{}',               -- { "google-analytics": true }
    tcf_string TEXT,                          -- IAB TCF String

    -- Metadaten (anonymisiert)
    ip_hash VARCHAR(64),                      -- Anonymisierte IP
    user_agent TEXT,
    language VARCHAR(10),
    platform VARCHAR(20),                     -- web, ios, android
    app_version VARCHAR(20),

    -- Versionierung
    version VARCHAR(20) DEFAULT '1.0.0',

    -- Zeitstempel
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    expires_at TIMESTAMPTZ,
    revoked_at TIMESTAMPTZ,

    -- Constraints
    CONSTRAINT unique_site_device UNIQUE (site_id, device_fingerprint)
);

-- Indizes für schnelle Abfragen
CREATE INDEX IF NOT EXISTS idx_banner_consents_site ON banner_consents(site_id);
CREATE INDEX IF NOT EXISTS idx_banner_consents_user ON banner_consents(user_id) WHERE user_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_banner_consents_device ON banner_consents(device_fingerprint);
CREATE INDEX IF NOT EXISTS idx_banner_consents_created ON banner_consents(created_at);
CREATE INDEX IF NOT EXISTS idx_banner_consents_expires ON banner_consents(expires_at) WHERE expires_at IS NOT NULL;

-- ========================================
-- Audit Log (unveränderbar)
-- ========================================

CREATE TABLE IF NOT EXISTS banner_consent_audit_log (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    consent_id UUID NOT NULL,
    action VARCHAR(20) NOT NULL,  -- created, updated, revoked
    details JSONB,
    ip_hash VARCHAR(64),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Kein UPDATE/DELETE auf Audit-Log
-- REVOKE UPDATE, DELETE ON banner_consent_audit_log FROM PUBLIC;

CREATE INDEX IF NOT EXISTS idx_banner_audit_consent ON banner_consent_audit_log(consent_id);
CREATE INDEX IF NOT EXISTS idx_banner_audit_created ON banner_consent_audit_log(created_at);

-- ========================================
-- Site-Konfigurationen
-- ========================================

CREATE TABLE IF NOT EXISTS banner_site_configs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    site_id VARCHAR(50) UNIQUE NOT NULL,
    site_name VARCHAR(100) NOT NULL,

    -- UI-Konfiguration
    ui_theme VARCHAR(20) DEFAULT 'auto',
    ui_position VARCHAR(20) DEFAULT 'bottom',
    ui_layout VARCHAR(20) DEFAULT 'modal',
    custom_css TEXT,

    -- Rechtliche Links
    privacy_policy_url VARCHAR(255),
    imprint_url VARCHAR(255),
    dpo_name VARCHAR(100),
    dpo_email VARCHAR(100),

    -- TCF 2.2
    tcf_enabled BOOLEAN DEFAULT FALSE,
    tcf_cmp_id INTEGER,
    tcf_cmp_version INTEGER,

    -- Zeitstempel
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- ========================================
-- Kategorie-Konfigurationen pro Site
-- ========================================

CREATE TABLE IF NOT EXISTS banner_category_configs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    site_id VARCHAR(50) NOT NULL,
    category_id VARCHAR(50) NOT NULL,

    -- Namen (mehrsprachig)
    name_de VARCHAR(100) NOT NULL,
    name_en VARCHAR(100),

    -- Beschreibungen (mehrsprachig)
    description_de TEXT,
    description_en TEXT,

    -- Einstellungen
    is_required BOOLEAN DEFAULT FALSE,
    sort_order INTEGER DEFAULT 0,
    is_active BOOLEAN DEFAULT TRUE,

    -- Zeitstempel
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),

    CONSTRAINT unique_site_category UNIQUE (site_id, category_id)
);

-- ========================================
-- Vendor-Konfigurationen
-- ========================================

CREATE TABLE IF NOT EXISTS banner_vendor_configs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    site_id VARCHAR(50) NOT NULL,
    category_id VARCHAR(50) NOT NULL,
    vendor_id VARCHAR(100) NOT NULL,

    -- Vendor-Informationen
    name VARCHAR(100) NOT NULL,
    privacy_policy_url VARCHAR(255),
    data_retention VARCHAR(50),
    data_transfer VARCHAR(100),

    -- TCF
    tcf_vendor_id INTEGER,
    tcf_purposes JSONB,
    tcf_legitimate_interests JSONB,

    -- Cookies
    cookies JSONB DEFAULT '[]',

    -- Zeitstempel
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),

    CONSTRAINT unique_site_vendor UNIQUE (site_id, vendor_id)
);

-- ========================================
-- Helper-Funktionen
-- ========================================

-- Abgelaufene Consents bereinigen
CREATE OR REPLACE FUNCTION cleanup_expired_banner_consents()
RETURNS INTEGER AS $$
DECLARE
    deleted_count INTEGER;
BEGIN
    -- Soft-Delete nach 30 Tagen nach Ablauf
    WITH deleted AS (
        DELETE FROM banner_consents
        WHERE expires_at < NOW() - INTERVAL '30 days'
        AND revoked_at IS NULL
        RETURNING id
    )
    SELECT COUNT(*) INTO deleted_count FROM deleted;

    RETURN deleted_count;
END;
$$ LANGUAGE plpgsql;

-- Statistik-View
CREATE OR REPLACE VIEW banner_consent_stats AS
SELECT
    site_id,
    DATE(created_at) as consent_date,
    COUNT(*) as total_consents,
    COUNT(*) FILTER (WHERE revoked_at IS NOT NULL) as revoked_consents,
    COUNT(*) FILTER (WHERE (categories->>'analytics')::boolean = true) as analytics_accepted,
    COUNT(*) FILTER (WHERE (categories->>'marketing')::boolean = true) as marketing_accepted,
    COUNT(*) FILTER (WHERE (categories->>'functional')::boolean = true) as functional_accepted,
    COUNT(*) FILTER (WHERE (categories->>'social')::boolean = true) as social_accepted
FROM banner_consents
GROUP BY site_id, DATE(created_at);

-- ========================================
-- Standard-Kategorien einfügen
-- ========================================

INSERT INTO banner_category_configs (site_id, category_id, name_de, name_en, description_de, description_en, is_required, sort_order)
VALUES
    ('default', 'essential', 'Essentiell', 'Essential',
     'Notwendig für die Grundfunktionen der Website.',
     'Required for basic website functionality.',
     TRUE, 1),
    ('default', 'functional', 'Funktional', 'Functional',
     'Ermöglicht Personalisierung und Komfortfunktionen.',
     'Enables personalization and comfort features.',
     FALSE, 2),
    ('default', 'analytics', 'Statistik', 'Analytics',
     'Hilft uns, die Website zu verbessern.',
     'Helps us improve the website.',
     FALSE, 3),
    ('default', 'marketing', 'Marketing', 'Marketing',
     'Ermöglicht personalisierte Werbung.',
     'Enables personalized advertising.',
     FALSE, 4),
    ('default', 'social', 'Soziale Medien', 'Social Media',
     'Ermöglicht Inhalte von sozialen Netzwerken.',
     'Enables content from social networks.',
     FALSE, 5)
ON CONFLICT (site_id, category_id) DO NOTHING;

-- Fertig
SELECT 'Banner Consent Tables created successfully' as status;
