import 'dart:convert';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:get/get.dart';
import 'package:praresi/presentation/controllers/internet_controller.dart';

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

  var isSaving = false.obs; // ✅ loading save

  @override
  void onInit() {
    super.onInit();
    _loadWilayahData();
  }

  /// 🔹 Muat data provinsi & kota dari JSON lokal
  Future<void> _loadWilayahData() async {
    try {
      final String jsonString = await rootBundle.loadString('assets/data/regions.json');
      final List<dynamic> jsonData = jsonDecode(jsonString);
      _wilayahData = jsonData.cast<Map<String, dynamic>>();
    } catch (e) {
      debugPrint("Gagal memuat data wilayah: $e");
    }
  }

  /// 🔹 Deteksi provinsi & kota dari alamat (prioritaskan akhir alamat + fuzzy + aman)
// Map<String, String?> _extractWilayah(String alamat) {
//   if (alamat.isEmpty || _wilayahData.isEmpty) {
//     return {'kota': null, 'provinsi': null};
//   }

//   String alamatLower = alamat.toLowerCase();
//   String? provinsi;
//   String? kota;
//   double bestScore = 0.0;

//   // Ambil 4 kata terakhir, karena umumnya di situ ada kota/provinsi
//   List<String> alamatWords = alamatLower.split(RegExp(r'\s+'));
//   String lastPart = alamatWords.length > 4
//       ? alamatWords.sublist(alamatWords.length - 4).join(' ')
//       : alamatLower;

//   for (var data in _wilayahData) {
//     if (data['provinsi'] == null || data['kota'] == null) continue;

//     final String prov = data['provinsi'].toString();
//     final List kotaList = List.from(data['kota']);
//     final String provLower = prov.toLowerCase();

//     // 🔹 Deteksi provinsi langsung atau pakai fuzzy matching
//     if (lastPart.contains(provLower)) {
//       provinsi = prov;
//     } else if (_similarity(lastPart, provLower) > 0.7) {
//       provinsi = prov;
//     } else {
//       // Cek singkatan umum provinsi
//       if (provLower.contains('jawa timur') && lastPart.contains('jatim')) provinsi = prov;
//       if (provLower.contains('jawa tengah') && lastPart.contains('jateng')) provinsi = prov;
//       if (provLower.contains('jawa barat') && lastPart.contains('jabar')) provinsi = prov;
//       if (provLower.contains('daerah istimewa yogyakarta') && lastPart.contains('diy')) provinsi = prov;
//     }

//     // 🔹 Deteksi kota
//     for (var k in kotaList) {
//       if (k == null) continue;
//       final String kotaNama = k.toString();
//       final String kotaLower = kotaNama.toLowerCase();
//       final String kotaBersih = kotaLower.replaceAll(RegExp(r'^(kab\.?|kota)\s*'), '').trim();

//       // Hindari error: pastikan index valid
//       int indexKota = alamatLower.contains(kotaBersih)
//           ? alamatLower.lastIndexOf(kotaBersih)
//           : -1;

//       // Semakin ke akhir alamat, bobot lebih tinggi
//       double weight = (indexKota > 0)
//           ? (indexKota / alamatLower.length).clamp(0.0, 1.0)
//           : 0.0;

//       // Skor kemiripan
//       double score;
//       if (alamatLower.contains(kotaBersih)) {
//         score = 0.9 + weight * 0.1;
//       } else {
//         score = _similarity(lastPart, kotaBersih) + weight * 0.1;
//       }

//       // Simpan hasil terbaik
//       if (score > bestScore) {
//         bestScore = score;
//         kota = kotaNama;
//         provinsi ??= prov;
//       }
//     }
//   }

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

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;
  }
}

// 🔥 Tambahan penting di sini
if (bestScore < 0.75) {
  kota = null;
}

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

/// 🔹 Fungsi bantu: fuzzy similarity sederhana antar string
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);
}

  /// 🔹 Ekstrak data dari hasil OCR
Map<String, dynamic> parseResiData(String text, String storeId) {
  final lines = text.split('\n').map((e) => e.trim()).where((e) => e.isNotEmpty).toList();

  final RegExp penerimaExp = RegExp(r'Penerima\s*:\s*(.*)', caseSensitive: false);
  final RegExp alamatExp = RegExp(r'Alamat\s*:\s*(.*)', caseSensitive: false);
  final RegExp waExp = RegExp(r'(No\.?\s*Wa|Nomor\s*Wa|WA)\s*:\s*(.*)', caseSensitive: false);
  final RegExp barangExp = RegExp(r'Barang\s*:\s*(.*)', caseSensitive: false);
  final RegExp totalExp = RegExp(r'Total\s*:\s*([0-9.,]+)', caseSensitive: false);
  final RegExp pembayaranExp = RegExp(r'(COD|Non\s*COD)', caseSensitive: false);

  String penerima = '';
  String alamat = '';
  String noWa = '';
  String barang = '';
  String total = '';
  String pembayaran = '';

  bool inAlamatSection = false;

  for (int i = 0; i < lines.length; i++) {
    final line = lines[i];

    if (penerimaExp.hasMatch(line)) {
      penerima = penerimaExp.firstMatch(line)?.group(1)?.trim() ?? '';
    } 
    else if (alamatExp.hasMatch(line)) {
      // mulai tangkap alamat
      alamat = alamatExp.firstMatch(line)?.group(1)?.trim() ?? '';
      inAlamatSection = true;
      continue;
    } 
    else if (waExp.hasMatch(line)) {
      inAlamatSection = false;
      noWa = waExp.firstMatch(line)?.group(2)?.trim() ?? '';
    } 
    else if (barangExp.hasMatch(line)) {
      inAlamatSection = false;
      barang = barangExp.firstMatch(line)?.group(1)?.trim() ?? '';
    } 
    else if (totalExp.hasMatch(line)) {
      inAlamatSection = false;
      total = totalExp.firstMatch(line)?.group(1)?.trim() ?? '';
      total = total.replaceAll(RegExp(r'[^\d]'), '');
    } 
    else if (pembayaranExp.hasMatch(line)) {
      inAlamatSection = false;
      pembayaran = pembayaranExp.firstMatch(line)?.group(1)?.trim().toUpperCase() ?? '';
      if (pembayaran.contains('NON')) {
        pembayaran = 'NON COD';
      } else {
        pembayaran = 'COD';
      }
    }
    else if (inAlamatSection) {
      // gabungkan baris tambahan alamat
      if (line.isNotEmpty && !line.contains(':')) {
        alamat += ' $line';
      }
    }
  }

  // 🔍 Ekstrak kota & provinsi dari alamat lengkap
  final wilayah = _extractWilayah(alamat);

  return {
    'store_id': storeId,
    'penerima': penerima,
    'alamat': alamat,
    'no_wa': noWa,
    'barang': barang,
    'total': total,
    'pembayaran': pembayaran, 
    'kota': wilayah['kota'],
    'provinsi': wilayah['provinsi'],
    'created_at': FieldValue.serverTimestamp(),
  };
}

/// 🔹 Simpan hasil OCR ke Firestore
Future<void> saveResi(String ocrText, String userId) async {
  try {
    final storeRef =
        await _firestore.collection('stores').doc(userId).get();

    // 🔹 Cek apakah user punya toko
    if (!storeRef.exists) {
      Get.snackbar(
        'Gagal Menyimpan',
        'Kamu belum memiliki data toko.\nSilakan isi data toko terlebih dahulu.',
        backgroundColor: const Color(0xFFFF9800),
        colorText: Colors.white,
        snackPosition: SnackPosition.BOTTOM,
      );
      return;
    }

    final storeId = storeRef.id;

    // 🔹 Parsing hasil OCR
    final data = parseResiData(ocrText, storeId);

    // 🔹 Validasi field utama
    List<String> missing = [];

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

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

    // 🔥 VALIDASI WILAYAH (INI YANG KAMU BUTUHKAN)
    if (data['provinsi'] == null ||
        data['provinsi'].toString().isEmpty) {
      Get.snackbar(
        'Gagal Menyimpan',
        'Provinsi tidak terdeteksi dari alamat!',
        backgroundColor: const Color(0xFFFF9800),
        colorText: Colors.white,
        snackPosition: SnackPosition.BOTTOM,
      );
      return;
    }

    if (data['kota'] == null ||
        data['kota'].toString().isEmpty) {
      Get.snackbar(
        'Gagal Menyimpan',
        'Kota/Kabupaten tidak terdeteksi!',
        backgroundColor: const Color(0xFFFF9800),
        colorText: Colors.white,
        snackPosition: SnackPosition.BOTTOM,
      );
      return;
    }

    // 🔹 Simpan ke Firestore
    await _firestore.collection('resis').add(data);

    Get.snackbar(
      'Berhasil',
      'Data resi berhasil disimpan!',
      backgroundColor: const Color(0xFF4CAF50),
      colorText: Colors.white,
      snackPosition: SnackPosition.BOTTOM,
    );
  } catch (e) {
    Get.snackbar(
      'Error',
      'Gagal menyimpan data: $e',
      backgroundColor: const Color(0xFFF44336),
      colorText: Colors.white,
      snackPosition: SnackPosition.BOTTOM,
    );
  }
}

// Future<void> saveResi(String ocrText, String userId) async {

//   /// ✅ cegah double klik
//   if (isSaving.value) return;

//   /// ✅ CEK INTERNET GLOBAL
//   final internet = Get.find<InternetController>();

//   if (!internet.isConnected.value) {
//     Get.snackbar(
//       'Offline',
//       'Tidak dapat menyimpan tanpa koneksi internet.',
//       backgroundColor: const Color(0xFFFF9800),
//       colorText: Colors.white,
//       snackPosition: SnackPosition.BOTTOM,
//     );
//     return;
//   }

//   try {
//     isSaving.value = true;

//     final storeRef =
//         await _firestore.collection('stores').doc(userId).get();

//     if (!storeRef.exists) {
//       Get.snackbar(
//         'Gagal Menyimpan',
//         'Kamu belum memiliki data toko.\nSilakan isi data toko terlebih dahulu.',
//         backgroundColor: const Color(0xFFFF9800),
//         colorText: Colors.white,
//         snackPosition: SnackPosition.BOTTOM,
//       );
//       return;
//     }

//     final storeId = storeRef.id;
//     final data = parseResiData(ocrText, storeId);

//     /// ===============================
//     /// VALIDASI FIELD OCR
//     /// ===============================
//     List<String> missing = [];

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

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

//     /// ===============================
//     /// ✅ ANTI DUPLICATE FIRESTORE
//     /// ===============================

//     /// buat document id unik dari data resi
//     final docId =
//         "${data['no_wa']}_${data['total']}_${data['penerima']}";

//     await _firestore
//         .collection('resis')
//         .doc(docId)
//         .set(data); // ✅ BUKAN add()

//     Get.snackbar(
//       'Berhasil',
//       'Data resi berhasil disimpan!',
//       backgroundColor: const Color(0xFF4CAF50),
//       colorText: Colors.white,
//       snackPosition: SnackPosition.BOTTOM,
//     );

//   } on FirebaseException catch (e) {

//     /// ✅ HANDLE INTERNET PUTUS TENGAH JALAN
//     if (e.code == 'network-request-failed') {
//       Get.snackbar(
//         'Koneksi Terputus',
//         'Internet tidak stabil.',
//         backgroundColor: const Color(0xFFFF9800),
//         colorText: Colors.white,
//         snackPosition: SnackPosition.BOTTOM,
//       );
//     } else {
//       Get.snackbar(
//         'Error Firebase',
//         e.message ?? 'Terjadi kesalahan.',
//         backgroundColor: const Color(0xFFF44336),
//         colorText: Colors.white,
//         snackPosition: SnackPosition.BOTTOM,
//       );
//     }

//   } catch (e) {

//     Get.snackbar(
//       'Error',
//       'Gagal menyimpan data.',
//       backgroundColor: const Color(0xFFF44336),
//       colorText: Colors.white,
//       snackPosition: SnackPosition.BOTTOM,
//     );

//   } finally {

//     /// ✅ aktifkan button kembali
//     isSaving.value = false;
//   }
// }

}