import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:intl/intl.dart';

class RiwayatController extends GetxController {
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;
  final FirebaseAuth _auth = FirebaseAuth.instance;
  List<Map<String, dynamic>> _wilayahData = [];

  var monthlySummary = <Map<String, dynamic>>[].obs;

  var isLoading = false.obs;
  var dailySummary = <Map<String, dynamic>>[].obs;
  var dailyDetail = <Map<String, dynamic>>[].obs;

  /// 🔹 Ambil data ringkasan resi per hari
  Future<void> fetchResiData({DateTime? start, DateTime? end}) async {
    try {
      isLoading.value = true;
      final user = _auth.currentUser;
      if (user == null) return;
      final userId = user.uid;

      final DateTime now = DateTime.now();
      final DateTime startOfMonth = start ?? DateTime(now.year, now.month, 1);
      final DateTime endOfMonth =
          end ?? DateTime(now.year, now.month + 1, 0, 23, 59, 59);

      final snapshot = await _firestore
          .collection('resis')
          .where('store_id', isEqualTo: userId)
          .where('created_at', isGreaterThanOrEqualTo: startOfMonth)
          .where('created_at', isLessThanOrEqualTo: endOfMonth)
          .get();

      final data = snapshot.docs.map((doc) {
        final resi = doc.data();
        final createdAt = (resi['created_at'] as Timestamp).toDate();
        final tanggalKey = DateFormat('yyyy-MM-dd').format(createdAt);

        return {
          'id': doc.id,
          'tanggalKey': tanggalKey,
          'tanggalAsli': createdAt,
          'pembayaran': resi['pembayaran'] ?? '',
          'total': int.tryParse(resi['total'].toString()) ?? 0,
        };
      }).toList();

      final Map<String, List<Map<String, dynamic>>> grouped = {};
      for (var item in data) {
        grouped.putIfAbsent(item['tanggalKey'], () => []);
        grouped[item['tanggalKey']]!.add(item);
      }

      final List<Map<String, dynamic>> summary = [];
      grouped.forEach((key, list) {
        int total = 0, codCount = 0, nonCodCount = 0, income = 0;

        for (var resi in list) {
          total += 1;
          final totalValue = num.tryParse(resi['total'].toString()) ?? 0;
          income += totalValue.toInt();

          if (resi['pembayaran'].toString().toUpperCase() == 'COD') {
            codCount++;
          } else {
            nonCodCount++;
          }
        }

        final date = DateTime.parse(key);
        summary.add({
          'day': DateFormat('EEEE', 'id_ID').format(date),
          'date': DateFormat('d MMMM yyyy', 'id_ID').format(date),
          'total': total,
          'cod': codCount,
          'nonCod': nonCodCount,
          'income': income,
          'rawDate': date,
        });
      });

      summary.sort((a, b) => b['rawDate'].compareTo(a['rawDate']));
      dailySummary.assignAll(summary);
    } catch (e) {
      print('Error fetching resi data: $e');
      dailySummary.clear();
    } finally {
      isLoading.value = false;
    }
  }

  /// 🔹 Ambil data resi + detail toko berdasarkan tanggal
  Future<void> fetchResiByDate(DateTime selectedDate) async {
    try {
      isLoading.value = true;
      final user = _auth.currentUser;
      if (user == null) return;
      final userId = user.uid;

      final startOfDay =
          DateTime(selectedDate.year, selectedDate.month, selectedDate.day);
      final endOfDay =
          DateTime(selectedDate.year, selectedDate.month, selectedDate.day, 23, 59, 59);

      final snapshot = await _firestore
          .collection('resis')
          .where('store_id', isEqualTo: userId)
          .where('created_at', isGreaterThanOrEqualTo: startOfDay)
          .where('created_at', isLessThanOrEqualTo: endOfDay)
          .get();

      // 🔹 Ambil data resi & data toko
      List<Map<String, dynamic>> results = [];

      for (var doc in snapshot.docs) {
        final data = doc.data();
        final storeId = data['store_id'];

        // ambil data toko
        final storeSnapshot =
            await _firestore.collection('stores').doc(storeId).get();
        final storeData = storeSnapshot.data() ?? {};

        results.add({
          'id': doc.id,
          'no_resi': data['no_resi'] ?? '-',
          'penerima': data['penerima'] ?? '-',
          'alamat': data['alamat'] ?? '-',
          'kota': data['kota'] ?? '-',
          'provinsi': data['provinsi'] ?? '-',
          'barang': data['barang'] ?? '-',
          'pembayaran': data['pembayaran'] ?? '-',
          'total': data['total'] ?? 0,
          'no_wa': data['no_wa'] ?? '-',
          'created_at': (data['created_at'] as Timestamp).toDate(),
          'store': {
            'namaToko': storeData['namaToko'] ?? '-',
            'alamat': storeData['alamat'] ?? '-',
            'noHp': storeData['noHp'] ?? '-',
            'noRegistrasi': storeData['noRegistrasi'] ?? '-',
            'keterangan': storeData['keterangan'] ?? '-',
          }
        });
      }

      dailyDetail.assignAll(results);
    } catch (e) {
      print('Error fetching resi detail: $e');
      dailyDetail.clear();
    } finally {
      isLoading.value = false;
    }
  }


    /// 🔹 Ambil total pendapatan COD & Non COD per tanggal
  Future<Map<String, dynamic>> getPendapatanHarian(DateTime date) async {
    try {
      final user = _auth.currentUser;
      if (user == null) return {};

      final startOfDay = DateTime(date.year, date.month, date.day);
      final endOfDay = DateTime(date.year, date.month, date.day, 23, 59, 59);

      final snapshot = await _firestore
          .collection('resis')
          .where('store_id', isEqualTo: user.uid)
          .where('created_at', isGreaterThanOrEqualTo: startOfDay)
          .where('created_at', isLessThanOrEqualTo: endOfDay)
          .get();

      double codIncome = 0;
      double nonCodIncome = 0;

      for (var doc in snapshot.docs) {
        final data = doc.data();
        final pembayaran = (data['pembayaran'] ?? '').toString().toUpperCase();
        final total = double.tryParse(data['total'].toString()) ?? 0;

        if (pembayaran == 'COD') {
          codIncome += total;
        } else {
          nonCodIncome += total;
        }
      }

      return {
        'cod': codIncome,
        'nonCod': nonCodIncome,
      };
    } catch (e) {
      print('Error getPendapatanHarian: $e');
      return {};
    }
  }

  Map<String, String?> _extractWilayah(String alamat) {
  if (alamat.isEmpty || _wilayahData.isEmpty) {
    return {'kota': null, 'provinsi': null};
  }

  String alamatLower = alamat.toLowerCase();
  String? provinsi;
  String? kota;

  // 🔹 Ambil bagian belakang alamat (lebih akurat)
  List<String> words = alamatLower.split(RegExp(r'\s+'));
  String lastPart = words.length > 5
      ? words.sublist(words.length - 5).join(' ')
      : alamatLower;

  // ==============================
  // 🔹 STEP 1: DETEKSI PROVINSI DULU
  // ==============================
  for (var data in _wilayahData) {
    final prov = data['provinsi']?.toString() ?? '';
    final provLower = prov.toLowerCase();

    if (provLower.isEmpty) continue;

    if (lastPart.contains(provLower) ||
        _similarity(lastPart, provLower) > 0.7 ||
        (provLower.contains('jawa timur') && lastPart.contains('jatim')) ||
        (provLower.contains('jawa tengah') && lastPart.contains('jateng')) ||
        (provLower.contains('jawa barat') && lastPart.contains('jabar')) ||
        (provLower.contains('yogyakarta') && lastPart.contains('diy'))) {
      provinsi = prov;
      break; // 🔥 STOP kalau sudah ketemu
    }
  }

  // ❌ kalau provinsi tidak ketemu → langsung return
  if (provinsi == null) {
    return {'kota': null, 'provinsi': null};
  }

  // ==============================
  // 🔹 STEP 2: CARI KOTA DALAM PROVINSI TERSEBUT
  // ==============================
  final provData = _wilayahData.firstWhere(
    (e) => e['provinsi'] == provinsi,
    orElse: () => {},
  );

  final List kotaList = List.from(provData['kota'] ?? []);

  double bestScore = 0;

  for (var k in kotaList) {
    final kotaNama = k.toString();
    final kotaLower = kotaNama.toLowerCase();

    final kotaBersih =
        kotaLower.replaceAll(RegExp(r'^(kab\.?|kota)\s*'), '').trim();

    double score;

    if (alamatLower.contains(kotaBersih)) {
      score = 0.95;
    } else {
      score = _similarity(lastPart, kotaBersih);
    }

    if (score > bestScore) {
      bestScore = score;
      kota = kotaNama;
    }
  }

  return {
    'kota': kota,
    'provinsi': provinsi,
  };
}

double _similarity(String a, String b) {
  if (a.isEmpty || b.isEmpty) return 0.0;

  final aWords = a.split(' ');
  final bWords = b.split(' ');
  int matches = 0;

  for (var aw in aWords) {
    for (var bw in bWords) {
      if (aw.isNotEmpty && bw.isNotEmpty && aw == bw) matches++;
    }
  }

  return matches / ((aWords.length + bWords.length) / 2);
}

  /// 🔹 Update data resi berdasarkan ID
Future<void> updateResi(String id, Map<String, dynamic> updatedData) async {
  try {
    isLoading.value = true;

    // Pastikan dokumen dengan ID tersebut ada
    final docRef = _firestore.collection('resis').doc(id);
    final snapshot = await docRef.get();

    if (!snapshot.exists) {
      Get.snackbar(
        "Gagal",
        "Data resi tidak ditemukan.",
        snackPosition: SnackPosition.BOTTOM,
        backgroundColor: const Color(0xFFFFCDD2),
        colorText: const Color(0xFFB71C1C),
      );
      return;
    }

    // 🔹 Update data di Firestore
    await docRef.update(updatedData);

    // 🔹 Refresh data setelah update
    if (snapshot.data()?['created_at'] != null) {
      final tanggal = (snapshot.data()!['created_at'] as Timestamp).toDate();
      await fetchResiByDate(tanggal);
    }

    Get.snackbar(
      "Berhasil",
      "Data resi berhasil diperbarui.",
      snackPosition: SnackPosition.BOTTOM,
      backgroundColor: const Color(0xFFC8E6C9),
      colorText: const Color(0xFF1B5E20),
    );
  } catch (e) {
    print("Error update resi: $e");
    Get.snackbar(
      "Error",
      "Terjadi kesalahan saat memperbarui data.",
      snackPosition: SnackPosition.BOTTOM,
      backgroundColor: const Color(0xFFFFCDD2),
      colorText: const Color(0xFFB71C1C),
    );
  } finally {
    isLoading.value = false;
  }
}
// Future<void> updateResi(String id, Map<String, dynamic> updatedData) async {
//   try {
//     isLoading.value = true;

//     final docRef = _firestore.collection('resis').doc(id);
//     final snapshot = await docRef.get();

//     if (!snapshot.exists) {
//       Get.snackbar(
//         "Gagal",
//         "Data resi tidak ditemukan.",
//         snackPosition: SnackPosition.BOTTOM,
//         backgroundColor: const Color(0xFFFFCDD2),
//         colorText: const Color(0xFFB71C1C),
//       );
//       return;
//     }

//     final oldData = snapshot.data()!;

//     // ==============================
//     // 🔥 VALIDASI FIELD KOSONG
//     // ==============================
//     bool isEmpty(String? val) => val == null || val.trim().isEmpty;

//     List<String> missing = [];

//     if (isEmpty(updatedData['penerima'])) missing.add('Penerima');
//     if (isEmpty(updatedData['alamat'])) missing.add('Alamat');
//     if (isEmpty(updatedData['no_wa'])) missing.add('No. WA');
//     if (isEmpty(updatedData['barang'])) missing.add('Barang');
//     if (isEmpty(updatedData['total'])) missing.add('Total');
//     if (isEmpty(updatedData['pembayaran'])) missing.add('Pembayaran');

//     if (missing.isNotEmpty) {
//       Get.snackbar(
//         'Gagal Update',
//         'Field berikut kosong:\n${missing.join(', ')}',
//         backgroundColor: const Color(0xFFFF9800),
//         colorText: Colors.white,
//         snackPosition: SnackPosition.BOTTOM,
//       );
//       return;
//     }

//     // ==============================
//     // 🔥 VALIDASI FORMAT
//     // ==============================

//     // No WA minimal 10 digit angka
//     String noWa =
//         updatedData['no_wa'].toString().replaceAll(RegExp(r'\D'), '');
//     if (noWa.length < 10) {
//       Get.snackbar(
//         'Gagal Update',
//         'No. WA tidak valid!',
//         backgroundColor: const Color(0xFFFF9800),
//         colorText: Colors.white,
//         snackPosition: SnackPosition.BOTTOM,
//       );
//       return;
//     }

//     // Total harus angka
//     String total =
//         updatedData['total'].toString().replaceAll(RegExp(r'\D'), '');
//     if (total.isEmpty || int.tryParse(total) == null) {
//       Get.snackbar(
//         'Gagal Update',
//         'Total harus berupa angka!',
//         backgroundColor: const Color(0xFFFF9800),
//         colorText: Colors.white,
//         snackPosition: SnackPosition.BOTTOM,
//       );
//       return;
//     }

//     // ==============================
//     // 🔥 CEK APAKAH ALAMAT DIUBAH
//     // ==============================
//     final oldAlamat = oldData['alamat'] ?? '';
//     final newAlamat = updatedData['alamat'] ?? '';
// // ==============================
// // 🔥 SELALU DETEKSI ULANG WILAYAH
// // ==============================
// final alamat = updatedData['alamat'].toString().trim();

// final wilayah = _extractWilayah(alamat);

// // ❗ Kalau gagal detect → TOLAK
// if (wilayah['provinsi'] == null || wilayah['kota'] == null) {
//   Get.snackbar(
//     'Gagal Update',
//     'Alamat tidak valid, provinsi/kota tidak terdeteksi!',
//     backgroundColor: const Color(0xFFFF9800),
//     colorText: Colors.white,
//     snackPosition: SnackPosition.BOTTOM,
//   );
//   return;
// }

// // 🔥 SET ULANG
// updatedData['alamat'] = alamat;
// updatedData['kota'] = wilayah['kota'];
// updatedData['provinsi'] = wilayah['provinsi'];

//     // ==============================
//     // 🔥 CLEAN DATA
//     // ==============================
//     updatedData.updateAll((key, value) => value.toString().trim());

//     debugPrint("FINAL UPDATE DATA: $updatedData");

//     // ==============================
//     // 🔹 UPDATE FIRESTORE
//     // ==============================
//     await docRef.update(updatedData);

//     // 🔹 Refresh data
//     if (snapshot.data()?['created_at'] != null) {
//       final tanggal =
//           (snapshot.data()!['created_at'] as Timestamp).toDate();
//       await fetchResiByDate(tanggal);
//     }

//     Get.snackbar(
//       "Berhasil",
//       "Data resi berhasil diperbarui.",
//       snackPosition: SnackPosition.BOTTOM,
//       backgroundColor: const Color(0xFFC8E6C9),
//       colorText: const Color(0xFF1B5E20),
//     );
//   } catch (e) {
//     debugPrint("Error update resi: $e");

//     Get.snackbar(
//       "Error",
//       "Terjadi kesalahan saat memperbarui data.",
//       snackPosition: SnackPosition.BOTTOM,
//       backgroundColor: const Color(0xFFFFCDD2),
//       colorText: const Color(0xFFB71C1C),
//     );
//   } finally {
//     isLoading.value = false;
//   }
// }
Future<void> deleteRiwayat(String id) async {
    try {
      isLoading(true);

      // Hapus dari Firestore
      await _firestore.collection('riwayat_bulanan').doc(id).delete();

      // Hapus juga dari list lokal agar tampilan otomatis ter-update
      monthlySummary.removeWhere((item) => item['id'] == id);

      Get.snackbar(
        "Berhasil",
        "Data berhasil dihapus",
        backgroundColor: const Color(0xFFFFCDD2),
        snackPosition: SnackPosition.BOTTOM,
      );
    } catch (e) {
      Get.snackbar(
        "Error",
        "Gagal menghapus data: $e",
        backgroundColor: const Color(0xFFFFE0B2),
        snackPosition: SnackPosition.BOTTOM,
      );
    } finally {
      isLoading(false);
    }
  }

/// 🔹 Hapus data resi berdasarkan ID dokumen
Future<void> deleteResi(String id) async {
  try {
    isLoading(true);

    // Cek apakah dokumen ada
    final docRef = _firestore.collection('resis').doc(id);
    final snapshot = await docRef.get();

    if (!snapshot.exists) {
      Get.snackbar(
        "Gagal",
        "Data tidak ditemukan atau sudah dihapus.",
        snackPosition: SnackPosition.BOTTOM,
        backgroundColor: const Color(0xFFFFCDD2),
        colorText: const Color(0xFFB71C1C),
      );
      return;
    }

    // 🔹 Hapus dari Firestore
    await docRef.delete();

    // 🔹 Hapus dari list lokal agar tampilan otomatis update
    dailyDetail.removeWhere((item) => item['id'] == id);
    dailySummary.removeWhere((item) => item['id'] == id);

    Get.snackbar(
      "Berhasil",
      "Data berhasil dihapus.",
      snackPosition: SnackPosition.BOTTOM,
      backgroundColor: const Color(0xFFFFEBEE),
      colorText: const Color(0xFFB71C1C),
    );
  } catch (e) {
    Get.snackbar(
      "Error",
      "Gagal menghapus data: $e",
      snackPosition: SnackPosition.BOTTOM,
      backgroundColor: const Color(0xFFFFE0B2),
      colorText: const Color(0xFFBF360C),
    );
  } finally {
    isLoading(false);
  }
}



}
