import 'package:bluetooth_print/bluetooth_print.dart';
import 'package:bluetooth_print/bluetooth_print_model.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:io';
import 'package:flutter/services.dart';

class BluetoothService {
  late BluetoothPrint _bluetoothPrint;
  BluetoothDevice? _connectedDevice;
  bool _isConnected = false;
  bool _isPrinting = false;

  BluetoothService() {
    _bluetoothPrint = BluetoothPrint.instance;
  }

  // Getter untuk status koneksi
  bool get isConnected => _isConnected;
  bool get isPrinting => _isPrinting;
  BluetoothDevice? get connectedDevice => _connectedDevice;

  /// Inisialisasi Bluetooth printer
  Future<void> initialize() async {
    // Memeriksa status koneksi Bluetooth
    final isConnected = await _bluetoothPrint.isConnected ?? false;
    _isConnected = isConnected;
  }

  /// Memuat device bluetooth yang tersimpan
  Future<void> loadSavedDevice() async {
    final prefs = await SharedPreferences.getInstance();
    final deviceAddress = prefs.getString('bluetooth_device_address');
    final deviceName = prefs.getString('bluetooth_device_name');

    if (deviceAddress != null && deviceName != null) {
      _connectedDevice = BluetoothDevice();
      _connectedDevice!.name = deviceName;
      _connectedDevice!.address = deviceAddress;
    }
  }

  /// Memeriksa status koneksi Bluetooth printer secara real-time
  Future<bool> checkConnection() async {
    try {
      final isConnected = await _bluetoothPrint.isConnected ?? false;
      _isConnected = isConnected;
      return isConnected;
    } on SocketException {
      // Tangani error koneksi secara spesifik
      _isConnected = false;
      return false;
    } catch (e) {
      // Tangani error umum
      _isConnected = false;
      return false;
    }
  }

  /// Menghubungkan ke device bluetooth
  Future<bool> connectToDevice(BluetoothDevice device) async {
    try {
      await _bluetoothPrint.connect(device);
      _connectedDevice = device;
      _isConnected = true;
      
      // Simpan device ke SharedPreferences
      final prefs = await SharedPreferences.getInstance();
      await prefs.setString('bluetooth_device_address', device.address ?? '');
      await prefs.setString('bluetooth_device_name', device.name ?? '');
      
      return true;
    } on SocketException {
      // Tangani error koneksi secara spesifik
      _isConnected = false;
      return false;
    } on PlatformException {
      // Tangani error platform secara spesifik
      _isConnected = false;
      return false;
    } catch (e) {
      // Tangani error umum
      _isConnected = false;
      return false;
    }
  }

  /// Memutuskan koneksi dari device bluetooth
  Future<void> disconnect() async {
    try {
      await _bluetoothPrint.disconnect();
      _isConnected = false;
    } catch (e) {
      rethrow;
    }
  }

  /// Mencetak struk ke printer thermal
  Future<void> printReceipt(Uint8List data) async {
    if (!_isConnected) {
      throw SocketException('Printer tidak terhubung');
    }

    _isPrinting = true;
    try {
      await _bluetoothPrint.printRawData(data);
    } on SocketException {
      // Tangani error koneksi saat mencetak
      _isPrinting = false;
      rethrow;
    } on PlatformException {
      // Tangani error platform saat mencetak
      _isPrinting = false;
      rethrow;
    } catch (e) {
      // Tangani error umum saat mencetak
      _isPrinting = false;
      throw Exception('Gagal mencetak: $e');
    } finally {
      _isPrinting = false;
    }
  }

  /// Mencoba menyambungkan kembali ke printer jika terputus
  Future<bool> reconnectIfNeeded() async {
    // Periksa koneksi printer secara real-time
    bool isConnected = await checkConnection();
    
    if (!isConnected) {
      // Coba sambungkan kembali jika ada device yang tersimpan
      if (_connectedDevice != null) {
        try {
          // Putuskan koneksi yang mungkin tersisa
          try {
            await disconnect();
          } catch (disconnectError) {
            // Tidak ada koneksi yang perlu diputuskan
          }
          
          // Tunggu sebentar sebelum menyambungkan kembali
          await Future.delayed(const Duration(milliseconds: 500));
          
          // Sambungkan kembali
          bool connectResult = await connectToDevice(_connectedDevice!);
          
          if (!connectResult) {
            return false;
          }
          
          // Tunggu sebentar untuk memastikan koneksi stabil
          await Future.delayed(const Duration(milliseconds: 500));
          
          // Periksa koneksi lagi
          isConnected = await checkConnection();
          
          return isConnected;
        } on SocketException {
          // Tangani error koneksi secara spesifik
          return false;
        } on PlatformException {
          // Tangani error platform secara spesifik
          return false;
        } catch (e) {
          // Tangani error umum
          return false;
        }
      } else {
        return false;
      }
    } else {
      return true;
    }
  }

  /// Mendengarkan perubahan status bluetooth
  Stream<dynamic> get state => _bluetoothPrint.state;
}