-- Music Aggregator Database Schema
-- Based on docs/erd.puml

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- ══════════════════════════════════════════════════════════════
-- CONFIGURATION
-- ══════════════════════════════════════════════════════════════

CREATE TABLE quality_profiles (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name TEXT NOT NULL UNIQUE,
    cutoff INT NOT NULL DEFAULT 0,
    items JSONB NOT NULL DEFAULT '[]',
    upgrade_allowed BOOLEAN NOT NULL DEFAULT true
);

CREATE TABLE metadata_profiles (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name TEXT NOT NULL UNIQUE,
    primary_album_types JSONB NOT NULL DEFAULT '["Album", "EP"]',
    secondary_album_types JSONB NOT NULL DEFAULT '[]',
    release_statuses JSONB NOT NULL DEFAULT '["Official"]'
);

CREATE TABLE root_folders (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name TEXT NOT NULL,
    path TEXT NOT NULL UNIQUE,
    default_quality_profile_id UUID REFERENCES quality_profiles(id),
    default_metadata_profile_id UUID REFERENCES metadata_profiles(id)
);

CREATE TABLE indexers (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name TEXT NOT NULL,
    implementation TEXT NOT NULL,
    settings JSONB NOT NULL DEFAULT '{}',
    enable_rss BOOLEAN NOT NULL DEFAULT true,
    enable_search BOOLEAN NOT NULL DEFAULT true,
    priority INT NOT NULL DEFAULT 25
);

CREATE TABLE download_clients (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name TEXT NOT NULL,
    implementation TEXT NOT NULL,
    settings JSONB NOT NULL DEFAULT '{}',
    protocol TEXT NOT NULL DEFAULT 'torrent',
    priority INT NOT NULL DEFAULT 1,
    enabled BOOLEAN NOT NULL DEFAULT true
);

-- ══════════════════════════════════════════════════════════════
-- CORE MUSIC ENTITIES
-- ══════════════════════════════════════════════════════════════

CREATE TABLE artist_metadata (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    foreign_artist_id TEXT UNIQUE,
    name TEXT NOT NULL,
    sort_name TEXT,
    disambiguation TEXT,
    artist_type TEXT,
    status TEXT,
    overview TEXT,
    images JSONB NOT NULL DEFAULT '[]',
    links JSONB NOT NULL DEFAULT '[]',
    genres JSONB NOT NULL DEFAULT '[]',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE artists (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    metadata_id UUID NOT NULL REFERENCES artist_metadata(id) ON DELETE CASCADE,
    quality_profile_id UUID REFERENCES quality_profiles(id),
    metadata_profile_id UUID REFERENCES metadata_profiles(id),
    root_folder_id UUID REFERENCES root_folders(id),
    path TEXT,
    monitored BOOLEAN NOT NULL DEFAULT true,
    monitor_new_items TEXT NOT NULL DEFAULT 'all',
    last_info_sync TIMESTAMPTZ,
    added_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE albums (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    artist_metadata_id UUID NOT NULL REFERENCES artist_metadata(id) ON DELETE CASCADE,
    foreign_album_id TEXT UNIQUE,
    title TEXT NOT NULL,
    clean_title TEXT,
    disambiguation TEXT,
    overview TEXT,
    album_type TEXT,
    release_date DATE,
    images JSONB NOT NULL DEFAULT '[]',
    genres JSONB NOT NULL DEFAULT '[]',
    monitored BOOLEAN NOT NULL DEFAULT true,
    added_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE album_releases (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    album_id UUID NOT NULL REFERENCES albums(id) ON DELETE CASCADE,
    foreign_release_id TEXT UNIQUE,
    title TEXT NOT NULL,
    status TEXT,
    duration_ms INT,
    release_date DATE,
    country TEXT[],
    label TEXT[],
    format TEXT,
    track_count INT,
    monitored BOOLEAN NOT NULL DEFAULT true
);

CREATE TABLE track_files (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    album_id UUID NOT NULL REFERENCES albums(id) ON DELETE CASCADE,
    path TEXT NOT NULL,
    relative_path TEXT NOT NULL,
    size BIGINT NOT NULL DEFAULT 0,
    file_hash TEXT,
    audio_hash TEXT,
    quality JSONB NOT NULL DEFAULT '{}',
    media_info JSONB NOT NULL DEFAULT '{}',
    scene_name TEXT,
    release_group TEXT,
    date_added TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE tracks (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    album_release_id UUID NOT NULL REFERENCES album_releases(id) ON DELETE CASCADE,
    artist_metadata_id UUID NOT NULL REFERENCES artist_metadata(id) ON DELETE CASCADE,
    track_file_id UUID REFERENCES track_files(id) ON DELETE SET NULL,
    foreign_track_id TEXT UNIQUE,
    title TEXT NOT NULL,
    track_number INT NOT NULL DEFAULT 1,
    disc_number INT NOT NULL DEFAULT 1,
    duration_ms INT,
    explicit BOOLEAN NOT NULL DEFAULT false
);

-- ══════════════════════════════════════════════════════════════
-- DOWNLOAD TRACKING
-- ══════════════════════════════════════════════════════════════

CREATE TABLE wanted_albums (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    album_id UUID NOT NULL UNIQUE REFERENCES albums(id) ON DELETE CASCADE,
    priority INT NOT NULL DEFAULT 0,
    search_count INT NOT NULL DEFAULT 0,
    last_searched_at TIMESTAMPTZ,
    added_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE download_queue (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    artist_id UUID REFERENCES artists(id) ON DELETE SET NULL,
    album_id UUID REFERENCES albums(id) ON DELETE SET NULL,
    download_id TEXT,
    title TEXT NOT NULL,
    size BIGINT NOT NULL DEFAULT 0,
    size_left BIGINT NOT NULL DEFAULT 0,
    status TEXT NOT NULL DEFAULT 'queued',
    progress REAL NOT NULL DEFAULT 0.0,
    error_message TEXT,
    protocol TEXT NOT NULL DEFAULT 'torrent',
    indexer TEXT,
    download_client TEXT,
    torrent_hash TEXT,
    output_path TEXT,
    added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    completed_at TIMESTAMPTZ
);

CREATE TABLE blocklist (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    artist_id UUID NOT NULL REFERENCES artists(id) ON DELETE CASCADE,
    album_id UUID REFERENCES albums(id) ON DELETE CASCADE,
    source_title TEXT NOT NULL,
    quality JSONB NOT NULL DEFAULT '{}',
    size BIGINT NOT NULL DEFAULT 0,
    protocol TEXT,
    indexer TEXT,
    message TEXT,
    torrent_hash TEXT,
    date TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ══════════════════════════════════════════════════════════════
-- INDEXES
-- ══════════════════════════════════════════════════════════════

CREATE INDEX idx_artist_metadata_name ON artist_metadata(name);
CREATE INDEX idx_artist_metadata_foreign_id ON artist_metadata(foreign_artist_id);
CREATE INDEX idx_albums_artist ON albums(artist_metadata_id);
CREATE INDEX idx_albums_foreign_id ON albums(foreign_album_id);
CREATE INDEX idx_albums_release_date ON albums(release_date);
CREATE INDEX idx_album_releases_album ON album_releases(album_id);
CREATE INDEX idx_tracks_release ON tracks(album_release_id);
CREATE INDEX idx_tracks_artist ON tracks(artist_metadata_id);
CREATE INDEX idx_track_files_album ON track_files(album_id);
CREATE INDEX idx_track_files_hash ON track_files(file_hash);
CREATE INDEX idx_track_files_audio_hash ON track_files(audio_hash);
CREATE INDEX idx_wanted_albums_priority ON wanted_albums(priority DESC);
CREATE INDEX idx_download_queue_status ON download_queue(status);
CREATE INDEX idx_download_queue_album ON download_queue(album_id);
CREATE INDEX idx_blocklist_artist ON blocklist(artist_id);
CREATE INDEX idx_blocklist_torrent ON blocklist(torrent_hash);

-- ══════════════════════════════════════════════════════════════
-- DEFAULT DATA
-- ══════════════════════════════════════════════════════════════

INSERT INTO quality_profiles (name, cutoff, items, upgrade_allowed) VALUES
('Any', 0, '[]', true),
('Lossless', 1, '[{"quality": "FLAC", "allowed": true}, {"quality": "ALAC", "allowed": true}]', true),
('Standard', 2, '[{"quality": "MP3-320", "allowed": true}, {"quality": "MP3-VBR-V0", "allowed": true}]', true);

INSERT INTO metadata_profiles (name, primary_album_types, secondary_album_types, release_statuses) VALUES
('Standard', '["Album", "EP"]', '[]', '["Official"]'),
('All', '["Album", "EP", "Single", "Broadcast", "Other"]', '["Compilation", "Soundtrack", "Spokenword", "Interview", "Audiobook", "Live", "Remix", "DJ-mix", "Mixtape/Street", "Demo"]', '["Official", "Promotional", "Bootleg"]');
