-- Migration 008: M:N Exercise Relations + Hierarchical Catalogs
-- Erstellt: 2026-04-23
-- Beschreibung: Umstellung von 1:1 auf M:N Beziehungen + Hierarchie Fokusbereich → Stil → Zielgruppe

-- ============================================================================
-- PHASE 1: Hierarchische Struktur aufbauen
-- ============================================================================

-- training_styles erweitern: Hierarchie zu focus_areas
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name='training_styles' AND column_name='focus_area_id') THEN
        ALTER TABLE training_styles
        ADD COLUMN focus_area_id INT REFERENCES focus_areas(id);
    END IF;
END $$;

CREATE INDEX IF NOT EXISTS idx_training_styles_focus_area ON training_styles(focus_area_id);

-- Zielgruppen-Tabelle (NEU)
CREATE TABLE IF NOT EXISTS target_groups (
    id SERIAL PRIMARY KEY,
    training_style_id INT REFERENCES training_styles(id),  -- Hierarchie-Link
    name VARCHAR(100) NOT NULL,
    description TEXT,
    min_age INT,
    max_age INT,
    sort_order INT,
    status VARCHAR(50) DEFAULT 'active',
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_target_groups_style ON target_groups(training_style_id);
CREATE INDEX IF NOT EXISTS idx_target_groups_status ON target_groups(status);

-- ============================================================================
-- PHASE 2: M:N Zuordnungstabellen
-- ============================================================================

-- Übung ↔ Fokusbereiche (M:N)
CREATE TABLE IF NOT EXISTS exercise_focus_areas (
    id SERIAL PRIMARY KEY,
    exercise_id INT REFERENCES exercises(id) ON DELETE CASCADE,
    focus_area_id INT REFERENCES focus_areas(id),
    is_primary BOOLEAN DEFAULT false,
    created_at TIMESTAMP DEFAULT NOW(),
    UNIQUE(exercise_id, focus_area_id)
);

CREATE INDEX IF NOT EXISTS idx_exercise_focus_areas_exercise ON exercise_focus_areas(exercise_id);
CREATE INDEX IF NOT EXISTS idx_exercise_focus_areas_focus ON exercise_focus_areas(focus_area_id);
CREATE INDEX IF NOT EXISTS idx_exercise_focus_areas_primary ON exercise_focus_areas(is_primary);

-- Übung ↔ Stile (M:N)
CREATE TABLE IF NOT EXISTS exercise_styles (
    id SERIAL PRIMARY KEY,
    exercise_id INT REFERENCES exercises(id) ON DELETE CASCADE,
    training_style_id INT REFERENCES training_styles(id),
    is_primary BOOLEAN DEFAULT false,
    created_at TIMESTAMP DEFAULT NOW(),
    UNIQUE(exercise_id, training_style_id)
);

CREATE INDEX IF NOT EXISTS idx_exercise_styles_exercise ON exercise_styles(exercise_id);
CREATE INDEX IF NOT EXISTS idx_exercise_styles_style ON exercise_styles(training_style_id);
CREATE INDEX IF NOT EXISTS idx_exercise_styles_primary ON exercise_styles(is_primary);

-- Übung ↔ Zielgruppen (M:N)
CREATE TABLE IF NOT EXISTS exercise_target_groups (
    id SERIAL PRIMARY KEY,
    exercise_id INT REFERENCES exercises(id) ON DELETE CASCADE,
    target_group_id INT REFERENCES target_groups(id),
    is_primary BOOLEAN DEFAULT false,
    created_at TIMESTAMP DEFAULT NOW(),
    UNIQUE(exercise_id, target_group_id)
);

CREATE INDEX IF NOT EXISTS idx_exercise_target_groups_exercise ON exercise_target_groups(exercise_id);
CREATE INDEX IF NOT EXISTS idx_exercise_target_groups_target ON exercise_target_groups(target_group_id);
CREATE INDEX IF NOT EXISTS idx_exercise_target_groups_primary ON exercise_target_groups(is_primary);

-- Übung ↔ Altersgruppen (M:N - separate Dimension)
CREATE TABLE IF NOT EXISTS exercise_age_groups (
    id SERIAL PRIMARY KEY,
    exercise_id INT REFERENCES exercises(id) ON DELETE CASCADE,
    age_group VARCHAR(50) NOT NULL,  -- 'Minis', 'Kinder', 'Schüler', 'Teenager', 'Erwachsene'
    created_at TIMESTAMP DEFAULT NOW(),
    UNIQUE(exercise_id, age_group),
    CHECK (age_group IN ('Minis', 'Kinder', 'Schüler', 'Teenager', 'Erwachsene'))
);

CREATE INDEX IF NOT EXISTS idx_exercise_age_groups_exercise ON exercise_age_groups(exercise_id);
CREATE INDEX IF NOT EXISTS idx_exercise_age_groups_age ON exercise_age_groups(age_group);

-- ============================================================================
-- PHASE 3: Daten-Migration (Altdaten von 1:1 zu M:N)
-- ============================================================================

-- Migriere focus_area_id → exercise_focus_areas (als primäre Zuordnung)
INSERT INTO exercise_focus_areas (exercise_id, focus_area_id, is_primary)
SELECT id, focus_area_id, true
FROM exercises
WHERE focus_area_id IS NOT NULL
ON CONFLICT (exercise_id, focus_area_id) DO NOTHING;

-- Migriere training_style_id → exercise_styles (als primäre Zuordnung)
INSERT INTO exercise_styles (exercise_id, training_style_id, is_primary)
SELECT id, training_style_id, true
FROM exercises
WHERE training_style_id IS NOT NULL
ON CONFLICT (exercise_id, training_style_id) DO NOTHING;

-- ============================================================================
-- PHASE 4: Basis-Daten für Zielgruppen
-- ============================================================================

-- Beispiel-Zielgruppen für Shotokan (training_style_id = 1, falls vorhanden)
DO $$
DECLARE
    shotokan_id INT;
BEGIN
    SELECT id INTO shotokan_id FROM training_styles WHERE name = 'Shotokan' LIMIT 1;

    IF shotokan_id IS NOT NULL THEN
        INSERT INTO target_groups (training_style_id, name, description, sort_order) VALUES
        (shotokan_id, 'Breitensportler', 'Karate für Freizeit und Fitness', 1),
        (shotokan_id, 'Leistungssportler', 'Wettkampforientiertes Training', 2),
        (shotokan_id, 'Kinder', 'Karate für Kinder (6-12 Jahre)', 3)
        ON CONFLICT DO NOTHING;
    END IF;
END $$;

-- ============================================================================
-- PHASE 5: Hierarchie-Daten (Stile zu Fokusbereichen zuordnen)
-- ============================================================================

-- Ordne Karate-Stile dem Fokusbereich "Karate" zu
DO $$
DECLARE
    karate_id INT;
BEGIN
    SELECT id INTO karate_id FROM focus_areas WHERE name = 'Karate' LIMIT 1;

    IF karate_id IS NOT NULL THEN
        UPDATE training_styles
        SET focus_area_id = karate_id
        WHERE name IN ('Shotokan', 'Goju-Ryu', 'Wado-Ryu', 'Shito-Ryu', 'Kyokushin')
        AND focus_area_id IS NULL;
    END IF;
END $$;

-- ============================================================================
-- HINWEISE für spätere Migrationen
-- ============================================================================

-- Die folgenden Spalten in exercises können später gedroppt werden:
-- - focus_area_id (deprecated, durch exercise_focus_areas ersetzt)
-- - training_style_id (deprecated, durch exercise_styles ersetzt)
-- - training_character_id (bleibt vorerst, separate Dimension)

-- Aktuell bleiben sie zur Rückwärtskompatibilität erhalten.
-- Neue Übungen sollten NUR über M:N-Tabellen zugeordnet werden.
-- API-Endpoints sollten enriched data aus M:N-Tabellen liefern.
