/// Repository Implementation: News Repository
///
/// Concrete implementation of the NewsRepository interface.
/// Coordinates between local and remote data sources.
library;

import 'package:worker/features/news/data/datasources/news_local_datasource.dart';
import 'package:worker/features/news/data/datasources/news_remote_datasource.dart';
import 'package:worker/features/news/domain/entities/blog_category.dart';
import 'package:worker/features/news/domain/entities/news_article.dart';
import 'package:worker/features/news/domain/repositories/news_repository.dart';

/// News Repository Implementation
class NewsRepositoryImpl implements NewsRepository {

  /// Constructor
  NewsRepositoryImpl({
    required this.localDataSource,
    required this.remoteDataSource,
  });
  /// Local data source
  final NewsLocalDataSource localDataSource;

  /// Remote data source
  final NewsRemoteDataSource remoteDataSource;

  @override
  Future<List<BlogCategory>> getBlogCategories() async {
    try {
      // Fetch categories from remote API
      final models = await remoteDataSource.getBlogCategories();

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

      return entities;
    } catch (e) {
      print('[NewsRepository] Error getting blog categories: $e');
      rethrow; // Re-throw to let providers handle the error
    }
  }

  @override
  Future<List<NewsArticle>> getAllArticles() async {
    try {
      final models = await localDataSource.getAllArticles();
      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('[NewsRepository] Error getting articles: $e');
      return [];
    }
  }

  @override
  Future<NewsArticle?> getFeaturedArticle() async {
    try {
      final model = await localDataSource.getFeaturedArticle();
      return model?.toEntity();
    } catch (e) {
      print('[NewsRepository] Error getting featured article: $e');
      return null;
    }
  }

  @override
  Future<List<NewsArticle>> getArticlesByCategory(NewsCategory category) async {
    try {
      final categoryString = category.filterName;
      final models = await localDataSource.getArticlesByCategory(
        categoryString,
      );

      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('[NewsRepository] Error getting articles by category: $e');
      return [];
    }
  }

  @override
  Future<NewsArticle?> getArticleById(String articleId) async {
    try {
      final model = await localDataSource.getArticleById(articleId);
      return model?.toEntity();
    } catch (e) {
      print('[NewsRepository] Error getting article by id: $e');
      return null;
    }
  }

  @override
  Future<NewsArticle?> getArticleByIdFromApi(String articleId) async {
    try {
      // Fetch blog post detail from Frappe API using frappe.client.get
      final blogPostModel = await remoteDataSource.getBlogPostDetail(articleId);

      // Convert to domain entity
      return blogPostModel.toEntity();
    } catch (e) {
      print('[NewsRepository] Error getting article by id from API: $e');
      rethrow; // Re-throw to let providers handle the error
    }
  }

  @override
  Future<List<NewsArticle>> refreshArticles() async {
    try {
      await localDataSource.clearCache();
      return getAllArticles();
    } catch (e) {
      print('[NewsRepository] Error refreshing articles: $e');
      return [];
    }
  }
}
