from __future__ import annotations

from sqlalchemy import text

from app.core.shared.database import get_engine


class StoryContextSchemaRepository:
    def ensure_tables(self) -> None:
        with get_engine().connect() as conn:
            for statement in self._statements():
                conn.execute(text(statement))
            conn.commit()

    def _statements(self) -> tuple[str, ...]:
        return (
            """
            CREATE TABLE IF NOT EXISTS story_records (
                story_id VARCHAR(128) PRIMARY KEY,
                project_id VARCHAR(512) NOT NULL,
                title TEXT NOT NULL,
                status VARCHAR(64) NOT NULL DEFAULT 'draft',
                owner VARCHAR(256) NULL,
                metadata_json JSONB NOT NULL DEFAULT '{}'::jsonb,
                baseline_commit_sha VARCHAR(128) NULL,
                snapshot_id VARCHAR(128) NULL,
                created_by VARCHAR(256) NULL,
                updated_by VARCHAR(256) NULL,
                created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS story_artifacts (
                id BIGSERIAL PRIMARY KEY,
                story_id VARCHAR(128) NOT NULL,
                artifact_type VARCHAR(64) NOT NULL,
                revision INTEGER NOT NULL,
                content TEXT NOT NULL,
                content_hash VARCHAR(128) NULL,
                rag_session_id VARCHAR(64) NULL,
                created_by VARCHAR(256) NULL,
                created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
                artifact_role VARCHAR(64) NULL,
                doc_id TEXT NULL,
                doc_version TEXT NULL,
                path TEXT NULL,
                section TEXT NULL,
                chunk_id TEXT NULL,
                change_type VARCHAR(32) NULL,
                summary TEXT NULL,
                source_ref TEXT NULL,
                session_id VARCHAR(128) NULL,
                CONSTRAINT fk_story_artifacts_story
                    FOREIGN KEY (story_id)
                    REFERENCES story_records(story_id)
                    ON DELETE CASCADE,
                CONSTRAINT uq_story_artifact_revision
                    UNIQUE (story_id, artifact_type, revision)
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS story_links (
                id BIGSERIAL PRIMARY KEY,
                story_id VARCHAR(128) NOT NULL,
                link_type VARCHAR(64) NOT NULL,
                link_value TEXT NOT NULL,
                target_ref TEXT NULL,
                description TEXT NULL,
                metadata_json JSONB NOT NULL DEFAULT '{}'::jsonb,
                created_by VARCHAR(256) NULL,
                created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
                CONSTRAINT fk_story_links_story
                    FOREIGN KEY (story_id)
                    REFERENCES story_records(story_id)
                    ON DELETE CASCADE
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS session_artifacts (
                id BIGSERIAL PRIMARY KEY,
                session_id VARCHAR(128) NOT NULL,
                project_id VARCHAR(512) NOT NULL,
                artifact_role VARCHAR(64) NOT NULL,
                source_ref TEXT NULL,
                doc_id TEXT NULL,
                doc_version TEXT NULL,
                path TEXT NULL,
                section TEXT NULL,
                chunk_id TEXT NULL,
                change_type VARCHAR(32) NULL,
                summary TEXT NULL,
                created_by VARCHAR(256) NULL,
                created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
                bound_story_id VARCHAR(128) NULL,
                bound_at TIMESTAMPTZ NULL
            )
            """,
            "ALTER TABLE story_records ADD COLUMN IF NOT EXISTS owner VARCHAR(256) NULL",
            "ALTER TABLE story_records ADD COLUMN IF NOT EXISTS metadata_json JSONB NOT NULL DEFAULT '{}'::jsonb",
            "ALTER TABLE story_records ADD COLUMN IF NOT EXISTS baseline_commit_sha VARCHAR(128) NULL",
            "ALTER TABLE story_records ADD COLUMN IF NOT EXISTS snapshot_id VARCHAR(128) NULL",
            "ALTER TABLE story_records ADD COLUMN IF NOT EXISTS created_by VARCHAR(256) NULL",
            "ALTER TABLE story_records ADD COLUMN IF NOT EXISTS updated_by VARCHAR(256) NULL",
            "ALTER TABLE story_artifacts ADD COLUMN IF NOT EXISTS artifact_role VARCHAR(64) NULL",
            "ALTER TABLE story_artifacts ADD COLUMN IF NOT EXISTS doc_id TEXT NULL",
            "ALTER TABLE story_artifacts ADD COLUMN IF NOT EXISTS doc_version TEXT NULL",
            "ALTER TABLE story_artifacts ADD COLUMN IF NOT EXISTS path TEXT NULL",
            "ALTER TABLE story_artifacts ADD COLUMN IF NOT EXISTS section TEXT NULL",
            "ALTER TABLE story_artifacts ADD COLUMN IF NOT EXISTS chunk_id TEXT NULL",
            "ALTER TABLE story_artifacts ADD COLUMN IF NOT EXISTS change_type VARCHAR(32) NULL",
            "ALTER TABLE story_artifacts ADD COLUMN IF NOT EXISTS summary TEXT NULL",
            "ALTER TABLE story_artifacts ADD COLUMN IF NOT EXISTS source_ref TEXT NULL",
            "ALTER TABLE story_artifacts ADD COLUMN IF NOT EXISTS session_id VARCHAR(128) NULL",
            "ALTER TABLE story_links ADD COLUMN IF NOT EXISTS target_ref TEXT NULL",
            "ALTER TABLE story_links ADD COLUMN IF NOT EXISTS description TEXT NULL",
            "ALTER TABLE story_links ADD COLUMN IF NOT EXISTS metadata_json JSONB NOT NULL DEFAULT '{}'::jsonb",
            "ALTER TABLE story_links ADD COLUMN IF NOT EXISTS created_by VARCHAR(256) NULL",
            "ALTER TABLE session_artifacts ADD COLUMN IF NOT EXISTS bound_story_id VARCHAR(128) NULL",
            "ALTER TABLE session_artifacts ADD COLUMN IF NOT EXISTS bound_at TIMESTAMPTZ NULL",
            "CREATE INDEX IF NOT EXISTS idx_story_records_project ON story_records(project_id, updated_at DESC)",
            "CREATE INDEX IF NOT EXISTS idx_story_artifacts_story_type ON story_artifacts(story_id, artifact_type, revision DESC)",
            "CREATE INDEX IF NOT EXISTS idx_story_links_story ON story_links(story_id, link_type)",
            "CREATE INDEX IF NOT EXISTS idx_session_artifacts_session ON session_artifacts(session_id, created_at DESC)",
            "CREATE INDEX IF NOT EXISTS idx_session_artifacts_project ON session_artifacts(project_id, created_at DESC)",
        )
