import '../../core/api/api_client.dart';

class PublicApi {
  PublicApi(this._client);

  final ApiClient _client;

  Future<List<Map<String, dynamic>>> discover({
    String? city,
    String? q,
    double? minRating,
    String? sort,
    List<String>? themes,
    List<String>? vibes,
    List<String>? occasions,
    List<String>? spaceFeatures,
    String? noise,
    String? priceTier,
    String? size,
    bool openNow = false,
  }) async {
    final params = <String, String>{};
    if (city != null && city.isNotEmpty) params['city'] = city;
    if (q != null && q.isNotEmpty) params['q'] = q;
    if (minRating != null) params['minRating'] = minRating.toString();
    if (sort != null && sort.isNotEmpty) params['sort'] = sort;
    if (themes != null && themes.isNotEmpty) params['themes'] = themes.join(',');
    if (vibes != null && vibes.isNotEmpty) params['vibes'] = vibes.join(',');
    if (occasions != null && occasions.isNotEmpty) params['occasions'] = occasions.join(',');
    if (spaceFeatures != null && spaceFeatures.isNotEmpty) params['spaceFeatures'] = spaceFeatures.join(',');
    if (noise != null && noise.isNotEmpty) params['noise'] = noise;
    if (priceTier != null && priceTier.isNotEmpty) params['priceTier'] = priceTier;
    if (size != null && size.isNotEmpty) params['size'] = size;
    if (openNow) params['openNow'] = 'true';
    final res = await _client.dio.get<Map<String, dynamic>>(
      '/api/public/discover',
      queryParameters: params.isEmpty ? null : params,
    );
    final list = res.data?['data'] as List<dynamic>? ?? [];
    return list.cast<Map<String, dynamic>>();
  }

  /// Cafés near a coordinate, sorted by distance (for "near me").
  Future<List<Map<String, dynamic>>> discoverNearby({
    required double lat,
    required double lng,
    String? excludeSlug,
    int limit = 12,
  }) async {
    final res = await _client.dio.get<Map<String, dynamic>>(
      '/api/public/discover/near',
      queryParameters: {
        'lat': lat,
        'lng': lng,
        if (excludeSlug != null && excludeSlug.isNotEmpty) 'excludeSlug': excludeSlug,
        'limit': limit,
      },
    );
    final list = res.data?['data'] as List<dynamic>? ?? [];
    return list.cast<Map<String, dynamic>>();
  }

  /// Parse a free-text query into structured discovery hints (themes/vibes/...).
  Future<Map<String, dynamic>?> nlpParse(String q) async {
    final res = await _client.dio.get<Map<String, dynamic>>(
      '/api/public/discover/nlp-parse',
      queryParameters: {'q': q},
    );
    return res.data?['data'] as Map<String, dynamic>?;
  }

  /// The discovery taxonomy (available themes, vibes, occasions, space features).
  Future<Map<String, dynamic>?> discoverTaxonomy() async {
    final res = await _client.dio.get<Map<String, dynamic>>(
      '/api/public/discover-profile/taxonomy',
    );
    return res.data?['data'] as Map<String, dynamic>?;
  }

  Future<List<Map<String, dynamic>>> getReviews(String slug, {int page = 1}) async {
    final res = await _client.dio.get<Map<String, dynamic>>(
      '/api/public/cafes/$slug/reviews',
      queryParameters: {'page': page, 'pageSize': 20},
    );
    final list = res.data?['data'] as List<dynamic>? ?? [];
    return list.cast<Map<String, dynamic>>();
  }

  Future<Map<String, dynamic>?> createReview(
    String slug, {
    required String authorName,
    required int rating,
    String? comment,
    String? authorPhone,
  }) async {
    final res = await _client.dio.post<Map<String, dynamic>>(
      '/api/public/cafes/$slug/reviews',
      data: {
        'authorName': authorName,
        'rating': rating,
        if (comment != null && comment.isNotEmpty) 'comment': comment,
        if (authorPhone != null && authorPhone.isNotEmpty) 'authorPhone': authorPhone,
      },
    );
    return res.data?['data'] as Map<String, dynamic>?;
  }

  Future<Map<String, dynamic>?> getCafe(String slug) async {
    final res = await _client.dio.get<Map<String, dynamic>>('/api/public/cafes/$slug');
    return res.data?['data'] as Map<String, dynamic>?;
  }

  Future<Map<String, dynamic>?> getMenu(String slug) async {
    final res = await _client.dio.get<Map<String, dynamic>>('/api/public/cafes/$slug/menu');
    return res.data?['data'] as Map<String, dynamic>?;
  }

  Future<Map<String, dynamic>?> resolveQr(String qrCode) async {
    final res = await _client.dio.get<Map<String, dynamic>>('/api/q/$qrCode');
    return res.data?['data'] as Map<String, dynamic>?;
  }

  Future<Map<String, dynamic>?> placeOrder(
    String slug, {
    required String? tableId,
    required List<Map<String, dynamic>> items,
    String? guestPhone,
    String? guestName,
  }) async {
    final res = await _client.dio.post<Map<String, dynamic>>(
      '/api/public/cafes/$slug/orders',
      data: {
        'orderType': 'DineIn',
        if (tableId != null) 'tableId': tableId,
        if (guestPhone != null) 'guestPhone': guestPhone,
        if (guestName != null) 'guestName': guestName,
        'items': items,
      },
    );
    return res.data?['data'] as Map<String, dynamic>?;
  }

  Future<Map<String, dynamic>?> trackOrder(String orderId) async {
    final res = await _client.dio.get<Map<String, dynamic>>('/api/public/orders/$orderId/track');
    return res.data?['data'] as Map<String, dynamic>?;
  }

  Future<Map<String, dynamic>?> createReservation(
    String slug, {
    required String guestName,
    required String guestPhone,
    required String date,
    required String time,
    required int partySize,
    String? notes,
  }) async {
    final res = await _client.dio.post<Map<String, dynamic>>(
      '/api/public/cafes/$slug/reservations',
      data: {
        'guestName': guestName,
        'guestPhone': guestPhone,
        'date': date,
        'time': time,
        'partySize': partySize,
        if (notes != null) 'notes': notes,
      },
    );
    return res.data?['data'] as Map<String, dynamic>?;
  }
}
