-- init.sql
-- Executed by PostgreSQL on first container start.
-- The full schema is copied here so it runs automatically via
-- docker-entrypoint-initdb.d without requiring a separate psql call.

-- Enable UUID generation
CREATE EXTENSION IF NOT EXISTS "pgcrypto";

-- ─── songs ────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS songs (
  mbid                        UUID          PRIMARY KEY,
  title                       TEXT          NOT NULL,
  artist                      TEXT          NOT NULL,
  duration_seconds            NUMERIC(8, 3),
  acousticbrainz_bpm          NUMERIC(6, 2),
  acousticbrainz_time_sig_num INTEGER,
  source                      TEXT          NOT NULL DEFAULT 'musicbrainz',
  created_at                  TIMESTAMPTZ   NOT NULL DEFAULT NOW(),
  updated_at                  TIMESTAMPTZ   NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS songs_title_artist_idx
  ON songs USING gin(to_tsvector('english', title || ' ' || artist));

-- ─── tempo_maps ───────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS tempo_maps (
  id             UUID          PRIMARY KEY DEFAULT gen_random_uuid(),
  song_mbid      UUID          NOT NULL REFERENCES songs(mbid) ON DELETE CASCADE,
  ctp_data       JSONB         NOT NULL,
  contributed_by TEXT          NOT NULL,
  verified       BOOLEAN       NOT NULL DEFAULT FALSE,
  upvotes        INTEGER       NOT NULL DEFAULT 0,
  created_at     TIMESTAMPTZ   NOT NULL DEFAULT NOW(),
  updated_at     TIMESTAMPTZ   NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS tempo_maps_song_mbid_idx ON tempo_maps (song_mbid);
CREATE INDEX IF NOT EXISTS tempo_maps_verified_upvotes_idx
  ON tempo_maps (verified DESC, upvotes DESC);

ALTER TABLE tempo_maps
  ADD CONSTRAINT ctp_data_has_version
  CHECK (ctp_data ? 'version');

-- ─── registry_sync_log ────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS registry_sync_log (
  id              UUID          PRIMARY KEY DEFAULT gen_random_uuid(),
  synced_at       TIMESTAMPTZ   NOT NULL DEFAULT NOW(),
  records_added   INTEGER       NOT NULL DEFAULT 0,
  records_updated INTEGER       NOT NULL DEFAULT 0,
  status          TEXT          NOT NULL,
  message         TEXT
);

-- ─── Triggers ─────────────────────────────────────────────────────────────────
CREATE OR REPLACE FUNCTION set_updated_at()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$;

DO $$
BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'songs_set_updated_at') THEN
    CREATE TRIGGER songs_set_updated_at
      BEFORE UPDATE ON songs FOR EACH ROW EXECUTE FUNCTION set_updated_at();
  END IF;
  IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'tempo_maps_set_updated_at') THEN
    CREATE TRIGGER tempo_maps_set_updated_at
      BEFORE UPDATE ON tempo_maps FOR EACH ROW EXECUTE FUNCTION set_updated_at();
  END IF;
END;
$$;
