/**
 * Print Label Hook
 * Handles printing labels for inventory items
 * Uses real-time printer detection from print service (no localStorage caching)
 */

import { useState, useCallback } from 'react';
import { useMutation } from '@tanstack/react-query';
import { labelPrintingAPI } from '@/lib/api/labelPrinting';
import { printZPL, getAvailablePrinters } from '@/lib/utils/printerClient';
import toast from 'react-hot-toast';

export function usePrintLabel() {
  // Store selected printer NAME (canonical identifier)
  const [selectedPrinterName, setSelectedPrinterName] = useState(null);

  const handleSetSelectedPrinterName = useCallback((printerName) => {
    setSelectedPrinterName(printerName);
  }, []);

  const printLabelMutation = useMutation({
    mutationFn: async ({ inventoryItemId, productId, sampleUID, printerName, zplData: zplDataOverride }) => {
      const printers = await getAvailablePrinters();

      if (!printers || printers.length === 0) {
        throw new Error(
          'No printers available. Please ensure the print service is running and a label printer is connected.'
        );
      }

      // Resolve target printer name
      const targetPrinterName =
        printerName ||
        selectedPrinterName ||
        printers[0]?.name;

      if (!targetPrinterName) {
        throw new Error('No printer selected. Please select a printer first.');
      }

      // Find printer with case-insensitive matching (Windows printer names may vary in case)
      const printer = printers.find(
        (p) => p.name?.toLowerCase() === targetPrinterName.toLowerCase()
      ) || printers.find(
        (p) => p.name?.toLowerCase().includes(targetPrinterName.toLowerCase()) ||
               targetPrinterName.toLowerCase().includes(p.name?.toLowerCase())
      );

      if (!printer) {
        throw new Error(
          `Selected printer "${targetPrinterName}" not found. Available printers: ${printers
            .map((p) => p.name)
            .join(', ')}`
        );
      }

      // Use the exact printer name from the service (case-sensitive for Windows API)
      const exactPrinterName = printer.name;

      // Printer properties
      const printerDpi = printer.dpi || 203;
      const labelLength = 2.5;
      // Use a safer default width (4") to avoid content touching label edges
      const labelWidth = 4;

      // Fetch ZPL unless an override was provided (e.g. batch pre-generated ZPL)
      let zplData = zplDataOverride;
      if (!zplData) {
        let zplResponse;
        if (inventoryItemId) {
          zplResponse = await labelPrintingAPI.getInventoryItemLabelZPL(
            inventoryItemId,
            { dpi: printerDpi, labelLength, labelWidth }
          );
        } else if (productId) {
          zplResponse = await labelPrintingAPI.getProductLabelZPL(
            productId,
            sampleUID,
            { dpi: printerDpi, labelLength, labelWidth }
          );
        } else {
          throw new Error('Either inventory item ID or product ID is required');
        }

        // Standardized backend response (via apiClient): { success, message, data: { zplData, productName, uid } }
        // apiClient already returns `response.data`, so `zplResponse` is this object directly.
        zplData = zplResponse?.data?.zplData;

        if (!zplData || typeof zplData !== 'string') {
          console.error('Invalid ZPL response structure:', {
            response: zplResponse,
            zplData,
          });
          throw new Error(
            'No ZPL data received from server. The server response may be malformed.'
          );
        }
      }

      // Print using exact printer name from service (Windows API requires exact match)
      const result = await printZPL(zplData, {
        printerName: exactPrinterName,
        printerPort: printer.port,
      });

      return {
        ...result,
        printer: exactPrinterName,
        inventoryItemId,
        productId,
      };
    },
    onSuccess: (data) => {
      toast.success(`Label printed successfully to ${data.printer}`);
    },
    onError: (error) => {
      const message =
        error?.response?.data?.message ||
        error.message ||
        'Failed to print label';

      toast.error(message);
      console.error('Print error:', error);
    },
  });

  return {
    printLabel: printLabelMutation.mutate,
    // Expose async version so callers (like reprint flows) can sequence prints
    printLabelAsync: printLabelMutation.mutateAsync,
    isPrinting: printLabelMutation.isPending,
    selectedPrinterName,
    setSelectedPrinterName: handleSetSelectedPrinterName,
  };
}

