"""bootstrap schema and recall ai fields

Revision ID: 20260514_0001
Revises:
Create Date: 2026-05-14 00:00:00
"""
from __future__ import annotations

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "20260514_0001"
down_revision = "20260512_0001"
branch_labels = None
depends_on = None


def _table_exists(inspector, table_name: str) -> bool:
    return table_name in inspector.get_table_names()


def _column_exists(inspector, table_name: str, column_name: str) -> bool:
    if not _table_exists(inspector, table_name):
        return False
    return column_name in {column["name"] for column in inspector.get_columns(table_name)}


def _index_exists(inspector, table_name: str, index_name: str) -> bool:
    if not _table_exists(inspector, table_name):
        return False
    return index_name in {index["name"] for index in inspector.get_indexes(table_name)}


def upgrade() -> None:
    bind = op.get_bind()
    inspector = sa.inspect(bind)

    if not _table_exists(inspector, "users"):
        op.create_table(
            "users",
            sa.Column("id", sa.Integer(), primary_key=True, nullable=False),
            sa.Column("email", sa.String(), unique=True),
            sa.Column("name", sa.String()),
            sa.Column("access_token", sa.String()),
        )
        op.create_index("ix_users_id", "users", ["id"], unique=False)

    inspector = sa.inspect(bind)
    if not _table_exists(inspector, "meetings"):
        op.create_table(
            "meetings",
            sa.Column("id", sa.Integer(), primary_key=True, nullable=False),
            sa.Column("title", sa.String(), nullable=True),
            sa.Column("meet_link", sa.String()),
            sa.Column("user_id", sa.Integer(), sa.ForeignKey("users.id")),
            sa.Column("status", sa.String(), server_default="pending"),
            sa.Column("created_at", sa.Date(), server_default=sa.text("CURRENT_DATE")),
        )
        op.create_index("ix_meetings_id", "meetings", ["id"], unique=False)

    inspector = sa.inspect(bind)
    if not _table_exists(inspector, "recordings"):
        op.create_table(
            "recordings",
            sa.Column("id", sa.Integer(), primary_key=True, nullable=False),
            sa.Column("meeting_id", sa.Integer(), sa.ForeignKey("meetings.id"), unique=True),
            sa.Column("file_path", sa.String(), nullable=True),
            sa.Column("status", sa.String(), server_default="recording"),
            sa.Column("started_at", sa.DateTime(timezone=True), server_default=sa.text("NOW()")),
            sa.Column("stopped_at", sa.DateTime(timezone=True), nullable=True),
        )
        op.create_index("ix_recordings_id", "recordings", ["id"], unique=False)

    inspector = sa.inspect(bind)
    if not _table_exists(inspector, "transcripts"):
        op.create_table(
            "transcripts",
            sa.Column("id", sa.Integer(), primary_key=True, nullable=False),
            sa.Column("meeting_id", sa.Integer(), sa.ForeignKey("meetings.id"), unique=True),
            sa.Column("status", sa.String(), server_default="pending"),
            sa.Column("language", sa.String(), nullable=True),
            sa.Column("duration_seconds", sa.Integer(), nullable=True),
            sa.Column("participants", sa.String(), nullable=True),
            sa.Column("speaker_map", sa.String(), nullable=True),
            sa.Column("transcript_json", sa.String(), nullable=True),
            sa.Column("full_text", sa.String(), nullable=True),
            sa.Column("error_message", sa.String(), nullable=True),
            sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("NOW()")),
            sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True),
        )
        op.create_index("ix_transcripts_id", "transcripts", ["id"], unique=False)

    inspector = sa.inspect(bind)

    meeting_columns = [
        ("recall_bot_id", sa.String(), True),
        ("recall_join_at", sa.DateTime(timezone=True), True),
        ("provider", sa.String(), False),
        ("bot_status", sa.String(), True),
        ("bot_payload", sa.Text(), True),
    ]
    for name, column_type, nullable in meeting_columns:
        if not _column_exists(inspector, "meetings", name):
            if name == "provider":
                op.add_column("meetings", sa.Column(name, column_type, nullable=nullable, server_default="recall_ai"))
            else:
                op.add_column("meetings", sa.Column(name, column_type, nullable=nullable))
            inspector = sa.inspect(bind)
    if not _index_exists(inspector, "meetings", "uq_meetings_recall_bot_id"):
        op.create_index("uq_meetings_recall_bot_id", "meetings", ["recall_bot_id"], unique=True)

    recording_columns = [
        ("recall_recording_id", sa.String(), True),
        ("video_download_url", sa.Text(), True),
        ("transcript_download_url", sa.Text(), True),
        ("transcript_provider_data_download_url", sa.Text(), True),
        ("participant_events_download_url", sa.Text(), True),
        ("speaker_timeline_download_url", sa.Text(), True),
        ("participants_download_url", sa.Text(), True),
        ("recording_payload", sa.Text(), True),
    ]
    for name, column_type, nullable in recording_columns:
        if not _column_exists(inspector, "recordings", name):
            op.add_column("recordings", sa.Column(name, column_type, nullable=nullable))
            inspector = sa.inspect(bind)
    if not _index_exists(inspector, "recordings", "uq_recordings_recall_recording_id"):
        op.create_index("uq_recordings_recall_recording_id", "recordings", ["recall_recording_id"], unique=True)

    transcript_columns = [
        ("recall_transcript_id", sa.String(), True),
        ("download_url", sa.Text(), True),
        ("provider_data_download_url", sa.Text(), True),
        ("transcript_payload", sa.Text(), True),
    ]
    for name, column_type, nullable in transcript_columns:
        if not _column_exists(inspector, "transcripts", name):
            op.add_column("transcripts", sa.Column(name, column_type, nullable=nullable))
            inspector = sa.inspect(bind)
    if not _index_exists(inspector, "transcripts", "uq_transcripts_recall_transcript_id"):
        op.create_index("uq_transcripts_recall_transcript_id", "transcripts", ["recall_transcript_id"], unique=True)


def downgrade() -> None:
    bind = op.get_bind()
    inspector = sa.inspect(bind)

    if _index_exists(inspector, "transcripts", "uq_transcripts_recall_transcript_id"):
        op.drop_index("uq_transcripts_recall_transcript_id", table_name="transcripts")
    for column_name in ["transcript_payload", "provider_data_download_url", "download_url", "recall_transcript_id"]:
        if _column_exists(inspector, "transcripts", column_name):
            op.drop_column("transcripts", column_name)
            inspector = sa.inspect(bind)

    if _index_exists(inspector, "recordings", "uq_recordings_recall_recording_id"):
        op.drop_index("uq_recordings_recall_recording_id", table_name="recordings")
    for column_name in [
        "recording_payload",
        "participants_download_url",
        "speaker_timeline_download_url",
        "participant_events_download_url",
        "transcript_provider_data_download_url",
        "transcript_download_url",
        "video_download_url",
        "recall_recording_id",
    ]:
        if _column_exists(inspector, "recordings", column_name):
            op.drop_column("recordings", column_name)
            inspector = sa.inspect(bind)

    if _index_exists(inspector, "meetings", "uq_meetings_recall_bot_id"):
        op.drop_index("uq_meetings_recall_bot_id", table_name="meetings")
    for column_name in ["bot_payload", "bot_status", "provider", "recall_join_at", "recall_bot_id"]:
        if _column_exists(inspector, "meetings", column_name):
            op.drop_column("meetings", column_name)
            inspector = sa.inspect(bind)

    # This bootstrap migration intentionally keeps core tables in place on downgrade
    # because they may predate Alembic management in existing environments.
