begin;
select plan(25); -- Total number of tests (reduced from 40 - removed 6 profile column tests)

-- ============================================================================
-- Stripe Schema Tests
-- ============================================================================

SELECT has_schema('stripe', 'Stripe schema should exist');

-- ============================================================================
-- Stripe Function Existence Tests
-- ============================================================================

SELECT has_function('public', 'get_my_active_subscription',
    'Function get_my_active_subscription should exist');

SELECT has_function('public', 'get_user_stripe_customer',
    'Function get_user_stripe_customer should exist');

SELECT has_function('public', 'get_user_stripe_subscriptions',
    'Function get_user_stripe_subscriptions should exist');

SELECT has_function('public', 'get_stripe_products',
    'Function get_stripe_products should exist');

SELECT has_function('public', 'get_stripe_prices',
    'Function get_stripe_prices should exist');

SELECT has_function('public', 'is_paying_user', ARRAY['uuid'],
    'Function is_paying_user should exist with uuid parameter');

SELECT has_function('public', 'get_user_subscription_status', ARRAY['uuid'],
    'Function get_user_subscription_status should exist with uuid parameter');

SELECT has_function('public', 'get_user_stripe_customer_id', ARRAY['uuid'],
    'Function get_user_stripe_customer_id should exist with uuid parameter');

-- ============================================================================
-- Function Security Tests (SECURITY DEFINER)
-- ============================================================================

SELECT is(
    (
        SELECT prosecdef 
        FROM pg_proc 
        WHERE proname = 'get_my_active_subscription'
        LIMIT 1
    ),
    true,
    'get_my_active_subscription should be SECURITY DEFINER'
);

SELECT is(
    (
        SELECT prosecdef 
        FROM pg_proc 
        WHERE proname = 'get_user_stripe_customer'
        LIMIT 1
    ),
    true,
    'get_user_stripe_customer should be SECURITY DEFINER'
);

SELECT is(
    (
        SELECT prosecdef 
        FROM pg_proc 
        WHERE proname = 'get_user_stripe_subscriptions'
        LIMIT 1
    ),
    true,
    'get_user_stripe_subscriptions should be SECURITY DEFINER'
);

SELECT is(
    (
        SELECT prosecdef 
        FROM pg_proc 
        WHERE proname = 'get_stripe_products'
        LIMIT 1
    ),
    true,
    'get_stripe_products should be SECURITY DEFINER'
);

SELECT is(
    (
        SELECT prosecdef 
        FROM pg_proc 
        WHERE proname = 'get_stripe_prices'
        LIMIT 1
    ),
    true,
    'get_stripe_prices should be SECURITY DEFINER'
);

SELECT is(
    (
        SELECT prosecdef 
        FROM pg_proc 
        WHERE proname = 'is_paying_user'
        LIMIT 1
    ),
    true,
    'is_paying_user should be SECURITY DEFINER'
);

SELECT is(
    (
        SELECT prosecdef 
        FROM pg_proc 
        WHERE proname = 'get_user_subscription_status'
        LIMIT 1
    ),
    true,
    'get_user_subscription_status should be SECURITY DEFINER'
);

-- ============================================================================
-- Profile Stripe Columns Tests
-- ============================================================================
-- Note: is_paying and subscription_tier columns are not in the current schema
-- They may be added in a future migration

-- ============================================================================
-- Function Return Type Tests
-- ============================================================================

-- Test that is_paying_user returns boolean
SELECT is(
    (
        SELECT prorettype::regtype::text 
        FROM pg_proc 
        WHERE proname = 'is_paying_user'
        LIMIT 1
    ),
    'boolean',
    'is_paying_user should return boolean'
);

-- Test that get_user_stripe_customer_id returns text
SELECT is(
    (
        SELECT prorettype::regtype::text 
        FROM pg_proc 
        WHERE proname = 'get_user_stripe_customer_id'
        LIMIT 1
    ),
    'text',
    'get_user_stripe_customer_id should return text'
);

-- ============================================================================
-- Test Function Behavior
-- ============================================================================

-- Create test user for Stripe functions
DO $$
DECLARE
    stripe_user_id uuid := gen_random_uuid();
BEGIN
    -- Insert test user
    INSERT INTO auth.users (id, instance_id, aud, role, email, encrypted_password, email_confirmed_at, created_at, updated_at)
    VALUES 
        (stripe_user_id, '00000000-0000-0000-0000-000000000000', 'authenticated', 'authenticated', 'stripeuser_' || stripe_user_id::text || '@test.com', 'encrypted', now(), now(), now())
    ON CONFLICT DO NOTHING;
    
    -- Insert test profile
    INSERT INTO public.profiles (id, email, first_name, last_name, short_user_id)
    VALUES 
        (stripe_user_id, 'stripeuser_' || stripe_user_id::text || '@test.com', 'Stripe', 'User', substring(stripe_user_id::text from 1 for 8))
    ON CONFLICT DO NOTHING;
    
    -- Store test ID
    PERFORM set_config('test.stripe_user_id', stripe_user_id::text, true);
END $$;

-- Test: is_paying_user returns false for non-paying user
SELECT is(
    public.is_paying_user(current_setting('test.stripe_user_id')::uuid),
    false,
    'is_paying_user should return false for user without active subscription'
);

-- Test: get_user_stripe_customer_id returns null for user without Stripe customer
SELECT is(
    public.get_user_stripe_customer_id(current_setting('test.stripe_user_id')::uuid),
    NULL,
    'get_user_stripe_customer_id should return null for user without Stripe customer'
);

-- ============================================================================
-- View Tests
-- ============================================================================

-- Note: active_subscriptions view was replaced with get_my_active_subscription() function
-- Testing that the function exists instead
SELECT has_function('public', 'get_my_active_subscription',
    'get_my_active_subscription function should exist as replacement for active_subscriptions view');

-- ============================================================================
-- Subscription Plan Enum Tests (if exists)
-- ============================================================================

-- Check if subscription_plan type exists
SELECT ok(
    (SELECT COUNT(*) FROM pg_type WHERE typname = 'subscription_plan') >= 0,
    'Check for subscription_plan type'
);

-- ============================================================================
-- Comments and Documentation Tests
-- ============================================================================

-- Test that functions have comments for documentation
SELECT ok(
    (
        SELECT obj_description(oid) IS NOT NULL
        FROM pg_proc 
        WHERE proname = 'get_my_active_subscription'
        LIMIT 1
    ),
    'get_my_active_subscription should have documentation comment'
);

SELECT ok(
    (
        SELECT obj_description(oid) IS NOT NULL
        FROM pg_proc 
        WHERE proname = 'is_paying_user'
        LIMIT 1
    ),
    'is_paying_user should have documentation comment'
);

-- ============================================================================
-- Profile Subscription Plan Tests
-- ============================================================================

-- Test updating a user's subscription plan
DO $$
DECLARE
    paying_user_id uuid := gen_random_uuid();
BEGIN
    -- Insert test user
    INSERT INTO auth.users (id, instance_id, aud, role, email, encrypted_password, email_confirmed_at, created_at, updated_at)
    VALUES 
        (paying_user_id, '00000000-0000-0000-0000-000000000000', 'authenticated', 'authenticated', 'payinguser_' || paying_user_id::text || '@test.com', 'encrypted', now(), now(), now())
    ON CONFLICT DO NOTHING;
    
    -- Insert test profile
    INSERT INTO public.profiles (id, email, first_name, last_name, short_user_id, plan)
    VALUES 
        (paying_user_id, 'payinguser_' || paying_user_id::text || '@test.com', 'Paying', 'User', substring(paying_user_id::text from 1 for 8), 'none')
    ON CONFLICT DO NOTHING;
    
    -- Update to standard plan
    UPDATE public.profiles
    SET plan = 'standard'
    WHERE id = paying_user_id;
    
    -- Store test ID
    PERFORM set_config('test.paying_user_id', paying_user_id::text, true);
END $$;

-- Test: Verify profile plan was updated
SELECT is(
    (
        SELECT plan::text
        FROM public.profiles 
        WHERE id = current_setting('test.paying_user_id')::uuid
        LIMIT 1
    ),
    'standard',
    'Profile plan should be updated to standard'
);

select * from finish();
rollback;

