import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:tugas_akhir_supabase/screens/community/models/farming_guide_model.dart';
import 'package:tugas_akhir_supabase/screens/community/data/static_guides_data.dart';
import 'package:tugas_akhir_supabase/screens/community/utils/plant_categorizer.dart';

class GuideService {
  final _supabase = Supabase.instance.client;

  // Storage bucket that should be used for images
  String _imageBucket = 'images';
  bool _bucketsChecked = false;

  // Singleton pattern
  static final GuideService _instance = GuideService._internal();
  factory GuideService() => _instance;
  GuideService._internal() {
    // Check available buckets
    _checkAvailableBuckets();
    // Debug existing guides when service is created
    debugCheckExistingGuides();
  }

  // Check available buckets and set the appropriate one to use
  Future<void> _checkAvailableBuckets() async {
    if (_bucketsChecked) return;

    try {
      final buckets = await _supabase.storage.listBuckets();
      final bucketNames = buckets.map((b) => b.name).toList();

      debugPrint('Available buckets: ${bucketNames.join(', ')}');

      // Preferred bucket order: images, guide_images, avatars
      if (bucketNames.contains('images')) {
        _imageBucket = 'images';
      } else if (bucketNames.contains('guide_images')) {
        _imageBucket = 'guide_images';
      } else if (bucketNames.contains('avatars')) {
        _imageBucket = 'avatars';
      } else if (bucketNames.isNotEmpty) {
        _imageBucket = bucketNames.first;
      }

      debugPrint('Selected bucket for guide images: $_imageBucket');
      _bucketsChecked = true;
    } catch (e) {
      debugPrint('Error checking buckets: $e');
    }
  }

  // Debug function to check existing guides and their image URLs
  Future<void> debugCheckExistingGuides() async {
    try {
      await _checkAvailableBuckets();

      final response = await _supabase
          .from('farming_guides')
          .select('*')
          .timeout(const Duration(seconds: 5));

      debugPrint('====== DEBUG EXISTING GUIDES ======');
      debugPrint('Found ${response.length} guides in database');
      debugPrint('Using bucket: $_imageBucket');

      // Check each guide and its image URL
      for (var i = 0; i < response.length; i++) {
        final guide = response[i];
        final id = guide['id'] ?? 'unknown';
        final title = guide['title'] ?? 'No title';
        final imageUrl = guide['image_url'];

        debugPrint('Guide #${i + 1}: $title (ID: $id)');

        if (imageUrl == null) {
          debugPrint('  - No image URL (null)');
        } else if (imageUrl.isEmpty) {
          debugPrint('  - Empty image URL');
        } else {
          debugPrint('  - Original image URL: $imageUrl');
          final fixedUrl = fixImageUrl(imageUrl);
          debugPrint('  - Fixed image URL: $fixedUrl');

          // Try to fix the guide's image URL in the database if needed
          if (fixedUrl != null && fixedUrl != imageUrl) {
            try {
              await _supabase
                  .from('farming_guides')
                  .update({'image_url': fixedUrl})
                  .eq('id', id);
              debugPrint('  - Updated image URL in database');
            } catch (e) {
              debugPrint('  - Failed to update image URL: $e');
            }
          }
        }
      }
      debugPrint('====== END DEBUG ======');
    } catch (e) {
      debugPrint('Error checking existing guides: $e');
    }
  }

  // Mengambil panduan dari database dan menggabungkan dengan data statis
  Future<List<FarmingGuideModel>> getGuides() async {
    try {
      // Mencoba mengambil data dari Supabase dengan timeout 5 detik
      final response = await _supabase
          .from('farming_guides')
          .select('*')
          .order('created_at', ascending: false)
          .timeout(const Duration(seconds: 5));

      debugPrint('Loaded ${response.length} guides from database');

      // Cek respons untuk masalah pada data gambar
      for (final guide in response) {
        if (guide['image_url'] == null) {
          debugPrint('Guide with title "${guide['title']}" has null image_url');
        } else {
          debugPrint('Guide image URL: ${guide['image_url']}');
        }
      }

      // Konversi ke List<FarmingGuideModel> dengan auto-kategorisasi jika perlu
      final dbGuides =
          List<Map<String, dynamic>>.from(response).map((map) {
            // Jika kategori kosong atau generic, coba kategorikan otomatis
            final currentCategory = map['category'] ?? '';
            if (currentCategory.isEmpty ||
                currentCategory.toLowerCase() == 'umum') {
              final title = map['title'] ?? '';
              final content = map['content'] ?? '';

              // Auto-kategorisasi berdasarkan judul dan konten
              final category = PlantCategorizer.categorize(
                title,
                description: content,
              );
              map['category'] = category;

              debugPrint('Auto-categorized "${title}" as "$category"');
            }

            // Cek dan perbaiki URL gambar
            if (map['image_url'] != null) {
              map['image_url'] = fixImageUrl(map['image_url']);
            }

            return FarmingGuideModel.fromMap(map);
          }).toList();

      // Mendapatkan data statis
      final staticGuides = StaticGuidesData().getAllGuides();

      // Gabungkan keduanya
      final allGuides = [...dbGuides, ...staticGuides];

      // Hilangkan duplikat berdasarkan judul
      final uniqueTitles = <String>{};
      final uniqueGuides = <FarmingGuideModel>[];

      for (final guide in allGuides) {
        if (uniqueTitles.add(guide.title)) {
          uniqueGuides.add(guide);
        }
      }

      return uniqueGuides;
    } catch (e) {
      // Jika terjadi error, gunakan data statis saja
      debugPrint('Error loading guides from database: $e');
      debugPrint('Falling back to static data only');
      return StaticGuidesData().getAllGuides();
    }
  }

  // Mengambil panduan berdasarkan kategori
  Future<List<FarmingGuideModel>> getGuidesByCategory(String category) async {
    if (category.isEmpty) {
      return getGuides();
    }

    try {
      // Mendapatkan semua panduan terlebih dahulu
      final allGuides = await getGuides();

      // Filter berdasarkan kategori
      // Ubah pencocokan menjadi case-insensitive dan juga menerima partial match
      return allGuides.where((guide) {
        // Check if the category matches (case insensitive)
        if (guide.category.toLowerCase() == category.toLowerCase()) {
          return true;
        }

        // Check if it's a partial match (for better categorization)
        if (guide.category.toLowerCase().contains(category.toLowerCase()) ||
            category.toLowerCase().contains(guide.category.toLowerCase())) {
          return true;
        }

        return false;
      }).toList();
    } catch (e) {
      // Jika terjadi error, gunakan data statis saja
      debugPrint('Error filtering guides by category: $e');
      return StaticGuidesData().getGuidesByCategory(category);
    }
  }

  // Memperbaiki URL gambar jika perlu
  String? fixImageUrl(String? imageUrl) {
    if (imageUrl == null || imageUrl.isEmpty) {
      return null;
    }

    // Log untuk debugging
    debugPrint('Original image URL: $imageUrl');

    // Fix URL jika perlu (pastikan URL lengkap)
    if (!imageUrl.startsWith('http')) {
      // Jika URL tidak lengkap, gunakan Storage dari Supabase
      String bucketName = _imageBucket; // Use the detected bucket
      String fileName = imageUrl;

      // Jika imageUrl sudah mengandung nama bucket, ekstrak
      if (imageUrl.contains('/')) {
        final parts = imageUrl.split('/');
        if (parts.length >= 2) {
          bucketName = parts[0];
          fileName = parts.sublist(1).join('/');
        }
      }

      // Dapatkan URL publik yang valid
      try {
        final fixedUrl = _supabase.storage
            .from(bucketName)
            .getPublicUrl(fileName);
        debugPrint('Fixed image URL: $fixedUrl');
        return fixedUrl;
      } catch (e) {
        debugPrint('Error fixing image URL: $e');
        return imageUrl; // Kembalikan URL asli jika gagal
      }
    }

    return imageUrl;
  }
}
