import '../core/api/meinweimar_api_client.dart';
import '../core/text/wp_text.dart';
import '../models/partner.dart';
class PartnerRepository {
const PartnerRepository(this.api);
final MeinWeimarApiClient api;
Future<List<Partner>> fetchAll({required String languageCode}) async {
final data = await api.getJson(
'/partners',
query: {'lang': languageCode, 'per_page': '100'},
);
return (data['items'] as List? ?? const [])
.whereType<Map<String, dynamic>>()
.map(_fromJson)
.toList();
}
Future<Partner> fetchOne({
required String id,
required String languageCode,
}) async {
final data = await api.getJson(
'/partners/$id',
query: {'lang': languageCode},
);
return _fromJson(data);
}
Partner _fromJson(Map<String, dynamic> j) {
final loc = j['location'] as Map<String, dynamic>? ?? const {};
final address = j['address'] as Map<String, dynamic>? ?? const {};
final contact = j['contact'] as Map<String, dynamic>? ?? const {};
final gastro = j['gastro'] as Map<String, dynamic>? ?? const {};
final coupon = j['coupon'] as Map<String, dynamic>? ?? const {};
final content = j['content'] as Map<String, dynamic>? ?? const {};
final featured = WpText.url((j['image'] as Map<String, dynamic>?)?['url']);
final gallery = (j['gallery'] as List? ?? const [])
.whereType<Map<String, dynamic>>()
.map((image) => WpText.url(image['url']) ?? '')
.where((url) => url.trim().isNotEmpty && url != featured)
.toSet()
.toList(growable: false);
return Partner(
id: j['id'].toString(),
title: content['title']?.toString().trim().isNotEmpty == true
? WpText.plain(content['title'])
: WpText.plain(j['title']),
latitude: (loc['lat'] as num?)?.toDouble() ?? 0,
longitude: (loc['lng'] as num?)?.toDouble() ?? 0,
imageUrl: featured,
galleryUrls: gallery,
partnerType: j['partner_type']?.toString(),
status: j['partner_status']?.toString(),
sponsored: j['sponsored'] == true,
priority: (j['priority'] as num?)?.toInt() ?? 0,
shortDescription:
content['short_text']?.toString().trim().isNotEmpty == true
? WpText.plain(content['short_text'])
: WpText.nullablePlain(j['short_description']),
description:
content['description_text']?.toString().trim().isNotEmpty == true
? WpText.plain(content['description_text'])
: WpText.nullablePlain(j['description_html']),
address: WpText.nullablePlain(address['formatted']),
openingHours: WpText.nullablePlain(j['opening_hours']),
websiteUrl: WpText.url(contact['website_url']),
bookingUrl: WpText.url(contact['booking_url']),
cuisine: WpText.nullablePlain(gastro['cuisine']),
priceLevel: WpText.nullablePlain(gastro['price_level']),
dayparts: (gastro['dayparts'] as List? ?? const [])
.map((e) => e.toString())
.toList(growable: false),
maxDetourMinutes: (gastro['max_detour_minutes'] as num?)?.toInt(),
goodForShortBreak: gastro['good_for_short_break'] == true,
goodForTourEnd: gastro['good_for_tour_end'] == true,
couponActive: coupon['active'] == true,
couponCode: WpText.nullablePlain(coupon['code']),
couponText: WpText.nullablePlain(coupon['text']),
preferredTourIds: (j['preferred_tour_ids'] as List? ?? const [])
.map((e) => e.toString())
.toList(growable: false),
);
}
}

