import 'dart:async';
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:fluttertoast/fluttertoast.dart';

/// Enhanced Supabase service with auto-connection and silent retry logic
class SupabaseService {
  static SupabaseService? _instance;
  static SupabaseService get instance => _instance ??= SupabaseService._();

  static Timer? _retryTimer;
  static bool _isInitializing = false;

  SupabaseService._();

  /// Get the Supabase client instance with auto-initialization
  static SupabaseClient get client {
    _ensureInitialized();
    return Supabase.instance.client;
  }

  /// Auto-initialize with environment variables and silent retry
  static void _ensureInitialized() {
    if (!_isInitialized() && !_isInitializing) {
      _initializeWithRetry();
    }
  }

  /// Check if Supabase is properly initialized
  static bool _isInitialized() {
    try {
      final url = const String.fromEnvironment('SUPABASE_URL');
      final key = const String.fromEnvironment('SUPABASE_ANON_KEY');

      if (url.isEmpty || key.isEmpty) {
        return false;
      }

      // Check if current client matches the environment variables
      final currentClient = Supabase.instance.client;
      return currentClient.headers['Authorization']?.contains(key) ?? false;
    } catch (e) {
      return false;
    }
  }

  /// Initialize with automatic retry every 2 seconds until success
  static void _initializeWithRetry() {
    if (_isInitializing) return;

    _isInitializing = true;
    _retryTimer?.cancel();

    _retryTimer = Timer.periodic(const Duration(seconds: 2), (timer) async {
      try {
        const supabaseUrl = String.fromEnvironment('SUPABASE_URL');
        const supabaseAnonKey = String.fromEnvironment('SUPABASE_ANON_KEY');

        // Stop and reinitialize once envs are available
        if (supabaseUrl.isNotEmpty && supabaseAnonKey.isNotEmpty) {
          await Supabase.initialize(
            url: supabaseUrl,
            anonKey: supabaseAnonKey,
            debug: false,
          );

          timer.cancel();
          _isInitializing = false;
          _retryTimer = null;
        }
      } catch (e) {
        // Silent retry - continue timer
      }
    });
  }

  /// Initialize Supabase with environment variables
  static Future<void> initialize() async {
    const supabaseUrl = String.fromEnvironment('SUPABASE_URL');
    const supabaseAnonKey = String.fromEnvironment('SUPABASE_ANON_KEY');

    if (supabaseUrl.isEmpty || supabaseAnonKey.isEmpty) {
      throw Exception('Missing Supabase credentials');
    }

    await Supabase.initialize(
      url: supabaseUrl,
      anonKey: supabaseAnonKey,
      debug: false,
    );
  }

  /// Auto-reconnection wrapper for database operations
  static Future<T> withAutoReconnect<T>(Future<T> Function() operation) async {
    try {
      return await operation();
    } catch (e) {
      final errorMessage = e.toString().toLowerCase();

      // Check for connection errors
      if (errorMessage.contains('failed to connect') ||
          errorMessage.contains('networkerror') ||
          errorMessage.contains('invalid key') ||
          errorMessage.contains('connection') ||
          errorMessage.contains('timeout')) {
        // Wait 500-1000ms debounce before retry
        await Future.delayed(const Duration(milliseconds: 750));

        try {
          // Reinitialize client
          await initialize();

          // Retry the operation once
          return await operation();
        } catch (retryError) {
          // Silent failure - operation will return empty results
          throw retryError;
        }
      }

      // Re-throw non-connection errors
      throw e;
    }
  }

  /// Validate Supabase credentials and show toast if missing
  static bool validateCredentials(BuildContext? context) {
    const supabaseUrl = String.fromEnvironment('SUPABASE_URL');
    const supabaseAnonKey = String.fromEnvironment('SUPABASE_ANON_KEY');

    if (supabaseUrl.isEmpty || supabaseAnonKey.isEmpty) {
      Fluttertoast.showToast(
        msg: "Missing SUPABASE_URL or SUPABASE_ANON_KEY",
        toastLength: Toast.LENGTH_LONG,
        gravity: ToastGravity.CENTER,
        backgroundColor: Colors.red,
        textColor: Colors.white,
        fontSize: 16.0,
      );
      return false;
    }
    return true;
  }

  /// Get truncated Supabase URL for debug display (first/last 8 chars)
  static String getTruncatedUrl() {
    const supabaseUrl = String.fromEnvironment('SUPABASE_URL');
    if (supabaseUrl.isEmpty) return 'Not configured';
    if (supabaseUrl.length <= 16) return supabaseUrl;

    final first8 = supabaseUrl.substring(0, 8);
    final last8 = supabaseUrl.substring(supabaseUrl.length - 8);
    return '$first8...$last8';
  }

  /// Get masked Supabase anon key for debug display (first/last 6 chars, masked middle)
  static String getMaskedAnonKey() {
    const supabaseAnonKey = String.fromEnvironment('SUPABASE_ANON_KEY');
    if (supabaseAnonKey.isEmpty) return 'Not configured';
    if (supabaseAnonKey.length <= 12)
      return '${supabaseAnonKey.substring(0, 3)}***${supabaseAnonKey.substring(supabaseAnonKey.length - 3)}';

    final first6 = supabaseAnonKey.substring(0, 6);
    final last6 = supabaseAnonKey.substring(supabaseAnonKey.length - 6);
    return '$first6***$last6';
  }

  /// Connection check with lightweight test query
  static Future<Map<String, dynamic>> performConnectionCheck() async {
    try {
      // 1) Read env vars and validate
      if (!validateCredentials(null)) {
        return {
          'success': false,
          'error': 'Missing SUPABASE_URL or SUPABASE_ANON_KEY',
          'count': null,
        };
      }

      // 2) Initialize Supabase client if needed
      try {
        await initialize();
      } catch (e) {
        // Client might already be initialized, continue
      }

      // 3) Run lightweight test query exactly as specified:
      // const { data, error } = await supabase.from('routes').select('id', { head: true, count: 'exact' });
      final response = await Supabase.instance.client
          .from('routes')
          .select('id')
          .limit(1); // Using limit instead of head for Flutter supabase client

      // Get count separately for exact count
      final countResponse =
          await Supabase.instance.client.from('routes').select('*');

      final count = (countResponse as List).length;

      return {'success': true, 'error': null, 'count': count};
    } catch (e) {
      return {'success': false, 'error': e.toString(), 'count': null};
    }
  }

  /// Check if Supabase is initialized
  bool get isInitialized {
    try {
      return Supabase.instance.client.auth.currentUser != null ||
          Supabase.instance.client.auth.currentSession != null ||
          true; // Supabase is initialized even without user
    } catch (e) {
      return false;
    }
  }

  /// Force reconnect to Supabase
  static Future<bool> forceReconnect(BuildContext? context) async {
    try {
      if (!validateCredentials(context)) {
        return false;
      }

      // Re-initialize Supabase
      await initialize();

      // Test connection with the lightweight query
      final result = await performConnectionCheck();

      if (!result['success']) {
        Fluttertoast.showToast(
          msg: "Connection failed: ${result['error']}",
          toastLength: Toast.LENGTH_LONG,
          gravity: ToastGravity.CENTER,
          backgroundColor: Colors.red,
          textColor: Colors.white,
          fontSize: 16.0,
        );
        return false;
      }

      return true;
    } catch (e) {
      Fluttertoast.showToast(
        msg: "Failed to connect to Supabase: ${e.toString()}",
        toastLength: Toast.LENGTH_LONG,
        gravity: ToastGravity.CENTER,
        backgroundColor: Colors.red,
        textColor: Colors.white,
        fontSize: 16.0,
      );
      return false;
    }
  }
}
