import '../config/app_config.dart';

class Laundry {
  final int id;
  final String nama;
  final String alamat;
  final String? noWhatsapp;
  final double? latitude;
  final double? longitude;
  final double jarakKampus; // jarak ke kampus dalam km
  final String jamBuka;
  final String jamTutup;
  final double hargaPerKg;
  final int waktuProses; // dalam jam
  final String? deskripsi;
  final String? fotoUtama;
  final String? foto; // Field foto dari API
  final List<GaleriLaundry> galeri;
  final double? avgRating;
  final int? totalReviews;
  final String status;

  Laundry({
    required this.id,
    required this.nama,
    required this.alamat,
    this.noWhatsapp,
    this.latitude,
    this.longitude,
    required this.jarakKampus,
    required this.jamBuka,
    required this.jamTutup,
    required this.hargaPerKg,
    required this.waktuProses,
    this.deskripsi,
    this.fotoUtama,
    this.foto,
    this.galeri = const [],
    this.avgRating,
    this.totalReviews,
    required this.status,
  });

  factory Laundry.fromJson(Map<String, dynamic> json) {
    // Try to get jarak from different possible field names
    double jarak = 0;
    if (json['jarak_kampus'] != null) {
      jarak = double.tryParse(json['jarak_kampus'].toString()) ?? 0;
    } else if (json['jarak'] != null) {
      // Backend uses 'jarak' column, convert meters to km
      jarak = (double.tryParse(json['jarak'].toString()) ?? 0) / 1000;
    }

    // Get harga from layanan if harga_per_kg is not set directly
    double harga = 0;
    if (json['harga_per_kg'] != null) {
      harga = double.tryParse(json['harga_per_kg'].toString()) ?? 0;
    } else if (json['layanan'] != null &&
        (json['layanan'] as List).isNotEmpty) {
      final layananList = json['layanan'] as List;
      harga =
          double.tryParse(layananList.first['harga']?.toString() ?? '0') ?? 0;
    }

    // Get foto from API and build gallery list
    final List<GaleriLaundry> galleryList = [];
    
    // Parse galeri array if exists
    if (json['galeri'] != null && (json['galeri'] as List).isNotEmpty) {
      galleryList.addAll(
        (json['galeri'] as List).map((g) => GaleriLaundry.fromJson(g)).toList()
      );
    }
    
    // If gallery is empty but foto field exists, create a galeri item from it
    if (galleryList.isEmpty && json['foto'] != null && json['foto'].toString().isNotEmpty) {
      galleryList.add(
        GaleriLaundry(
          id: json['id'] ?? 0,
          foto: json['foto'].toString(),
          isPrimary: true,
          urutan: 0,
        )
      );
    }

    return Laundry(
      id: json['id'] ?? 0,
      nama: json['nama'] ?? '',
      alamat: json['alamat'] ?? '',
      noWhatsapp: json['no_whatsapp'],
      latitude: json['latitude'] != null
          ? double.tryParse(json['latitude'].toString())
          : null,
      longitude: json['longitude'] != null
          ? double.tryParse(json['longitude'].toString())
          : null,
      jarakKampus: jarak,
      jamBuka: _parseTime(json['jam_buka'], '08:00'),
      jamTutup: _parseTime(json['jam_tutup'], '20:00'),
      hargaPerKg: harga,
      waktuProses: json['waktu_proses'] ?? 24,
      deskripsi: json['deskripsi'],
      fotoUtama: json['foto_utama'],
      foto: json['foto'], // Store raw foto field
      galeri: galleryList,
      avgRating: json['avg_rating'] != null
          ? double.tryParse(json['avg_rating'].toString())
          : null,
      totalReviews: json['total_reviews'],
      status: json['status'] ?? 'buka',
    );
  }

  // Parse time string, stripping seconds if present (e.g. "08:00:00" -> "08:00")
  static String _parseTime(dynamic value, String fallback) {
    if (value == null) return fallback;
    final str = value.toString();
    if (str.length >= 5) return str.substring(0, 5);
    return fallback;
  }

  // Get primary photo URL
  // Prioritize 'foto' field (Admin-set primary photo) over galeri entries,
  // because galeri items may reference files that have been deleted/replaced.
  String get primaryPhoto {
    // 1. Prefer the explicit 'foto' field (most up-to-date primary photo)
    if (foto != null && foto!.isNotEmpty) {
      if (foto!.startsWith('http')) {
        return foto!;
      }
      return '${AppConfig.serverUrl}/uploads/Laundry/$foto';
    }
    // 2. Fall back to galeri items if foto is not set
    if (galeri.isNotEmpty) {
      final primary = galeri.firstWhere(
        (g) => g.isPrimary,
        orElse: () => galeri.first,
      );
      if (primary.foto.isNotEmpty && primary.foto.startsWith('http')) {
        return primary.foto;
      }
      if (primary.foto.isNotEmpty) {
        return '${AppConfig.serverUrl}/uploads/Laundry/${primary.foto}';
      }
    }
    return 'https://via.placeholder.com/300';
  }

  // Format harga dengan Rupiah
  String get formattedHarga {
    return 'Rp ${hargaPerKg.toStringAsFixed(0).replaceAllMapped(RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]}.')}';
  }

  // Legacy getters for backward compatibility
  String get formattedHargaKiloan => formattedHarga;
  String get formattedHargaSatuan => formattedHarga;
  double get hargaKiloan => hargaPerKg;
  double get jarak => jarakKampus; // alias for jarak field
  double get rating => avgRating ?? 0.0;
  String get estimasiSelesai => '$waktuProses jam';

  // Check if currently open
  bool get isOpen {
    if (status != 'buka') return false;

    final now = DateTime.now();
    final currentTime =
        '${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}';

    return currentTime.compareTo(jamBuka) >= 0 &&
        currentTime.compareTo(jamTutup) <= 0;
  }

  // Get status text
  String get statusText {
    if (status == 'tutup') return 'Tutup';
    if (isOpen) return 'Buka';
    return 'Tutup Sementara';
  }
}

class GaleriLaundry {
  final int id;
  final String foto;
  final bool isPrimary;
  final int urutan;

  GaleriLaundry({
    required this.id,
    required this.foto,
    required this.isPrimary,
    required this.urutan,
  });

  factory GaleriLaundry.fromJson(Map<String, dynamic> json) {
    return GaleriLaundry(
      id: json['id'] ?? 0,
      foto: json['foto'] ?? '',
      isPrimary: json['is_primary'] == 1 || json['is_primary'] == true,
      urutan: json['urutan'] ?? 0,
    );
  }

  // Get full photo URL
  String get photoUrl {
    // Check if it's already a full URL
    if (foto.startsWith('http')) {
      return foto;
    }
    // Build full URL from uploads
    return '${AppConfig.serverUrl}/uploads/Laundry/$foto';
  }
}
