import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:tugas_akhir_supabase/utils/fix_users_policy.dart';
import 'package:tugas_akhir_supabase/utils/fix_user_roles_policy.dart';

/// Utility class to fix all database policies
class FixDatabasePoliciesUtil {
  /// Fix all database policies to prevent infinite recursion
  static Future<void> fixAllPolicies(BuildContext context) async {
    try {
      // Show loading dialog
      showDialog(
        context: context,
        barrierDismissible: false,
        builder: (context) => const AlertDialog(
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              CircularProgressIndicator(),
              SizedBox(height: 16),
              Text('Memperbaiki semua kebijakan database...'),
            ],
          ),
        ),
      );

      final client = Supabase.instance.client;

      // Step 1: Fix users policy
      try {
        // Drop the problematic policy
        await client.rpc(
          'execute_sql',
          params: {
            'sql_statement': 'DROP POLICY IF EXISTS users_policy ON auth.users;',
          },
        );
        print('Dropped users policy');

        // Create a new policy without recursion
        await client.rpc(
          'execute_sql',
          params: {
            'sql_statement': '''
CREATE POLICY users_policy ON auth.users
    FOR SELECT
    USING (
        auth.uid() = id 
        OR 
        EXISTS (
            SELECT 1 FROM public.user_roles 
            WHERE user_id = auth.uid() AND role = 'admin'
        )
    );
            ''',
          },
        );
        print('Created new users policy');

        // Grant necessary permissions
        await client.rpc(
          'execute_sql',
          params: {
            'sql_statement': 'GRANT SELECT ON auth.users TO authenticated; GRANT SELECT ON auth.users TO anon;',
          },
        );
        print('Granted permissions for users');
      } catch (e) {
        print('Error fixing users policy: $e');
      }

      // Step 2: Fix user_roles policy
      try {
        // Drop ALL existing policies
        await client.rpc(
          'execute_sql',
          params: {
            'sql_statement': '''
DROP POLICY IF EXISTS "Users can view their own roles" ON public.user_roles;
DROP POLICY IF EXISTS "Admins can manage all roles" ON public.user_roles;
DROP POLICY IF EXISTS "Users can manage their own roles" ON public.user_roles;
DROP POLICY IF EXISTS "Admins can view all roles" ON public.user_roles;
DROP POLICY IF EXISTS "All users can view roles" ON public.user_roles;
DROP POLICY IF EXISTS "Users can view own role" ON public.user_roles;
DROP POLICY IF EXISTS "Users can view their roles" ON public.user_roles;
DROP POLICY IF EXISTS "Admins can manage roles" ON public.user_roles;
            ''',
          },
        );
        print('Dropped all user_roles policies');

        // Create new clean policies
        await client.rpc(
          'execute_sql',
          params: {
            'sql_statement': '''
-- Policy for users to manage their own roles
CREATE POLICY "user_roles_self_management" 
    ON public.user_roles 
    FOR ALL
    USING (auth.uid() = user_id);

-- Policy for admins to see all roles (without recursion)
CREATE POLICY "user_roles_view_all" 
    ON public.user_roles 
    FOR SELECT
    TO authenticated
    USING (true);
            ''',
          },
        );
        print('Created new user_roles policies');

        // Grant necessary permissions
        await client.rpc(
          'execute_sql',
          params: {
            'sql_statement': 'GRANT SELECT ON public.user_roles TO authenticated; GRANT SELECT ON public.user_roles TO anon;',
          },
        );
        print('Granted permissions for user_roles');
      } catch (e) {
        print('Error fixing user_roles policy: $e');
      }

      // Step 3: Ensure current user is admin
      try {
        final userId = client.auth.currentUser?.id;
        if (userId != null) {
          await client.rpc(
            'execute_sql',
            params: {
              'sql_statement': '''
INSERT INTO public.user_roles (user_id, role)
SELECT '$userId', 'admin'
WHERE NOT EXISTS (
  SELECT 1 FROM public.user_roles WHERE user_id = '$userId' AND role = 'admin'
);
              ''',
            },
          );
          print('Ensured current user is admin');
        }
      } catch (e) {
        print('Error ensuring admin status: $e');
      }

      // Close the dialog
      Navigator.pop(context);

      // Show success message
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Semua kebijakan database berhasil diperbaiki'),
          backgroundColor: Colors.green,
        ),
      );
    } catch (e) {
      print('Error fixing database policies: $e');
      
      // Close the dialog if it's open
      Navigator.pop(context);
      
      // Show error message
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Gagal memperbaiki kebijakan database: ${e.toString()}'),
          backgroundColor: Colors.red,
        ),
      );
    }
  }
}
