import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_esc_pos_network/flutter_esc_pos_network.dart';
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
import 'package:enaklo_pos/data/models/response/print_model.dart';

class PrinterService {
  static final PrinterService _instance = PrinterService._internal();
  factory PrinterService() => _instance;
  PrinterService._internal();

  /// Connect to Bluetooth printer
  Future<bool> connectBluetoothPrinter(String macAddress) async {
    try {
      // Check if already connected
      bool isConnected = await PrintBluetoothThermal.connectionStatus;
      if (isConnected) {
        log("Already connected to Bluetooth printer");
        return true;
      }

      // Connect to the printer
      bool connected = await PrintBluetoothThermal.connect(
          macPrinterAddress: macAddress);
      
      if (connected) {
        log("Successfully connected to Bluetooth printer: $macAddress");
      } else {
        log("Failed to connect to Bluetooth printer: $macAddress");
      }
      
      return connected;
    } catch (e) {
      log("Error connecting to Bluetooth printer: $e");
      return false;
    }
  }

  /// Print using Bluetooth printer
  Future<bool> printBluetooth(List<int> printData) async {
    try {
      bool isConnected = await PrintBluetoothThermal.connectionStatus;
      if (!isConnected) {
        log("Not connected to Bluetooth printer");
        return false;
      }

      bool printResult = await PrintBluetoothThermal.writeBytes(printData);
      if (printResult) {
        log("Successfully printed via Bluetooth");
      } else {
        log("Failed to print via Bluetooth");
      }
      
      return printResult;
    } catch (e) {
      log("Error printing via Bluetooth: $e");
      return false;
    }
  }

  /// Print using Network printer
  Future<bool> printNetwork(String ipAddress, List<int> printData) async {
    try {
      final printer = PrinterNetworkManager(ipAddress);
      PosPrintResult connect = await printer.connect();
      
      if (connect == PosPrintResult.success) {
        PosPrintResult printing = await printer.printTicket(printData);
        printer.disconnect();
        
        if (printing == PosPrintResult.success) {
          log("Successfully printed via Network printer: $ipAddress");
          return true;
        } else {
          log("Failed to print via Network printer: ${printing.msg}");
          return false;
        }
      } else {
        log("Failed to connect to Network printer: ${connect.msg}");
        return false;
      }
    } catch (e) {
      log("Error printing via Network: $e");
      return false;
    }
  }

  /// Print with automatic printer type detection
  Future<bool> printWithPrinter(PrintModel printer, List<int> printData, BuildContext context) async {
    try {
      if (printer.type == 'Bluetooth') {
        bool connected = await connectBluetoothPrinter(printer.address);
        if (!connected) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Failed to connect to ${printer.name}')),
          );
          return false;
        }
        
        bool printResult = await printBluetooth(printData);
        if (!printResult) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Failed to print to ${printer.name}')),
          );
        }
        return printResult;
      } else {
        bool printResult = await printNetwork(printer.address, printData);
        if (!printResult) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Failed to print to ${printer.name}')),
          );
        }
        return printResult;
      }
    } catch (e) {
      log("Error printing with printer ${printer.name}: $e");
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Error printing to ${printer.name}: $e')),
      );
      return false;
    }
  }

  /// Disconnect from Bluetooth printer
  Future<bool> disconnectBluetooth() async {
    try {
      bool result = await PrintBluetoothThermal.disconnect;
      log("Bluetooth printer disconnected: $result");
      return result;
    } catch (e) {
      log("Error disconnecting Bluetooth printer: $e");
      return false;
    }
  }

  /// Check if Bluetooth is enabled
  Future<bool> isBluetoothEnabled() async {
    try {
      return await PrintBluetoothThermal.bluetoothEnabled;
    } catch (e) {
      log("Error checking Bluetooth status: $e");
      return false;
    }
  }

  /// Get paired Bluetooth devices
  Future<List<BluetoothInfo>> getPairedBluetoothDevices() async {
    try {
      return await PrintBluetoothThermal.pairedBluetooths;
    } catch (e) {
      log("Error getting paired Bluetooth devices: $e");
      return [];
    }
  }
} 