# Reviews API - Quick Reference Guide

## Rating Scale Conversion

### Convert UI Stars to API Rating
```dart
// UI: 5 stars → API: 1.0
final apiRating = stars / 5.0;
```

### Convert API Rating to UI Stars
```dart
// API: 0.8 → UI: 4 stars
final stars = (rating * 5).round();
```

### Helper Functions (in reviews_provider.dart)
```dart
double apiRating = starsToApiRating(5);  // Returns 1.0
int stars = apiRatingToStars(0.8);       // Returns 4
```

---

## Provider Usage

### Get Reviews for Product
```dart
final reviewsAsync = ref.watch(productReviewsProvider(itemId));

reviewsAsync.when(
  data: (reviews) => /* show reviews */,
  loading: () => const CustomLoadingIndicator(),
  error: (error, stack) => /* show error */,
);
```

### Get Average Rating
```dart
final avgRatingAsync = ref.watch(productAverageRatingProvider(itemId));
```

### Get Review Count
```dart
final countAsync = ref.watch(productReviewCountProvider(itemId));
```

### Submit Review
```dart
try {
  final submitUseCase = ref.read(submitReviewProvider);

  await submitUseCase(
    itemId: productId,
    rating: stars / 5.0,  // Convert stars to 0-1
    comment: comment,
  );

  // Refresh reviews
  ref.invalidate(productReviewsProvider(productId));
} catch (e) {
  // Handle error
}
```

### Delete Review
```dart
try {
  final deleteUseCase = ref.read(deleteReviewProvider);

  await deleteUseCase(name: reviewId);

  // Refresh reviews
  ref.invalidate(productReviewsProvider(productId));
} catch (e) {
  // Handle error
}
```

---

## API Endpoints

### Get Reviews
```dart
POST /api/method/building_material.building_material.api.item_feedback.get_list

Body: {
  "limit_page_length": 10,
  "limit_start": 0,
  "item_id": "PRODUCT_ID"
}
```

### Submit Review
```dart
POST /api/method/building_material.building_material.api.item_feedback.update

Body: {
  "item_id": "PRODUCT_ID",
  "rating": 0.8,        // 0-1 scale
  "comment": "Great!",
  "name": "REVIEW_ID"   // Optional, for updates
}
```

### Delete Review
```dart
POST /api/method/building_material.building_material.api.item_feedback.delete

Body: {
  "name": "ITEM-PRODUCT_ID-user@email.com"
}
```

---

## Review Entity

```dart
class Review {
  final String id;              // Review ID
  final String itemId;          // Product code
  final double rating;          // API rating (0-1)
  final String comment;         // Review text
  final String? reviewerName;   // Reviewer name
  final String? reviewerEmail;  // Reviewer email
  final DateTime? reviewDate;   // Review date

  // Convert to stars (0-5)
  int get starsRating => (rating * 5).round();
  double get starsRatingDecimal => rating * 5;
}
```

---

## Error Handling

### Common Exceptions
```dart
try {
  // API call
} on NoInternetException {
  // No internet connection
} on TimeoutException {
  // Request timeout
} on UnauthorizedException {
  // Session expired
} on ValidationException catch (e) {
  // Invalid data: e.message
} on NotFoundException {
  // Review not found
} on ServerException {
  // Server error (5xx)
} catch (e) {
  // Unknown error
}
```

### Status Codes
- **400**: Bad Request - Invalid data
- **401**: Unauthorized - Session expired
- **403**: Forbidden - No permission
- **404**: Not Found - Review doesn't exist
- **409**: Conflict - Review already exists
- **429**: Too Many Requests - Rate limited
- **500+**: Server Error

---

## Validation Rules

### Rating
- Must be 0-1 for API
- Must be 1-5 for UI
- Cannot be empty

### Comment
- Minimum: 20 characters
- Maximum: 1000 characters
- Cannot be empty or whitespace only

---

## Date Formatting

```dart
String _formatDate(DateTime date) {
  final now = DateTime.now();
  final diff = now.difference(date);

  if (diff.inDays == 0) return 'Hôm nay';
  if (diff.inDays == 1) return 'Hôm qua';
  if (diff.inDays < 7) return '${diff.inDays} ngày trước';
  if (diff.inDays < 30) return '${(diff.inDays / 7).floor()} tuần trước';
  if (diff.inDays < 365) return '${(diff.inDays / 30).floor()} tháng trước';
  return '${(diff.inDays / 365).floor()} năm trước';
}
```

---

## Review ID Format

```
ITEM-{item_id}-{user_email}
```

**Examples**:
- `ITEM-GIB20 G04-john@example.com`
- `ITEM-Product123-user@company.com`

---

## Testing Checklist

- [ ] Reviews load correctly
- [ ] Rating conversion works (0-1 ↔ 1-5)
- [ ] Submit review refreshes list
- [ ] Average rating calculates correctly
- [ ] Empty state shows when no reviews
- [ ] Loading state shows during API calls
- [ ] Error messages display correctly
- [ ] Date formatting works
- [ ] Star ratings display correctly
- [ ] Form validation works

---

## Common Issues

### Issue: Reviews not loading
**Solution**: Check auth tokens (sid, csrf_token) are set

### Issue: Rating conversion wrong
**Solution**: Always use `stars / 5.0` for API, `(rating * 5).round()` for UI

### Issue: Reviews not refreshing after submit
**Solution**: Use `ref.invalidate(productReviewsProvider(itemId))`

### Issue: Provider not found error
**Solution**: Run `dart run build_runner build` to generate .g.dart files

---

## File Locations

**Domain**:
- `lib/features/reviews/domain/entities/review.dart`
- `lib/features/reviews/domain/repositories/reviews_repository.dart`
- `lib/features/reviews/domain/usecases/*.dart`

**Data**:
- `lib/features/reviews/data/models/review_model.dart`
- `lib/features/reviews/data/datasources/reviews_remote_datasource.dart`
- `lib/features/reviews/data/repositories/reviews_repository_impl.dart`

**Presentation**:
- `lib/features/reviews/presentation/providers/reviews_provider.dart`

**Updated**:
- `lib/features/products/presentation/widgets/product_detail/product_tabs_section.dart`
- `lib/features/products/presentation/pages/write_review_page.dart`
- `lib/core/constants/api_constants.dart`
