-- Migration 045: Zentrale media_assets, exercise_media.media_asset_id, platform_media_storage (Superadmin-Pfad).
-- Siehe .claude/docs/technical/MEDIA_ASSETS_AND_ARCHIVE_SPEC.md

CREATE EXTENSION IF NOT EXISTS pgcrypto;

CREATE TABLE platform_media_storage (
  id SMALLINT PRIMARY KEY DEFAULT 1,
  CONSTRAINT platform_media_storage_singleton CHECK (id = 1),
  storage_backend VARCHAR(32) NOT NULL DEFAULT 'local',
  local_relative_root VARCHAR(512) NOT NULL DEFAULT '',
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_by_profile_id INT REFERENCES profiles(id) ON DELETE SET NULL
);

INSERT INTO platform_media_storage (id, storage_backend, local_relative_root)
VALUES (1, 'local', '')
ON CONFLICT (id) DO NOTHING;

CREATE TABLE media_assets (
  id SERIAL PRIMARY KEY,
  mime_type VARCHAR(100),
  byte_size INT,
  sha256 CHAR(64) NOT NULL,
  original_filename VARCHAR(300),
  visibility VARCHAR(32) NOT NULL DEFAULT 'private',
  club_id INT REFERENCES clubs(id) ON DELETE SET NULL,
  uploaded_by_profile_id INT REFERENCES profiles(id) ON DELETE SET NULL,
  copyright_notice TEXT,
  storage_backend VARCHAR(32) NOT NULL DEFAULT 'local',
  storage_key TEXT NOT NULL,
  lifecycle_state VARCHAR(32) NOT NULL DEFAULT 'active',
  trash_soft_at TIMESTAMP WITH TIME ZONE,
  trash_hidden_at TIMESTAMP WITH TIME ZONE,
  purge_after_at TIMESTAMP WITH TIME ZONE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX idx_media_assets_club ON media_assets(club_id);
CREATE INDEX idx_media_assets_sha256 ON media_assets(sha256);
CREATE INDEX idx_media_assets_lifecycle ON media_assets(lifecycle_state);
CREATE UNIQUE INDEX ux_media_assets_storage_key ON media_assets(storage_key);

ALTER TABLE exercise_media
  ADD COLUMN IF NOT EXISTS media_asset_id INT REFERENCES media_assets(id) ON DELETE SET NULL;

CREATE INDEX IF NOT EXISTS idx_exercise_media_asset ON exercise_media(media_asset_id);

-- Bestand: je distinct storage_key ein Asset; sha256 aus DB-Pfad (Migrations-Platzhalter, nicht Content-Hash)
INSERT INTO media_assets (
  mime_type,
  byte_size,
  sha256,
  original_filename,
  visibility,
  club_id,
  uploaded_by_profile_id,
  storage_backend,
  storage_key,
  copyright_notice,
  lifecycle_state,
  created_at,
  updated_at
)
SELECT
  s.mime_type,
  s.byte_size,
  s.sha256,
  s.original_filename,
  s.visibility,
  s.club_id,
  s.uploaded_by_profile_id,
  'local',
  s.storage_key,
  NULL,
  'active',
  s.created_at,
  NOW()
FROM (
  SELECT DISTINCT ON (storage_key)
    em.mime_type,
    em.file_size AS byte_size,
    encode(digest(trim(em.file_path), 'sha256'), 'hex') AS sha256,
    em.original_filename,
    lower(trim(e.visibility)) AS visibility,
    e.club_id,
    e.created_by AS uploaded_by_profile_id,
    regexp_replace(trim(em.file_path), '^/+media/+', '') AS storage_key,
    em.created_at
  FROM exercise_media em
  JOIN exercises e ON e.id = em.exercise_id
  WHERE em.file_path IS NOT NULL
    AND trim(em.file_path) <> ''
    AND em.embed_url IS NULL
  ORDER BY regexp_replace(trim(em.file_path), '^/+media/+', ''), em.id
) s
WHERE NOT EXISTS (SELECT 1 FROM media_assets ma WHERE ma.storage_key = s.storage_key);

UPDATE exercise_media em
SET media_asset_id = ma.id
FROM media_assets ma
WHERE em.media_asset_id IS NULL
  AND em.file_path IS NOT NULL
  AND trim(em.file_path) <> ''
  AND em.embed_url IS NULL
  AND ma.storage_key = regexp_replace(trim(em.file_path), '^/+media/+', '');
