-- Migration 039: Vereins-Mitgliedschaft, Rollen pro Verein, aktiver Vereinskontext (Multi-Tenancy Phase 1)
-- Erstellt: 2026-05-05

-- Mitgliedschaft Profil ↔ Verein
CREATE TABLE club_members (
    id SERIAL PRIMARY KEY,
    profile_id INT NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
    club_id INT NOT NULL REFERENCES clubs(id) ON DELETE CASCADE,
    status VARCHAR(20) NOT NULL DEFAULT 'active',
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),
    UNIQUE(profile_id, club_id)
);

CREATE INDEX idx_club_members_profile ON club_members(profile_id);
CREATE INDEX idx_club_members_club ON club_members(club_id);
CREATE INDEX idx_club_members_status ON club_members(status);

-- Rollen pro Mitgliedschaft (role_code: club_admin, trainer, division_lead, content_editor)
CREATE TABLE club_member_roles (
    id SERIAL PRIMARY KEY,
    club_member_id INT NOT NULL REFERENCES club_members(id) ON DELETE CASCADE,
    role_code VARCHAR(50) NOT NULL,
    division_id INT REFERENCES divisions(id) ON DELETE CASCADE,
    created_at TIMESTAMP DEFAULT NOW(),
    UNIQUE (club_member_id, role_code)
);

CREATE INDEX idx_club_member_roles_member ON club_member_roles(club_member_id);
CREATE INDEX idx_club_member_roles_code ON club_member_roles(role_code);

-- Hauptverwalter:in (fachliche Referenz; Rechte über club_member_roles.club_admin)
ALTER TABLE clubs ADD COLUMN IF NOT EXISTS primary_admin_profile_id INT REFERENCES profiles(id) ON DELETE SET NULL;

CREATE INDEX idx_clubs_primary_admin ON clubs(primary_admin_profile_id);

-- Persistenz gewählter aktiver Verein (UI); Request-Header kann überschreiben
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS active_club_id INT REFERENCES clubs(id) ON DELETE SET NULL;

CREATE INDEX idx_profiles_active_club ON profiles(active_club_id);

-- ── Backfill: Trainer/Co-Trainer aus Trainingsgruppen → Mitgliedschaft + Rolle trainer
INSERT INTO club_members (profile_id, club_id, status)
SELECT DISTINCT t.trainer_id, t.club_id, 'active'
FROM training_groups t
WHERE t.trainer_id IS NOT NULL
ON CONFLICT (profile_id, club_id) DO NOTHING;

INSERT INTO club_members (profile_id, club_id, status)
SELECT DISTINCT elem::int, t.club_id, 'active'
FROM training_groups t,
LATERAL jsonb_array_elements_text(t.co_trainer_ids) AS elem
WHERE jsonb_typeof(t.co_trainer_ids) = 'array'
  AND jsonb_array_length(t.co_trainer_ids) > 0
ON CONFLICT (profile_id, club_id) DO NOTHING;

INSERT INTO club_member_roles (club_member_id, role_code)
SELECT cm.id, 'trainer'
FROM club_members cm
WHERE NOT EXISTS (
    SELECT 1 FROM club_member_roles r
    WHERE r.club_member_id = cm.id AND r.role_code = 'trainer'
);

-- Pro Verein: kleinste trainer_id einer Gruppe als primärer Admin (Pilot / CURR-008-Analog)
UPDATE clubs c
SET primary_admin_profile_id = sub.pid
FROM (
    SELECT DISTINCT ON (club_id)
        club_id,
        trainer_id AS pid
    FROM training_groups
    WHERE trainer_id IS NOT NULL
    ORDER BY club_id, id ASC
) sub
WHERE c.id = sub.club_id
  AND c.primary_admin_profile_id IS NULL;

INSERT INTO club_member_roles (club_member_id, role_code)
SELECT cm.id, 'club_admin'
FROM club_members cm
INNER JOIN clubs cl ON cl.id = cm.club_id AND cl.primary_admin_profile_id = cm.profile_id
WHERE NOT EXISTS (
    SELECT 1 FROM club_member_roles r
    WHERE r.club_member_id = cm.id AND r.role_code = 'club_admin'
);

-- Globale Admins: in jedem bestehenden Verein als club_admin spiegeln (volle Plattform-Sicht)
INSERT INTO club_members (profile_id, club_id, status)
SELECT p.id, c.id, 'active'
FROM profiles p
CROSS JOIN clubs c
WHERE p.role IN ('admin', 'superadmin')
ON CONFLICT (profile_id, club_id) DO NOTHING;

INSERT INTO club_member_roles (club_member_id, role_code)
SELECT cm.id, 'club_admin'
FROM club_members cm
INNER JOIN profiles p ON p.id = cm.profile_id AND p.role IN ('admin', 'superadmin')
WHERE NOT EXISTS (
    SELECT 1 FROM club_member_roles r
    WHERE r.club_member_id = cm.id AND r.role_code = 'club_admin'
);

-- Default aktiver Verein: einziger Verein des Nutzers
UPDATE profiles p
SET active_club_id = sub.only_club
FROM (
    SELECT profile_id, MIN(club_id) AS only_club
    FROM club_members
    WHERE status = 'active'
    GROUP BY profile_id
    HAVING COUNT(DISTINCT club_id) = 1
) sub
WHERE p.id = sub.profile_id AND (p.active_club_id IS NULL);
