/**
 * Edge Function Integration Tests
 * 
 * Tests for edge function authentication, authorization, and functionality.
 */

import { supabase } from '@/integrations/supabase/client';
import type { TestSuite, TestResult } from '../testRunner';

export const edgeFunctionTestSuite: TestSuite = {
  id: 'edge-functions',
  name: 'Edge Function Tests',
  description: 'Tests for edge function authentication and business logic',
  tests: [
    {
      id: 'edge-001',
      name: 'Edge Function Authentication',
      description: 'Validates edge functions require authentication',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();

        try {
          // Get current session
          const { data: session } = await supabase.auth.getSession();
          
          if (!session.session) {
            throw new Error('No active session for test');
          }

          // Verify we have a valid JWT token
          const token = session.session.access_token;
          if (!token || token.length < 50) {
            throw new Error('Invalid access token');
          }

          // Decode JWT to check structure (basic validation)
          const parts = token.split('.');
          if (parts.length !== 3) {
            throw new Error('JWT token has invalid structure');
          }

          // Test that auth is working by calling a protected endpoint
          const { data: user } = await supabase.auth.getUser();
          if (!user.user) {
            throw new Error('Cannot retrieve authenticated user');
          }

          const duration = Date.now() - startTime;

          return {
            id: 'edge-001',
            name: 'Edge Function Authentication',
            suite: 'Edge Function Tests',
            status: 'pass',
            duration,
            timestamp: new Date().toISOString(),
            details: {
              hasToken: true,
              userId: user.user.id,
              tokenLength: token.length
            }
          };

        } catch (error) {
          return {
            id: 'edge-001',
            name: 'Edge Function Authentication',
            suite: 'Edge Function Tests',
            status: 'fail',
            duration: Date.now() - startTime,
            error: error instanceof Error ? error.message : String(error),
            timestamp: new Date().toISOString()
          };
        }
      }
    },
    {
      id: 'edge-002',
      name: 'User Ban Check Function',
      description: 'Tests is_user_banned database function',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();

        try {
          const { data: userData } = await supabase.auth.getUser();
          if (!userData.user) throw new Error('No authenticated user');

          // Call the ban check function
          const { data: isBanned, error: banError } = await supabase
            .rpc('is_user_banned', {
              _user_id: userData.user.id
            });

          if (banError) throw new Error(`Ban check failed: ${banError.message}`);

          // Superuser running tests should not be banned
          if (isBanned === true) {
            throw new Error('Test user is banned (superuser should not be banned)');
          }

          const duration = Date.now() - startTime;

          return {
            id: 'edge-002',
            name: 'User Ban Check Function',
            suite: 'Edge Function Tests',
            status: 'pass',
            duration,
            timestamp: new Date().toISOString(),
            details: {
              userId: userData.user.id,
              isBanned: isBanned,
              functionWorks: true
            }
          };

        } catch (error) {
          return {
            id: 'edge-002',
            name: 'User Ban Check Function',
            suite: 'Edge Function Tests',
            status: 'fail',
            duration: Date.now() - startTime,
            error: error instanceof Error ? error.message : String(error),
            timestamp: new Date().toISOString()
          };
        }
      }
    },
    {
      id: 'edge-003',
      name: 'Moderator Permissions Function',
      description: 'Tests is_moderator and permission checking',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();

        try {
          const { data: userData } = await supabase.auth.getUser();
          if (!userData.user) throw new Error('No authenticated user');

          // Test is_moderator function
          const { data: isMod, error: modError } = await supabase
            .rpc('is_moderator', {
              _user_id: userData.user.id
            });

          if (modError) throw new Error(`Moderator check failed: ${modError.message}`);

          // Test user running tests should be a moderator (superuser)
          if (!isMod) {
            throw new Error('Test user is not a moderator (superuser should be moderator)');
          }

          // Test is_superuser function
          const { data: isSuperuser, error: superError } = await supabase
            .rpc('is_superuser', {
              _user_id: userData.user.id
            });

          if (superError) throw new Error(`Superuser check failed: ${superError.message}`);

          if (!isSuperuser) {
            throw new Error('Test user is not a superuser');
          }

          const duration = Date.now() - startTime;

          return {
            id: 'edge-003',
            name: 'Moderator Permissions Function',
            suite: 'Edge Function Tests',
            status: 'pass',
            duration,
            timestamp: new Date().toISOString(),
            details: {
              userId: userData.user.id,
              isModerator: isMod,
              isSuperuser: isSuperuser,
              functionsWork: true
            }
          };

        } catch (error) {
          return {
            id: 'edge-003',
            name: 'Moderator Permissions Function',
            suite: 'Edge Function Tests',
            status: 'fail',
            duration: Date.now() - startTime,
            error: error instanceof Error ? error.message : String(error),
            timestamp: new Date().toISOString()
          };
        }
      }
    }
  ]
};
