"""Integration tests for PostgreSQL type operations."""

import pytest
from tests.integration.roundtrip import roundtrip_fidelity_test


@pytest.mark.integration
@pytest.mark.parametrize(
    "test_name,initial_setup,test_sql,expected_terms,expected_master_dependencies,expected_branch_dependencies",
    [
        (
            "create enum type",
            "CREATE SCHEMA test_schema;",
            """
            CREATE TYPE test_schema.mood AS ENUM ('sad', 'ok', 'happy');
            """,
            [
                'CREATE TYPE "test_schema"."mood"',
                "AS ENUM ('sad', 'ok', 'happy')",
            ],
            [],  # Master has no dependencies (empty state)
            [
                ("type:test_schema.mood", "test_schema"),
            ],
        ),
        (
            "create domain type with constraint",
            "CREATE SCHEMA test_schema;",
            """
            CREATE DOMAIN test_schema.positive_int AS INTEGER CHECK (VALUE > 0);
            """,
            [
                'CREATE DOMAIN "test_schema"."positive_int"',
                "AS integer",
                "CHECK ((VALUE > 0))",
            ],
            [],  # Master has no dependencies (empty state)
            [
                ("type:test_schema.positive_int", "test_schema"),
            ],
        ),
        (
            "create composite type",
            "CREATE SCHEMA test_schema;",
            """
            CREATE TYPE test_schema.address AS (
                street VARCHAR(90),
                city VARCHAR(90),
                state VARCHAR(2)
            );
            """,
            [
                'CREATE TYPE "test_schema"."address"',
                '"street" character varying(90)',
                '"city" character varying(90)',
                '"state" character varying(2)',
            ],
            [],  # Master has no dependencies (empty state)
            [
                ("type:test_schema.address", "test_schema"),
                (
                    "c:test_schema.address",
                    "type:test_schema.address",
                ),  # Composite type's underlying table
            ],
        ),
        (
            "create range type",
            "CREATE SCHEMA test_schema;",
            """
            CREATE TYPE test_schema.floatrange AS RANGE (subtype = float8);
            """,
            [
                'CREATE TYPE "test_schema"."floatrange"',
                "AS RANGE (subtype = double precision)",
            ],
            [],  # Master has no dependencies (empty state)
            [
                ("type:test_schema.floatrange", "test_schema"),
                # Note: multirange types and constructor functions are auto-generated by PostgreSQL
                # and should not be included in our catalog or dependency tracking
            ],
        ),
        (
            "drop enum type",
            """
            CREATE SCHEMA test_schema;
            CREATE TYPE test_schema.old_mood AS ENUM ('sad', 'happy');
            """,  # Both get schema + type
            "DROP TYPE test_schema.old_mood;",  # Branch drops the type
            [
                'DROP TYPE "test_schema"."old_mood";',
            ],
            [
                ("type:test_schema.old_mood", "test_schema"),
            ],
            [],  # Branch has no dependencies (type removed)
        ),
        (
            "replace enum type (modify values)",
            """
            CREATE SCHEMA test_schema;
            CREATE TYPE test_schema.status AS ENUM ('pending', 'approved');
            """,
            """
            DROP TYPE test_schema.status;
            CREATE TYPE test_schema.status AS ENUM ('pending', 'approved', 'rejected');
            """,
            [
                'DROP TYPE "test_schema"."status";',
                'CREATE TYPE "test_schema"."status"',
                "AS ENUM ('pending', 'approved', 'rejected')",
            ],
            [
                ("type:test_schema.status", "test_schema"),
            ],
            [
                ("type:test_schema.status", "test_schema"),
            ],
        ),
        (
            "replace domain type (modify constraint)",
            """
            CREATE SCHEMA test_schema;
            CREATE DOMAIN test_schema.valid_int AS INTEGER CHECK (VALUE > 0);
            """,
            """
            DROP DOMAIN test_schema.valid_int;
            CREATE DOMAIN test_schema.valid_int AS INTEGER CHECK (VALUE >= 0 AND VALUE <= 100);
            """,
            [
                'DROP TYPE "test_schema"."valid_int";',
                'CREATE DOMAIN "test_schema"."valid_int"',
                "AS integer",
                "CHECK (((VALUE >= 0) AND (VALUE <= 100)))",
            ],
            [
                ("type:test_schema.valid_int", "test_schema"),
            ],
            [
                ("type:test_schema.valid_int", "test_schema"),
            ],
        ),
    ],
)
def test_type_operations(
    session,
    alt_session,
    test_name,
    initial_setup,
    test_sql,
    expected_terms,
    expected_master_dependencies,
    expected_branch_dependencies,
):
    """Test type operations using roundtrip fidelity validation."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup=initial_setup,
        test_sql=test_sql,
        description=test_name,
        expected_sql_terms=expected_terms,
        expected_master_dependencies=expected_master_dependencies,
        expected_branch_dependencies=expected_branch_dependencies,
    )


@pytest.mark.integration
def test_enum_type_with_table_dependency(session, alt_session):
    """Test enum type creation with table that uses the enum."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="CREATE SCHEMA test_schema;",
        test_sql="""
            CREATE TYPE test_schema.user_status AS ENUM ('active', 'inactive', 'pending');

            CREATE TABLE test_schema.users (
                id INTEGER PRIMARY KEY,
                name TEXT NOT NULL,
                status test_schema.user_status DEFAULT 'pending'
            );
        """,
        description="enum type with table dependency",
        expected_sql_terms=[
            'CREATE TYPE "test_schema"."user_status"',
            "AS ENUM ('active', 'inactive', 'pending')",
            'CREATE TABLE "test_schema"."users"',
            '"status" test_schema.user_status',
        ],
        expected_master_dependencies=[],
        expected_branch_dependencies=[
            ("type:test_schema.user_status", "test_schema"),
            ("r:test_schema.users", "test_schema"),
            (
                "r:test_schema.users",
                "type:test_schema.user_status",
            ),  # Table depends on type
            (
                "i:test_schema.users_pkey",
                "test_schema.users.users_pkey",
            ),  # Index depends on constraint
            (
                "test_schema.users.users_pkey",
                "r:test_schema.users",
            ),  # Constraint depends on table
        ],
    )


@pytest.mark.integration
def test_domain_type_with_table_dependency(session, alt_session):
    """Test domain type creation with table that uses the domain."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="CREATE SCHEMA test_schema;",
        test_sql="""
            CREATE DOMAIN test_schema.email AS TEXT CHECK (VALUE ~ '^[^@]+@[^@]+\\.[^@]+$');

            CREATE TABLE test_schema.users (
                id INTEGER PRIMARY KEY,
                name TEXT NOT NULL,
                email_address test_schema.email
            );
        """,
        description="domain type with table dependency",
        expected_sql_terms=[
            'CREATE DOMAIN "test_schema"."email"',
            "AS text",
            "CHECK ((VALUE ~ '^[^@]+@[^@]+\\.[^@]+$'::text))",
            'CREATE TABLE "test_schema"."users"',
            '"email_address" test_schema.email',
        ],
        expected_master_dependencies=[],
        expected_branch_dependencies=[
            ("type:test_schema.email", "test_schema"),
            ("r:test_schema.users", "test_schema"),
            ("r:test_schema.users", "type:test_schema.email"),  # Table depends on type
            (
                "i:test_schema.users_pkey",
                "test_schema.users.users_pkey",
            ),  # Index depends on constraint
            (
                "test_schema.users.users_pkey",
                "r:test_schema.users",
            ),  # Constraint depends on table
        ],
    )


@pytest.mark.integration
def test_composite_type_with_table_dependency(session, alt_session):
    """Test composite type creation with table that uses the composite."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="CREATE SCHEMA test_schema;",
        test_sql="""
            CREATE TYPE test_schema.address AS (
                street TEXT,
                city TEXT,
                zip_code TEXT
            );

            CREATE TABLE test_schema.customers (
                id INTEGER PRIMARY KEY,
                name TEXT NOT NULL,
                billing_address test_schema.address,
                shipping_address test_schema.address
            );
        """,
        description="composite type with table dependency",
        expected_sql_terms=[
            'CREATE TYPE "test_schema"."address"',
            '"street" text',
            '"city" text',
            '"zip_code" text',
            'CREATE TABLE "test_schema"."customers"',
            '"billing_address" test_schema.address',
            '"shipping_address" test_schema.address',
        ],
        expected_master_dependencies=[],
        expected_branch_dependencies=[
            ("type:test_schema.address", "test_schema"),
            (
                "c:test_schema.address",
                "type:test_schema.address",
            ),  # Composite type's underlying table depends on type
            ("r:test_schema.customers", "test_schema"),
            (
                "r:test_schema.customers",
                "type:test_schema.address",
            ),  # Table depends on type
            (
                "i:test_schema.customers_pkey",
                "test_schema.customers.customers_pkey",
            ),  # Index depends on constraint
            (
                "test_schema.customers.customers_pkey",
                "r:test_schema.customers",
            ),  # Constraint depends on table
        ],
    )


@pytest.mark.integration
def test_multiple_types_complex_dependencies(session, alt_session):
    """Test multiple types with complex interdependencies."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="CREATE SCHEMA commerce;",
        test_sql="""
            -- Create base types
            CREATE TYPE commerce.order_status AS ENUM ('pending', 'processing', 'shipped', 'delivered', 'cancelled');
            CREATE DOMAIN commerce.price AS DECIMAL(10,2) CHECK (VALUE >= 0);

            -- Create composite type using domain
            CREATE TYPE commerce.product_info AS (
                name TEXT,
                description TEXT,
                unit_price commerce.price
            );

            -- Create tables using all types
            CREATE TABLE commerce.products (
                id INTEGER PRIMARY KEY,
                info commerce.product_info,
                category TEXT
            );

            CREATE TABLE commerce.orders (
                id INTEGER PRIMARY KEY,
                status commerce.order_status DEFAULT 'pending',
                total_amount commerce.price
            );
        """,
        description="multiple types with complex dependencies",
        expected_sql_terms=[
            'CREATE TYPE "commerce"."order_status"',
            "AS ENUM ('pending', 'processing', 'shipped', 'delivered', 'cancelled')",
            'CREATE DOMAIN "commerce"."price"',
            "AS numeric(10,2)",
            "CHECK ((VALUE >= (0)::numeric))",
            'CREATE TYPE "commerce"."product_info"',
            '"unit_price" commerce.price',
            'CREATE TABLE "commerce"."products"',
            'CREATE TABLE "commerce"."orders"',
        ],
        expected_master_dependencies=[],
        expected_branch_dependencies=[
            ("type:commerce.order_status", "commerce"),
            ("type:commerce.price", "commerce"),
            ("type:commerce.product_info", "commerce"),
            (
                "c:commerce.product_info",
                "type:commerce.price",
            ),  # Composite type's underlying table depends on domain
            (
                "c:commerce.product_info",
                "type:commerce.product_info",
            ),  # Composite type's underlying table depends on type
            ("r:commerce.products", "commerce"),
            ("r:commerce.products", "type:commerce.product_info"),
            ("r:commerce.orders", "commerce"),
            ("r:commerce.orders", "type:commerce.order_status"),
            ("r:commerce.orders", "type:commerce.price"),
            (
                "commerce.orders.orders_pkey",
                "r:commerce.orders",
            ),  # Constraint depends on table
            (
                "commerce.products.products_pkey",
                "r:commerce.products",
            ),  # Constraint depends on table
            (
                "i:commerce.orders_pkey",
                "commerce.orders.orders_pkey",
            ),  # Index depends on constraint
            (
                "i:commerce.products_pkey",
                "commerce.products.products_pkey",
            ),  # Index depends on constraint
        ],
    )


@pytest.mark.integration
def test_type_cascade_drop_with_dependent_table(session, alt_session):
    """Test that dropping a type used by a table works with CASCADE."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="""
            CREATE SCHEMA test_schema;
            CREATE TYPE test_schema.priority AS ENUM ('low', 'medium', 'high');
            CREATE TABLE test_schema.tasks (
                id INTEGER PRIMARY KEY,
                title TEXT,
                priority test_schema.priority DEFAULT 'medium'
            );
        """,
        test_sql="""
            DROP TABLE test_schema.tasks;
            DROP TYPE test_schema.priority;
        """,
        description="type cascade drop with dependent table",
        expected_sql_terms=[
            'DROP TABLE "test_schema"."tasks";',
            'DROP TYPE "test_schema"."priority";',
        ],
        expected_master_dependencies=[
            ("type:test_schema.priority", "test_schema"),
            ("r:test_schema.tasks", "test_schema"),
            ("r:test_schema.tasks", "type:test_schema.priority"),
            (
                "i:test_schema.tasks_pkey",
                "test_schema.tasks.tasks_pkey",
            ),  # Index depends on constraint
            (
                "test_schema.tasks.tasks_pkey",
                "r:test_schema.tasks",
            ),  # Constraint depends on table
        ],
        expected_branch_dependencies=[],
    )


@pytest.mark.integration
def test_type_name_with_special_characters(session, alt_session):
    """Test type operations with special characters in names."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup='CREATE SCHEMA "test-schema";',
        test_sql="""
            CREATE TYPE "test-schema"."user-status" AS ENUM ('active', 'in-active');
            CREATE DOMAIN "test-schema"."positive-number" AS INTEGER CHECK (VALUE > 0);
        """,
        description="type names with special characters",
        expected_sql_terms=[
            'CREATE TYPE "test-schema"."user-status"',
            "AS ENUM ('active', 'in-active')",
            'CREATE DOMAIN "test-schema"."positive-number"',
            "AS integer",
            "CHECK ((VALUE > 0))",
        ],
        expected_master_dependencies=[],
        expected_branch_dependencies=[
            ("type:test-schema.user-status", "test-schema"),
            ("type:test-schema.positive-number", "test-schema"),
        ],
    )


@pytest.mark.integration
def test_materialized_view_with_enum_dependency(session, alt_session):
    """Test materialized view that depends on an enum type."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="CREATE SCHEMA analytics;",
        test_sql="""
            CREATE TYPE analytics.status AS ENUM ('active', 'inactive', 'pending');

            CREATE TABLE analytics.users (
                id INTEGER PRIMARY KEY,
                name TEXT NOT NULL,
                status analytics.status DEFAULT 'pending'
            );

            CREATE MATERIALIZED VIEW analytics.user_status_summary AS
            SELECT
                status,
                COUNT(*) as count
            FROM analytics.users
            GROUP BY status;
        """,
        description="materialized view with enum dependency",
        expected_sql_terms=[
            'CREATE TYPE "analytics"."status"',
            "AS ENUM ('active', 'inactive', 'pending')",
            'CREATE TABLE "analytics"."users"',
            '"status" analytics.status',
            'CREATE MATERIALIZED VIEW "analytics"."user_status_summary"',
            "SELECT status",
            "FROM analytics.users",
            "GROUP BY status",
        ],
        expected_master_dependencies=[],
        expected_branch_dependencies=[
            ("type:analytics.status", "analytics"),
            ("r:analytics.users", "analytics"),
            ("r:analytics.users", "type:analytics.status"),  # Table depends on enum
            (
                "i:analytics.users_pkey",
                "analytics.users.users_pkey",
            ),  # Index depends on constraint
            (
                "analytics.users.users_pkey",
                "r:analytics.users",
            ),  # Constraint depends on table
            ("m:analytics.user_status_summary", "analytics"),
            (
                "m:analytics.user_status_summary",
                "r:analytics.users",
            ),  # Materialized view depends on table
            (
                "m:analytics.user_status_summary",
                "type:analytics.status",
            ),  # Materialized view depends on enum type
        ],
    )


@pytest.mark.integration
def test_materialized_view_with_domain_dependency(session, alt_session):
    """Test materialized view that depends on a domain type."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="CREATE SCHEMA financial;",
        test_sql="""
            CREATE DOMAIN financial.currency AS DECIMAL(10,2) CHECK (VALUE >= 0);

            CREATE TABLE financial.transactions (
                id INTEGER PRIMARY KEY,
                amount financial.currency NOT NULL,
                description TEXT
            );

            CREATE MATERIALIZED VIEW financial.transaction_summary AS
            SELECT
                SUM(amount) as total_amount,
                COUNT(*) as transaction_count
            FROM financial.transactions
            WHERE amount > 0;
        """,
        description="materialized view with domain dependency",
        expected_sql_terms=[
            'CREATE DOMAIN "financial"."currency"',
            "AS numeric(10,2)",
            "CHECK ((VALUE >= (0)::numeric))",
            'CREATE TABLE "financial"."transactions"',
            '"amount" financial.currency',
            'CREATE MATERIALIZED VIEW "financial"."transaction_summary"',
            "SELECT sum((amount)::numeric)",
            "FROM financial.transactions",
            "WHERE ((amount)::numeric > (0)::numeric)",
        ],
        expected_master_dependencies=[],
        expected_branch_dependencies=[
            ("type:financial.currency", "financial"),
            ("r:financial.transactions", "financial"),
            (
                "r:financial.transactions",
                "type:financial.currency",
            ),  # Table depends on domain
            (
                "i:financial.transactions_pkey",
                "financial.transactions.transactions_pkey",
            ),  # Index depends on constraint
            (
                "financial.transactions.transactions_pkey",
                "r:financial.transactions",
            ),  # Constraint depends on table
            ("m:financial.transaction_summary", "financial"),
            (
                "m:financial.transaction_summary",
                "r:financial.transactions",
            ),  # Materialized view depends on table
        ],
    )


@pytest.mark.integration
def test_materialized_view_with_composite_type_dependency(session, alt_session):
    """Test materialized view that depends on a composite type."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="CREATE SCHEMA inventory;",
        test_sql="""
            CREATE TYPE inventory.address AS (
                street TEXT,
                city TEXT,
                zip_code TEXT
            );

            CREATE TABLE inventory.warehouses (
                id INTEGER PRIMARY KEY,
                name TEXT NOT NULL,
                location inventory.address
            );

            CREATE MATERIALIZED VIEW inventory.warehouse_locations AS
            SELECT
                name,
                (location).city as city,
                (location).zip_code as zip_code
            FROM inventory.warehouses
            WHERE (location).city IS NOT NULL;
        """,
        description="materialized view with composite type dependency",
        expected_sql_terms=[
            'CREATE TYPE "inventory"."address"',
            '"street" text',
            '"city" text',
            '"zip_code" text',
            'CREATE TABLE "inventory"."warehouses"',
            '"location" inventory.address',
            'CREATE MATERIALIZED VIEW "inventory"."warehouse_locations"',
            "SELECT name",
            "(location).city",
            "(location).zip_code",
            "FROM inventory.warehouses",
        ],
        expected_master_dependencies=[],
        expected_branch_dependencies=[
            ("type:inventory.address", "inventory"),
            (
                "c:inventory.address",
                "type:inventory.address",
            ),  # Composite type's underlying table
            ("r:inventory.warehouses", "inventory"),
            (
                "r:inventory.warehouses",
                "type:inventory.address",
            ),  # Table depends on composite type
            (
                "i:inventory.warehouses_pkey",
                "inventory.warehouses.warehouses_pkey",
            ),  # Index depends on constraint
            (
                "inventory.warehouses.warehouses_pkey",
                "r:inventory.warehouses",
            ),  # Constraint depends on table
            ("m:inventory.warehouse_locations", "inventory"),
            (
                "m:inventory.warehouse_locations",
                "r:inventory.warehouses",
            ),  # Materialized view depends on table
        ],
    )


@pytest.mark.integration
def test_complex_mixed_dependencies_with_materialized_views(session, alt_session):
    """Test complex scenario with multiple types, tables, and materialized views."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="CREATE SCHEMA ecommerce;",
        test_sql="""
            -- Create types
            CREATE TYPE ecommerce.order_status AS ENUM ('pending', 'processing', 'shipped', 'delivered');
            CREATE DOMAIN ecommerce.price AS DECIMAL(10,2) CHECK (VALUE >= 0);
            CREATE TYPE ecommerce.product_info AS (
                name TEXT,
                description TEXT,
                base_price ecommerce.price
            );

            -- Create tables using the types
            CREATE TABLE ecommerce.products (
                id INTEGER PRIMARY KEY,
                info ecommerce.product_info NOT NULL,
                category TEXT
            );

            CREATE TABLE ecommerce.orders (
                id INTEGER PRIMARY KEY,
                status ecommerce.order_status DEFAULT 'pending',
                final_price ecommerce.price NOT NULL
            );

            -- Create materialized views that depend on the tables and types
            CREATE MATERIALIZED VIEW ecommerce.product_pricing AS
            SELECT
                id,
                (info).name as product_name,
                (info).base_price as base_price,
                category
            FROM ecommerce.products
            WHERE (info).base_price > 0;

            CREATE MATERIALIZED VIEW ecommerce.order_summary AS
            SELECT
                status,
                COUNT(*) as order_count,
                AVG(final_price) as avg_price
            FROM ecommerce.orders
            GROUP BY status;
        """,
        description="complex mixed dependencies with materialized views",
        expected_sql_terms=[
            'CREATE TYPE "ecommerce"."order_status"',
            "AS ENUM ('pending', 'processing', 'shipped', 'delivered')",
            'CREATE DOMAIN "ecommerce"."price"',
            "AS numeric(10,2)",
            "CHECK ((VALUE >= (0)::numeric))",
            'CREATE TYPE "ecommerce"."product_info"',
            '"base_price" ecommerce.price',
            'CREATE TABLE "ecommerce"."products"',
            '"info" ecommerce.product_info',
            'CREATE TABLE "ecommerce"."orders"',
            '"status" ecommerce.order_status',
            '"final_price" ecommerce.price',
            'CREATE MATERIALIZED VIEW "ecommerce"."product_pricing"',
            "(info).name",
            "(info).base_price",
            'CREATE MATERIALIZED VIEW "ecommerce"."order_summary"',
            "avg((final_price)::numeric)",
            "GROUP BY status",
        ],
        expected_master_dependencies=[],
        expected_branch_dependencies=[
            # Type dependencies
            ("type:ecommerce.order_status", "ecommerce"),
            ("type:ecommerce.price", "ecommerce"),
            ("type:ecommerce.product_info", "ecommerce"),
            (
                "c:ecommerce.product_info",
                "type:ecommerce.price",
            ),  # Composite type depends on domain
            (
                "c:ecommerce.product_info",
                "type:ecommerce.product_info",
            ),  # Composite type's underlying table
            # Table dependencies
            ("r:ecommerce.products", "ecommerce"),
            (
                "r:ecommerce.products",
                "type:ecommerce.product_info",
            ),  # Table depends on composite type
            ("r:ecommerce.orders", "ecommerce"),
            (
                "r:ecommerce.orders",
                "type:ecommerce.order_status",
            ),  # Table depends on enum
            ("r:ecommerce.orders", "type:ecommerce.price"),  # Table depends on domain
            # Constraint and index dependencies
            ("ecommerce.products.products_pkey", "r:ecommerce.products"),
            ("ecommerce.orders.orders_pkey", "r:ecommerce.orders"),
            ("i:ecommerce.products_pkey", "ecommerce.products.products_pkey"),
            ("i:ecommerce.orders_pkey", "ecommerce.orders.orders_pkey"),
            # Materialized view dependencies
            ("m:ecommerce.product_pricing", "ecommerce"),
            (
                "m:ecommerce.product_pricing",
                "r:ecommerce.products",
            ),  # Materialized view depends on table
            (
                "m:ecommerce.product_pricing",
                "type:ecommerce.price",
            ),  # Materialized view depends on domain type
            ("m:ecommerce.order_summary", "ecommerce"),
            (
                "m:ecommerce.order_summary",
                "r:ecommerce.orders",
            ),  # Materialized view depends on table
            (
                "m:ecommerce.order_summary",
                "type:ecommerce.order_status",
            ),  # Materialized view depends on enum type
        ],
    )


@pytest.mark.integration
def test_drop_type_with_materialized_view_dependency(session, alt_session):
    """Test dropping types that have materialized view dependencies."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="""
            CREATE SCHEMA reporting;
            CREATE TYPE reporting.priority AS ENUM ('low', 'medium', 'high');
            CREATE TABLE reporting.tasks (
                id INTEGER PRIMARY KEY,
                title TEXT NOT NULL,
                priority reporting.priority DEFAULT 'medium'
            );
            CREATE MATERIALIZED VIEW reporting.priority_stats AS
            SELECT
                priority,
                COUNT(*) as task_count
            FROM reporting.tasks
            GROUP BY priority;
        """,
        test_sql="""
            DROP MATERIALIZED VIEW reporting.priority_stats;
            DROP TABLE reporting.tasks;
            DROP TYPE reporting.priority;
        """,
        description="drop type with materialized view dependency",
        expected_sql_terms=[
            'DROP MATERIALIZED VIEW "reporting"."priority_stats";',
            'DROP TABLE "reporting"."tasks";',
            'DROP TYPE "reporting"."priority";',
        ],
        expected_master_dependencies=[
            ("type:reporting.priority", "reporting"),
            ("r:reporting.tasks", "reporting"),
            ("r:reporting.tasks", "type:reporting.priority"),
            ("i:reporting.tasks_pkey", "reporting.tasks.tasks_pkey"),
            ("reporting.tasks.tasks_pkey", "r:reporting.tasks"),
            ("m:reporting.priority_stats", "reporting"),
            ("m:reporting.priority_stats", "r:reporting.tasks"),
            (
                "m:reporting.priority_stats",
                "type:reporting.priority",
            ),  # Materialized view depends on enum type
        ],
        expected_branch_dependencies=[],
    )


@pytest.mark.integration
def test_materialized_view_with_range_type_dependency(session, alt_session):
    """Test materialized view that depends on a range type."""
    roundtrip_fidelity_test(
        master_session=session,
        branch_session=alt_session,
        initial_setup="CREATE SCHEMA scheduling;",
        test_sql="""
            CREATE TYPE scheduling.time_range AS RANGE (subtype = timestamp);

            CREATE TABLE scheduling.events (
                id INTEGER PRIMARY KEY,
                name TEXT NOT NULL,
                time_slot scheduling.time_range
            );

            CREATE MATERIALIZED VIEW scheduling.event_durations AS
            SELECT
                name,
                EXTRACT(EPOCH FROM (upper(time_slot) - lower(time_slot))) / 3600 as duration_hours
            FROM scheduling.events
            WHERE time_slot IS NOT NULL;
        """,
        description="materialized view with range type dependency",
        expected_sql_terms=[
            'CREATE TYPE "scheduling"."time_range"',
            "AS RANGE (subtype = timestamp(0) without time zone)",
            'CREATE TABLE "scheduling"."events"',
            '"time_slot" scheduling.time_range',
            'CREATE MATERIALIZED VIEW "scheduling"."event_durations"',
            "upper(time_slot)",
            "lower(time_slot)",
            "FROM scheduling.events",
        ],
        expected_master_dependencies=[],
        expected_branch_dependencies=[
            ("type:scheduling.time_range", "scheduling"),
            ("r:scheduling.events", "scheduling"),
            (
                "r:scheduling.events",
                "type:scheduling.time_range",
            ),  # Table depends on range type
            (
                "i:scheduling.events_pkey",
                "scheduling.events.events_pkey",
            ),  # Index depends on constraint
            (
                "scheduling.events.events_pkey",
                "r:scheduling.events",
            ),  # Constraint depends on table
            ("m:scheduling.event_durations", "scheduling"),
            (
                "m:scheduling.event_durations",
                "r:scheduling.events",
            ),  # Materialized view depends on table
        ],
    )
