/// Repository Implementation: Price Policy Repository
///
/// Concrete implementation of the PricePolicyRepository interface.
/// Coordinates between local and remote data sources to provide price policy data.
///
/// Currently uses mock data from local datasource.
/// Will implement offline-first strategy when backend API is available.
library;

import 'package:worker/features/price_policy/data/datasources/price_policy_local_datasource.dart';
import 'package:worker/features/price_policy/domain/entities/price_document.dart';
import 'package:worker/features/price_policy/domain/repositories/price_policy_repository.dart';

/// Price Policy Repository Implementation
///
/// Responsibilities:
/// - Coordinate between local cache and remote API (when available)
/// - Convert data models to domain entities
/// - Handle errors gracefully
/// - Manage cache invalidation
class PricePolicyRepositoryImpl implements PricePolicyRepository {
  /// Local data source
  final PricePolicyLocalDataSource localDataSource;

  /// Remote data source (API) - TODO: Add when API is ready
  // final PricePolicyRemoteDataSource remoteDataSource;

  /// Constructor
  PricePolicyRepositoryImpl({
    required this.localDataSource,
    // required this.remoteDataSource, // TODO: Add when API ready
  });

  @override
  Future<List<PriceDocument>> getAllDocuments() async {
    try {
      // TODO: Implement offline-first strategy
      // 1. Check if cache is valid
      // 2. Return cached data if valid
      // 3. If cache invalid, fetch from remote

      // For now, get from local datasource (mock data)
      final models = await localDataSource.getAllDocuments();

      // Convert models to entities
      final entities = models.map((model) => model.toEntity()).toList();

      // Sort by published date (newest first)
      entities.sort((a, b) => b.publishedDate.compareTo(a.publishedDate));

      return entities;
    } catch (e) {
      // Log error and return empty list
      // In production, this should throw proper domain failures
      print('[PricePolicyRepository] Error getting documents: $e');
      return [];
    }
  }

  @override
  Future<List<PriceDocument>> getDocumentsByCategory(
    DocumentCategory category,
  ) async {
    try {
      // Convert category to string for datasource
      final categoryString = _categoryToString(category);

      // Get documents from local datasource
      final models = await localDataSource.getDocumentsByCategory(
        categoryString,
      );

      // Convert models to entities
      final entities = models.map((model) => model.toEntity()).toList();

      // Sort by published date (newest first)
      entities.sort((a, b) => b.publishedDate.compareTo(a.publishedDate));

      return entities;
    } catch (e) {
      print('[PricePolicyRepository] Error getting documents by category: $e');
      return [];
    }
  }

  @override
  Future<PriceDocument?> getDocumentById(String documentId) async {
    try {
      // Get document from local datasource
      final model = await localDataSource.getDocumentById(documentId);

      // Convert model to entity
      return model?.toEntity();
    } catch (e) {
      print('[PricePolicyRepository] Error getting document by id: $e');
      return null;
    }
  }

  @override
  Future<List<PriceDocument>> refreshDocuments() async {
    try {
      // TODO: Implement remote fetch when API is available
      // 1. Fetch from remote API
      // 2. Cache the results locally
      // 3. Return fresh data

      // For now, just clear and refetch from local
      await localDataSource.clearCache();
      final models = await localDataSource.getAllDocuments();

      // Convert models to entities
      final entities = models.map((model) => model.toEntity()).toList();

      // Sort by published date (newest first)
      entities.sort((a, b) => b.publishedDate.compareTo(a.publishedDate));

      return entities;
    } catch (e) {
      print('[PricePolicyRepository] Error refreshing documents: $e');
      return [];
    }
  }

  /// Helper method to convert category enum to string
  String _categoryToString(DocumentCategory category) {
    switch (category) {
      case DocumentCategory.policy:
        return 'policy';
      case DocumentCategory.priceList:
        return 'priceList';
    }
  }
}
