"""PostgreSQL migrations — all domain tables (consolidated first deployment).

Creates 14 PostgreSQL tables with the complete schema from all accumulated
changes (account FK columns, translated_text, backfill_threshold, column renames).
Suitable for first-time deployment — no incremental migration history needed.
"""

from __future__ import annotations

from repo_core.migrations.builder import MigrationBuilder
from repo_core.migrations.runner import Migration

VERSION = "0001"


def get_postgres_migrations() -> list[Migration]:
    """Return ordered PostgreSQL migrations.  Migrations are applied in list order."""
    return [

        # ------------------------------------------------------------------ #
        # Telegram                                                             #
        # ------------------------------------------------------------------ #
        Migration(
            version="tg_channel_0001",
            description="Create telegram_channels table",
            up=(
                MigrationBuilder("telegram_channels")
                .uuid("id", primary_key=True, nullable=False)
                .bigint("channel_id", nullable=False)
                .text("title", nullable=False)
                .text("username", nullable=True)
                .text("kind", nullable=True, default="'channel'")
                .bigint("member_count", nullable=True)
                .text("profile_photo_base64", nullable=True)
                .text("description", nullable=True)
                .bigint("linked_chat_id", nullable=True)
                .bigint("admins_count", nullable=True)
                .bigint("online_count", nullable=True)
                .bigint("slowmode_seconds", nullable=True)
                .boolean("can_view_participants", nullable=True)
                .boolean("verified", nullable=True)
                .boolean("restricted", nullable=True)
                .boolean("scam", nullable=True)
                .boolean("fake", nullable=True)
                .boolean("broadcast", nullable=True)
                .boolean("megagroup", nullable=True)
                .float_("avg_views_last_10", nullable=True)
                .float_("avg_reactions_last_10", nullable=True)
                .float_("avg_comments_last_10", nullable=True)
                .bigint("total_posts_analyzed", nullable=True, default=0)
                .jsonb("saved_preview", nullable=True)
                .uuid("account_id", nullable=True)
                .timestamp("assigned_at", nullable=True)
                .text("assigned_by", nullable=True)
                .timestamp("saved_preview_at", nullable=True)
                .integer("backfill_threshold", nullable=False, default=10)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .index(["channel_id"], unique=True)
                .index(["kind"])
                .index(["username"])
                .index(["account_id"])
                .create_table()
            ),
            down=MigrationBuilder("telegram_channels").drop_table(),
        ),


        Migration(
            version="tg_account_0001",
            description="Create telegram_accounts table",
            up=(
                MigrationBuilder("telegram_accounts")
                .uuid("id", primary_key=True, nullable=False)
                .text("phone_number", nullable=False)
                .text("external_id", nullable=True)
                .text("username", nullable=True)
                .text("display_name", nullable=True)
                .text("session_encrypted", nullable=False)
                .jsonb("account_metadata", nullable=True, default="'{}'::jsonb")
                .boolean("is_active", nullable=True, default=True)
                .boolean("is_platform_manager", nullable=True, default=False)
                .text("status", nullable=True, default="'active'")
                .timestamp("flood_wait_until", nullable=True)
                .timestamp("last_active_at", nullable=True)
                .timestamp("leased_until", nullable=True)
                .text("leased_by", nullable=True)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .index(["phone_number"])
                .index(["status"])
                .create_table()
            ),
            down=MigrationBuilder("telegram_accounts").drop_table(),
        ),

        Migration(
            version="tg_channel_account_0001",
            description="Create channel_accounts junction table",
            up=(
                MigrationBuilder("channel_accounts")
                .uuid("id", primary_key=True, nullable=False)
                .uuid("channel_id", nullable=False)
                .uuid("account_id", nullable=False)
                .timestamp("assigned_at", nullable=False)
                .text("assigned_by", nullable=True)
                .boolean("is_active", nullable=True, default=True)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .index(["channel_id"])
                .index(["account_id"])
                .index(["channel_id", "account_id"], unique=True)
                .index(["is_active"])
                .foreign_key("channel_id", "telegram_channels")
                .foreign_key("account_id", "telegram_accounts")
                .create_table()
            ),
            down=MigrationBuilder("channel_accounts").drop_table(),
        ),

        Migration(
            version="tg_message_0001",
            description="Create telegram_messages table (v3: TIMESTAMPTZ columns)",
            up=(
                MigrationBuilder("telegram_messages")
                .bigint("peer_id", nullable=False)
                .bigint("message_id", nullable=False)
                .timestamp("message_sent_at", nullable=False)
                .text("message", nullable=True, default="''")
                .boolean("out", nullable=True, default=False)
                .boolean("mentioned", nullable=True, default=False)
                .boolean("media_unread", nullable=True, default=False)
                .boolean("silent", nullable=True, default=False)
                .boolean("post", nullable=True, default=False)
                .boolean("from_scheduled", nullable=True, default=False)
                .boolean("legacy", nullable=True, default=False)
                .boolean("edit_hide", nullable=True, default=False)
                .boolean("pinned", nullable=True, default=False)
                .boolean("noforwards", nullable=True, default=False)
                .boolean("invert_media", nullable=True, default=False)
                .boolean("offline", nullable=True, default=False)
                .boolean("paid_suggested_post_stars", nullable=True, default=False)
                .boolean("paid_suggested_post_ton", nullable=True, default=False)
                .jsonb("from_id", nullable=True)
                .bigint("from_boosts_applied", nullable=True)
                .jsonb("saved_peer_id", nullable=True)
                .jsonb("fwd_from", nullable=True)
                .bigint("via_bot_id", nullable=True)
                .bigint("via_business_bot_id", nullable=True)
                .jsonb("reply_to", nullable=True)
                .jsonb("media", nullable=True)
                .jsonb("reply_markup", nullable=True)
                .jsonb("details", nullable=True)
                .bigint("views", nullable=True)
                .bigint("forwards", nullable=True)
                .jsonb("replies", nullable=True)
                .timestamp("edit_date", nullable=True)
                .text("post_author", nullable=True)
                .bigint("grouped_id", nullable=True)
                .jsonb("reactions", nullable=True)
                .jsonb("restriction_reason", nullable=True)
                .bigint("ttl_period", nullable=True)
                .bigint("quick_reply_shortcut_id", nullable=True)
                .jsonb("effect", nullable=True)
                .jsonb("factcheck", nullable=True)
                .timestamp("report_delivery_until_date", nullable=True)
                .bigint("paid_message_stars", nullable=True)
                .jsonb("suggested_post", nullable=True)
                .timestamp("crawled_at", nullable=True)
                .timestamp("created_at", nullable=True)
                .timestamp("updated_at", nullable=True)
                .index(["peer_id", "message_id"], unique=True)
                .index(["message_sent_at"])
                .foreign_key("peer_id", "telegram_channels", ref_column="channel_id")
                .create_table()
            ),
            down=MigrationBuilder("telegram_messages").drop_table(),
        ),

        Migration(
            version="telegram_parsed_message_0001",
            description="Create telegram_parsed_messages table (v3: TIMESTAMPTZ columns)",
            up=(
                MigrationBuilder("telegram_parsed_messages")
                .uuid("id", primary_key=True, nullable=True)
                .bigint("peer_id", nullable=False)
                .bigint("message_id", nullable=False)
                .bigint("from_id", nullable=True)
                .timestamp("message_sent_at", nullable=True)
                .text("message_text", nullable=True)
                .text("message_lang", nullable=True)
                .timestamp("edit_date", nullable=True)
                .text("translated_text", nullable=True)
                .jsonb("details", nullable=True)
                .jsonb("media", nullable=True)
                .jsonb("reactions", nullable=True)
                .jsonb("replies", nullable=True)
                .jsonb("reply_to", nullable=True)
                .jsonb("fwd_from", nullable=True)
                .bigint("views", nullable=True, default=0)
                .bigint("forwards", nullable=True)
                .boolean("is_post", nullable=True, default=False)
                .boolean("is_pinned", nullable=True, default=False)
                .timestamp("crawled_at", nullable=True)
                .timestamp("created_at", nullable=True)
                .timestamp("updated_at", nullable=True)
                .index(["peer_id", "message_id"])
                .index(["message_sent_at"])
                .foreign_key("peer_id", "telegram_channels", ref_column="channel_id")
                .create_table()
            ),
            down=MigrationBuilder("telegram_parsed_messages").drop_table(),
        ),
        
        # ------------------------------------------------------------------ #
        # Instagram                                                            #
        # ------------------------------------------------------------------ #

        Migration(
            version="ig_account_0001",
            description="Create instagram_accounts table",
            up=(
                MigrationBuilder("instagram_accounts")
                .uuid("id", primary_key=True, nullable=False)
                .text("phone_number", nullable=False)
                .text("external_id", nullable=True)
                .text("username", nullable=True)
                .text("display_name", nullable=True)
                .text("session_encrypted", nullable=False)
                .jsonb("account_metadata", nullable=True, default="'{}'::jsonb")
                .boolean("is_active", nullable=True, default=True)
                .text("status", nullable=True, default="'active'")
                .timestamp("flood_wait_until", nullable=True)
                .timestamp("last_active_at", nullable=True)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .index(["phone_number"])
                .index(["account_metadata"], using="gin")
                .index(["status"])
                .create_table()
            ),
            down=MigrationBuilder("instagram_accounts").drop_table(),
        ),

        # ------------------------------------------------------------------ #
        # X (Twitter)                                                          #
        # ------------------------------------------------------------------ #

        Migration(
            version="x_account_0001",
            description="Create x_accounts table",
            up=(
                MigrationBuilder("x_accounts")
                .uuid("id", primary_key=True, nullable=False)
                .text("username", nullable=False)
                .text("password", nullable=False)
                .text("email", nullable=True)
                .text("mobile", nullable=True)
                .text("account_id", nullable=True)
                .text("display_name", nullable=True)
                .jsonb("viewport", nullable=True, default=r"""'{"width": 1920, "height": 1080}'::jsonb""")
                .text("timezone", nullable=True, default="'UTC'")
                .text("locale", nullable=True, default="'en-US'")
                .jsonb("geolocation", nullable=True)
                .text("proxy_region", nullable=True)
                .jsonb("account_metadata", nullable=True, default="'{}'::jsonb")
                .text("status", nullable=True, default="'active'")
                .timestamp("last_active_at", nullable=True)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .index(["username"], unique=True)
                .index(["email"])
                .index(["mobile"])
                .index(["account_id"])
                .index(["status"])
                .index(["proxy_region"])
                .create_table()
            ),
            down=MigrationBuilder("x_accounts").drop_table(),
        ),

        # ------------------------------------------------------------------ #
        # Article                                                              #
        # ------------------------------------------------------------------ #

        Migration(
            version="article_0001",
            description="Create articles table",
            up=(
                MigrationBuilder("articles")
                .bigint("id", primary_key=True, nullable=False)
                .text("title", nullable=False)
                .text("body", nullable=True, default="''")
                .boolean("published", nullable=True, default=False)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .create_table()
            ),
            down=MigrationBuilder("articles").drop_table(),
        ),

        # ------------------------------------------------------------------ #
        # Entity                                                               #
        # ------------------------------------------------------------------ #

        Migration(
            version="entity_0001",
            description="Create entities table",
            up=(
                MigrationBuilder("entities")
                .text("id", primary_key=True, nullable=False)
                .text("name", nullable=False)
                .text("description", nullable=True, default="''")
                .boolean("active", nullable=True, default=True)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .create_table()
            ),
            down=MigrationBuilder("entities").drop_table(),
        ),

        # ------------------------------------------------------------------ #
        # Proxy                                                                #
        # ------------------------------------------------------------------ #

        Migration(
            version="proxy_0001",
            description="Create proxies table",
            up=(
                MigrationBuilder("proxies")
                .text("id", primary_key=True, nullable=False)
                .text("username", nullable=False)
                .text("password", nullable=False)
                .text("proxy_address", nullable=False)
                .bigint("port", nullable=False)
                .boolean("valid", nullable=True, default=True)
                .timestamp("last_verification", nullable=True)
                .text("country_code", nullable=True)
                .text("city_name", nullable=True)
                .text("asn_name", nullable=True)
                .bigint("asn_number", nullable=True)
                .boolean("high_country_confidence", nullable=True, default=True)
                .float_("average_delay", nullable=True)
                .float_("average_speed", nullable=True)
                .timestamp("last_time_tested", nullable=True)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .index(["proxy_address", "port"])
                .index(["country_code"])
                .index(["valid"])
                .create_table()
            ),
            down=MigrationBuilder("proxies").drop_table(),
        ),

        # ------------------------------------------------------------------ #
        # Authentication                                                       #
        # ------------------------------------------------------------------ #

        Migration(
            version="auth_0001",
            description="Create auth_roles table",
            up=(
                MigrationBuilder("auth_roles")
                .uuid("id", primary_key=True, nullable=False)
                .text("name", nullable=False)
                .text("description", nullable=True)
                .jsonb("scopes", nullable=True, default="'[]'::jsonb")
                .boolean("is_active", nullable=True, default=True)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .index(["name"], unique=True)
                .create_table()
            ),
            down=MigrationBuilder("auth_roles").drop_table(),
        ),

        Migration(
            version="auth_0002",
            description="Create auth_users table",
            up=(
                MigrationBuilder("auth_users")
                .uuid("id", primary_key=True, nullable=False)
                .text("username", nullable=False)
                .text("email", nullable=False)
                .text("password_hash", nullable=False)
                .text("display_name", nullable=True)
                .text("role", nullable=True, default="'user'")
                .boolean("is_active", nullable=True, default=True)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .timestamp("last_login_at", nullable=True)
                .index(["username"], unique=True)
                .index(["email"], unique=True)
                .index(["role"])
                .create_table()
            ),
            down=MigrationBuilder("auth_users").drop_table(),
        ),

        Migration(
            version="api_key_0001",
            description="Create api_keys table",
            up=(
                MigrationBuilder("api_keys")
                .uuid("id", primary_key=True, nullable=False)
                .text("key_hash", nullable=False)
                .text("name", nullable=False)
                .jsonb("scopes", nullable=True, default="'[]'::jsonb")
                .boolean("is_active", nullable=True, default=True)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .timestamp("last_used_at", nullable=True)
                .index(["name"])
                .index(["key_hash"], unique=True)
                .create_table()
            ),
            down=MigrationBuilder("api_keys").drop_table(),
        ),

        # ------------------------------------------------------------------ #
        # Proxy Leases                                                         #
        # ------------------------------------------------------------------ #

        Migration(
            version="proxy_lease_0001",
            description="Create proxy_leases table",
            up=(
                MigrationBuilder("proxy_leases")
                .uuid("id", primary_key=True, nullable=False)
                .text("proxy_id", nullable=False)
                .text("account_type", nullable=False)
                .uuid("account_id", nullable=False)
                .text("lease_mode", nullable=False)
                .bigint("lease_duration_seconds", nullable=True)
                .timestamp("assigned_at", nullable=True)
                .timestamp("expires_at", nullable=True)
                .timestamp("reclaimed_at", nullable=True)
                .boolean("is_active", nullable=True, default=True)
                .timestamp("created_at", nullable=True, default="now()")
                .timestamp("updated_at", nullable=True, default="now()")
                .index(["proxy_id"])
                .index(["account_type", "account_id"])
                .index(["lease_mode"])
                .index(["is_active"])
                .foreign_key("proxy_id", "proxies")
                .create_table()
            ),
            down=MigrationBuilder("proxy_leases").drop_table(),
        ),
    ]
