import 'dart:developer';
import 'package:dartz/dartz.dart';
import 'package:enaklo_pos/data/datasources/product/product_local_datasource.dart';
import 'package:enaklo_pos/data/datasources/product_remote_datasource.dart';
import 'package:enaklo_pos/data/models/response/product_response_model.dart';

class ProductRepository {
  static ProductRepository? _instance;

  final ProductLocalDatasource _localDatasource;
  final ProductRemoteDatasource _remoteDatasource;

  ProductRepository._internal()
      : _localDatasource = ProductLocalDatasource.instance,
        _remoteDatasource = ProductRemoteDatasource();

  static ProductRepository get instance {
    _instance ??= ProductRepository._internal();
    return _instance!;
  }

  // ========================================
  // PURE LOCAL DATABASE OPERATIONS
  // ========================================
  Future<Either<String, ProductResponseModel>> getProducts({
    int page = 1,
    int limit = 10,
    String? categoryId,
    String? search,
    bool forceRefresh = false, // Ignored - kept for compatibility
  }) async {
    try {
      log('📱 Getting products from local database - page: $page, categoryId: $categoryId, search: $search');

      // Clean expired cache for optimal performance
      _localDatasource.clearExpiredCache();

      // Use cached query for maximum performance
      final cachedProducts = await _localDatasource.getCachedProducts(
        page: page,
        limit: limit,
        categoryId: categoryId,
        search: search,
      );

      final totalCount = await _localDatasource.getTotalCount(
        categoryId: categoryId,
        search: search,
      );

      final productData = ProductData(
        products: cachedProducts,
        totalCount: totalCount,
        page: page,
        limit: limit,
        totalPages: totalCount > 0 ? (totalCount / limit).ceil() : 0,
      );

      final response = ProductResponseModel(
        success: true,
        data: productData,
        errors: null,
      );

      log('✅ Returned ${cachedProducts.length} local products (${totalCount} total)');
      return Right(response);
    } catch (e) {
      log('❌ Error getting local products: $e');
      return Left('Gagal memuat produk dari database lokal: $e');
    }
  }

  // ========================================
  // OPTIMIZED LOCAL SEARCH
  // ========================================
  Future<Either<String, List<Product>>> searchProductsOptimized(
      String query) async {
    try {
      log('🔍 Local optimized search for: "$query"');

      final products = await _localDatasource.searchProductsOptimized(query);

      log('✅ Local search completed: ${products.length} results');
      return Right(products);
    } catch (e) {
      log('❌ Error in local search: $e');
      return Left('Pencarian lokal gagal: $e');
    }
  }

  // ========================================
  // PRODUCT SYNC OPERATIONS
  // ========================================
  Future<Either<String, String>> syncAllProducts() async {
    try {
      log('🔄 Starting manual sync of all products...');

      int page = 1;
      const limit = 50; // Higher limit for bulk sync
      bool hasMore = true;
      int totalSynced = 0;

      // Clear local data first for fresh sync
      await _localDatasource.clearAllProducts();

      while (hasMore) {
        log('📄 Syncing page $page...');

        final result = await _remoteDatasource.getProducts(
          page: page,
          limit: limit,
        );

        await result.fold(
          (failure) async {
            log('❌ Sync failed at page $page: $failure');
            throw Exception(failure);
          },
          (response) async {
            final products = response.data?.products ?? [];

            if (products.isNotEmpty) {
              await _localDatasource.saveProductsBatch(
                products,
                clearFirst: false, // Don't clear on subsequent pages
              );
              totalSynced += products.length;

              // Check if we have more pages
              hasMore = page < (response.data?.totalPages ?? 0);
              page++;

              log('📦 Page $page synced: ${products.length} products');
            } else {
              hasMore = false;
            }
          },
        );
      }

      final message = 'Berhasil sinkronisasi $totalSynced produk';
      log('✅ $message');
      return Right(message);
    } catch (e) {
      final error = 'Gagal sinkronisasi produk: $e';
      log('❌ $error');
      return Left(error);
    }
  }

  // ========================================
  // LOCAL DATABASE OPERATIONS
  // ========================================

  // Refresh just cleans cache and reloads from local
  Future<Either<String, ProductResponseModel>> refreshProducts({
    String? categoryId,
    String? search,
  }) async {
    log('🔄 Refreshing local products...');

    // Clear cache for fresh local data
    clearCache();

    return await getProducts(
      page: 1,
      limit: 10,
      categoryId: categoryId,
      search: search,
    );
  }

  Future<Product?> getProductById(String id) async {
    log('🔍 Getting product by ID from local: $id');
    return await _localDatasource.getProductById(id);
  }

  Future<bool> hasLocalProducts() async {
    final hasProducts = await _localDatasource.hasProducts();
    log('📊 Has local products: $hasProducts');
    return hasProducts;
  }

  Future<Map<String, dynamic>> getDatabaseStats() async {
    final stats = await _localDatasource.getDatabaseStats();
    log('📊 Database stats: $stats');
    return stats;
  }

  void clearCache() {
    log('🧹 Clearing local cache');
    _localDatasource.clearCache();
  }

  // Helper method to check if local database is populated
  Future<bool> isLocalDatabaseReady() async {
    try {
      final stats = await getDatabaseStats();
      final productCount = stats['total_products'] ?? 0;
      final isReady = productCount > 0;
      log('🔍 Local database ready: $isReady ($productCount products)');
      return isReady;
    } catch (e) {
      log('❌ Error checking database readiness: $e');
      return false;
    }
  }

  Future<void> clearAllProducts() async {
    try {
      log('🗑️ Clearing all products from repository...');
      await _localDatasource.clearAllProducts();
      clearCache();
      log('✅ All products cleared successfully');
    } catch (e) {
      log('❌ Error clearing all products: $e');
      rethrow;
    }
  }
}
