"""SQL schema for the per-workspace corpus database."""

from __future__ import annotations

SCHEMA_VERSION = "2"

PRAGMA = """\
PRAGMA journal_mode = WAL;
PRAGMA foreign_keys = ON;
PRAGMA busy_timeout = 5000;
"""

CREATE_TABLES = """\
CREATE TABLE IF NOT EXISTS files (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    path TEXT NOT NULL UNIQUE,
    name TEXT NOT NULL,
    stem TEXT NOT NULL,
    author TEXT,
    date TEXT,
    file_mtime REAL NOT NULL,
    parsed_at TEXT NOT NULL DEFAULT (datetime('now')),
    segment_count INTEGER NOT NULL DEFAULT 0
);

CREATE TABLE IF NOT EXISTS media_refs (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
    media_url TEXT,
    mime_type TEXT,
    relative_url TEXT
);

CREATE TABLE IF NOT EXISTS tiers (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
    tier_id TEXT NOT NULL,
    linguistic_type TEXT,
    participant TEXT DEFAULT '',
    annotator TEXT DEFAULT '',
    parent_ref TEXT,
    UNIQUE(file_id, tier_id)
);

CREATE TABLE IF NOT EXISTS segments (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
    tier_rowid INTEGER NOT NULL REFERENCES tiers(id) ON DELETE CASCADE,
    annotation_id TEXT NOT NULL,
    start_ms INTEGER NOT NULL,
    end_ms INTEGER NOT NULL,
    duration_ms INTEGER GENERATED ALWAYS AS (end_ms - start_ms) STORED,
    label TEXT,
    label_lower TEXT GENERATED ALWAYS AS (lower(label)) STORED,
    confidence REAL,
    source TEXT NOT NULL DEFAULT 'file',
    UNIQUE(file_id, annotation_id)
);

CREATE INDEX IF NOT EXISTS idx_seg_label ON segments(label_lower);
CREATE INDEX IF NOT EXISTS idx_seg_file ON segments(file_id);
CREATE INDEX IF NOT EXISTS idx_seg_tier ON segments(tier_rowid);
CREATE INDEX IF NOT EXISTS idx_seg_duration ON segments(duration_ms);
CREATE INDEX IF NOT EXISTS idx_seg_file_time ON segments(file_id, start_ms, end_ms);
CREATE INDEX IF NOT EXISTS idx_tiers_participant ON tiers(participant);
CREATE INDEX IF NOT EXISTS idx_tiers_tier_id ON tiers(tier_id);
CREATE INDEX IF NOT EXISTS idx_seg_tier_file ON segments(tier_rowid, file_id);
CREATE INDEX IF NOT EXISTS idx_seg_label_file ON segments(label_lower, file_id);
CREATE INDEX IF NOT EXISTS idx_seg_file_tier_start ON segments(file_id, tier_rowid, start_ms);

CREATE VIRTUAL TABLE IF NOT EXISTS segments_fts
    USING fts5(label, content=segments, content_rowid=id);

CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT);

CREATE TABLE IF NOT EXISTS file_metadata (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
    key TEXT NOT NULL,
    value TEXT NOT NULL,
    source TEXT NOT NULL DEFAULT 'manual',
    UNIQUE(file_id, key)
);
CREATE INDEX IF NOT EXISTS idx_fmeta_key ON file_metadata(key);
CREATE INDEX IF NOT EXISTS idx_fmeta_kv ON file_metadata(key, value);

CREATE TABLE IF NOT EXISTS tier_roles (
    tier_id_pattern TEXT PRIMARY KEY,
    role TEXT NOT NULL DEFAULT 'gloss'
);
"""

MIGRATE_V1_TO_V2 = """\
CREATE TABLE IF NOT EXISTS file_metadata (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
    key TEXT NOT NULL,
    value TEXT NOT NULL,
    source TEXT NOT NULL DEFAULT 'manual',
    UNIQUE(file_id, key)
);
CREATE INDEX IF NOT EXISTS idx_fmeta_key ON file_metadata(key);
CREATE INDEX IF NOT EXISTS idx_fmeta_kv ON file_metadata(key, value);

CREATE TABLE IF NOT EXISTS tier_roles (
    tier_id_pattern TEXT PRIMARY KEY,
    role TEXT NOT NULL DEFAULT 'gloss'
);
"""

FTS_TRIGGERS = """\
CREATE TRIGGER IF NOT EXISTS segments_ai AFTER INSERT ON segments BEGIN
    INSERT INTO segments_fts(rowid, label) VALUES (new.id, new.label);
END;

CREATE TRIGGER IF NOT EXISTS segments_ad AFTER DELETE ON segments BEGIN
    INSERT INTO segments_fts(segments_fts, rowid, label)
        VALUES ('delete', old.id, old.label);
END;

CREATE TRIGGER IF NOT EXISTS segments_au AFTER UPDATE ON segments BEGIN
    INSERT INTO segments_fts(segments_fts, rowid, label)
        VALUES ('delete', old.id, old.label);
    INSERT INTO segments_fts(rowid, label) VALUES (new.id, new.label);
END;
"""
