/// Providers: Reviews
///
/// Riverpod providers for review management.
library;

import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:worker/core/network/dio_client.dart';
import 'package:worker/features/reviews/data/datasources/reviews_remote_datasource.dart';
import 'package:worker/features/reviews/data/repositories/reviews_repository_impl.dart';
import 'package:worker/features/reviews/domain/entities/review.dart';
import 'package:worker/features/reviews/domain/entities/review_statistics.dart';
import 'package:worker/features/reviews/domain/repositories/reviews_repository.dart';
import 'package:worker/features/reviews/domain/usecases/delete_review.dart';
import 'package:worker/features/reviews/domain/usecases/get_product_reviews.dart';
import 'package:worker/features/reviews/domain/usecases/submit_review.dart';

part 'reviews_provider.g.dart';

// ============================================================================
// Data Layer Providers
// ============================================================================

/// Provider for reviews remote data source
@riverpod
Future<ReviewsRemoteDataSource> reviewsRemoteDataSource(
  Ref ref,
) async {
  final dioClient = await ref.watch(dioClientProvider.future);
  return ReviewsRemoteDataSourceImpl(dioClient);
}

/// Provider for reviews repository
@riverpod
Future<ReviewsRepository> reviewsRepository(Ref ref) async {
  final remoteDataSource = await ref.watch(reviewsRemoteDataSourceProvider.future);
  return ReviewsRepositoryImpl(remoteDataSource);
}

// ============================================================================
// Use Case Providers
// ============================================================================

/// Provider for get product reviews use case
@riverpod
Future<GetProductReviews> getProductReviews(Ref ref) async {
  final repository = await ref.watch(reviewsRepositoryProvider.future);
  return GetProductReviews(repository);
}

/// Provider for submit review use case
@riverpod
Future<SubmitReview> submitReview(Ref ref) async {
  final repository = await ref.watch(reviewsRepositoryProvider.future);
  return SubmitReview(repository);
}

/// Provider for delete review use case
@riverpod
Future<DeleteReview> deleteReview(Ref ref) async {
  final repository = await ref.watch(reviewsRepositoryProvider.future);
  return DeleteReview(repository);
}

// ============================================================================
// State Providers
// ============================================================================

/// Provider for fetching reviews for a specific product
///
/// This is a family provider that takes a product ID and returns
/// the list of reviews for that product.
///
/// Usage:
/// ```dart
/// final reviewsAsync = ref.watch(productReviewsProvider('PRODUCT_ID'));
/// ```
@riverpod
Future<List<Review>> productReviews(
    Ref ref,
  String itemId,
) async {
  final getProductReviewsUseCase = await ref.watch(getProductReviewsProvider.future);

  return await getProductReviewsUseCase(
    itemId: itemId,
    limitPageLength: 50, // Fetch more reviews
    limitStart: 0,
  );
}

/// Provider for review statistics (from API)
///
/// Gets statistics directly from API including:
/// - Total feedback count
/// - Average rating (0-5 scale, already calculated by server)
///
/// This is more efficient than calculating client-side
@riverpod
Future<ReviewStatistics> productReviewStatistics(
  Ref ref,
  String itemId,
) async {
  final repository = await ref.watch(reviewsRepositoryProvider.future);
  return await repository.getProductReviewStatistics(itemId: itemId);
}

/// Provider for average rating (convenience wrapper)
///
/// Gets the average rating from API statistics
/// Returns 0.0 if there are no reviews.
@riverpod
Future<double> productAverageRating(
    Ref ref,
  String itemId,
) async {
  final stats = await ref.watch(productReviewStatisticsProvider(itemId).future);
  return stats.averageRating;
}

/// Provider for counting reviews (convenience wrapper)
///
/// Gets the total count from API statistics
@riverpod
Future<int> productReviewCount(
    Ref ref,
  String itemId,
) async {
  final stats = await ref.watch(productReviewStatisticsProvider(itemId).future);
  return stats.totalFeedback;
}

/// Provider for checking if user can submit a review
///
/// This can be extended to check if user has already reviewed
/// the product and enforce one-review-per-user policy.
///
/// For now, it always returns true.
@riverpod
Future<bool> canSubmitReview(
    Ref ref,
  String itemId,
) async {
  // TODO: Implement logic to check if user already reviewed this product
  // This would require user email from auth state
  return true;
}

// ============================================================================
// Helper Functions
// ============================================================================

/// Convert star rating (1-5) to API rating (0-1)
///
/// Example:
/// - 1 star = 0.2
/// - 2 stars = 0.4
/// - 3 stars = 0.6
/// - 4 stars = 0.8
/// - 5 stars = 1.0
double starsToApiRating(int stars) {
  if (stars < 1 || stars > 5) {
    throw ArgumentError('Stars must be between 1 and 5. Got: $stars');
  }
  return stars / 5.0;
}

/// Convert API rating (0-1) to star rating (1-5)
///
/// Example:
/// - 0.2 = 1 star
/// - 0.5 = 2.5 stars (rounded to 3)
/// - 1.0 = 5 stars
int apiRatingToStars(double rating) {
  if (rating < 0 || rating > 1) {
    throw ArgumentError('Rating must be between 0 and 1. Got: $rating');
  }
  return (rating * 5).round();
}
