/**
 * Label Printing Page
 * Print labels for FG products (2x5 inch, ZPL format, Honeywell/Zebra)
 */

'use client';

import { useState } from 'react';
import { useQuery, useMutation } from '@tanstack/react-query';
import { labelPrintingAPI } from '@/lib/api/labelPrinting';
import { productsAPI } from '@/lib/api/products';
import { inventoryAPI } from '@/lib/api/inventory';
import { printZPL, getAvailablePrinters } from '@/lib/utils/printerClient';
import {
  Card,
  CardHeader,
  CardTitle,
  CardContent,
  Button,
  Input,
  LoadingSpinner,
  Table,
  TableHeader,
  TableBody,
  TableRow,
  TableHead,
  TableCell,
  Badge,
  Modal,
} from '@/components/ui';
import { Printer, Package, Network, Usb, Eye } from 'lucide-react';
import toast from 'react-hot-toast';
import PrinterSelect from '@/components/features/label-printing/PrinterSelect';

export default function LabelPrintingPage() {
  const [selectedProductId, setSelectedProductId] = useState(null);
  const [selectedInventoryItemId, setSelectedInventoryItemId] = useState(null);
  const [showPrintModal, setShowPrintModal] = useState(false);
  const [showPreviewModal, setShowPreviewModal] = useState(false);
  const [printMethod, setPrintMethod] = useState('client-side'); // 'client-side' or 'network'
  const [networkConfig, setNetworkConfig] = useState({
    host: '',
    port: 9100,
  });
  const [selectedPrinterName, setSelectedPrinterName] = useState('');
  const [previewData, setPreviewData] = useState(null);

  // Fetch FG products
  const { data: fgProductsData, isLoading: isLoadingProducts } = useQuery({
    queryKey: ['products', 'FG'],
    queryFn: async () => {
      const response = await productsAPI.list({ product_type: 'FG', limit: 100 });
      return response?.data?.products || response?.data || [];
    },
  });

  const fgProducts = fgProductsData || [];

  // Fetch inventory items for selected product
  const { data: inventoryItemsData, isLoading: isLoadingItems } = useQuery({
    queryKey: ['inventory-items', selectedProductId],
    queryFn: async () => {
      if (!selectedProductId) return { items: [] };
      const response = await inventoryAPI.listItems({
        product_id: selectedProductId,
        limit: 100,
      });
      return response?.data || { items: [] };
    },
    enabled: !!selectedProductId,
  });

  const inventoryItems = inventoryItemsData?.items || [];

  // Generate label preview
  const generatePreviewMutation = useMutation({
    mutationFn: async ({ inventoryItemId, productId, uid }) => {
      const params = {};
      if (inventoryItemId) params.inventory_item_id = inventoryItemId;
      if (productId) params.product_id = productId;
      if (uid) params.uid = uid;
      const response = await labelPrintingAPI.generateLabelPreview(params);
      return response?.data?.data || response?.data || response;
    },
    onSuccess: (data) => {
      setPreviewData(data);
      setShowPreviewModal(true);
    },
    onError: (error) => {
      const message = error?.response?.data?.message || error.message || 'Failed to generate preview';
      toast.error(message);
    },
  });

  // Print label mutation - client-side printing
  const printLabelMutation = useMutation({
    mutationFn: async ({ inventoryItemId, productId, sampleUID }) => {
      let zplResponse;
      
      // Resolve printer (local print service)
      let selectedPrinter = null;
      if (printMethod === 'client-side') {
        if (!selectedPrinterName) {
          throw new Error('Please select a printer');
        }

        const printers = await getAvailablePrinters();
        selectedPrinter = printers.find((p) => p.name === selectedPrinterName);
        if (!selectedPrinter) {
          throw new Error('Selected printer not found. Please refresh printer list.');
        }
      }

      // Get ZPL data from server
      if (inventoryItemId) {
        zplResponse = await labelPrintingAPI.getInventoryItemLabelZPL(
          inventoryItemId,
          printMethod === 'client-side'
            ? { dpi: selectedPrinter.dpi || 203, labelLength: 2.5, labelWidth: 5 }
            : undefined
        );
      } else if (productId) {
        zplResponse = await labelPrintingAPI.getProductLabelZPL(
          productId,
          sampleUID,
          printMethod === 'client-side'
            ? { dpi: selectedPrinter.dpi || 203, labelLength: 2.5, labelWidth: 5 }
            : undefined
        );
      } 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.
      const 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 client-side via local service
      if (printMethod === 'client-side') {
        const result = await printZPL(zplData, {
          printerName: selectedPrinter.name,
          printerPort: selectedPrinter.port || null,
          method: 'auto',
        });

        return {
          ...result,
          zplData,
          productName: zplResponse?.data?.data?.productName,
          uid: zplResponse?.data?.data?.uid,
        };
      } else {
        // Network printing (server-side)
        const printerConfig = {
          method: 'network',
          host: networkConfig.host,
          port: networkConfig.port,
        };

        if (inventoryItemId) {
          return await labelPrintingAPI.printInventoryItemLabel(inventoryItemId, printerConfig);
        } else {
          return await labelPrintingAPI.printProductLabel(productId, {
            printer: printerConfig,
            sampleUID,
          });
        }
      }
    },
    onSuccess: (data) => {
      if (data.requiresManualPrint) {
        toast.success('ZPL file downloaded. Open it with your printer application to print.', { duration: 5000 });
      } else {
        toast.success('Label printed successfully!');
      }
      setShowPrintModal(false);
    },
    onError: (error) => {
      const message = error?.response?.data?.message || error.message || 'Failed to print label';
      toast.error(message);
    },
  });

  const handlePrintInventoryItem = (inventoryItemId) => {
    setSelectedInventoryItemId(inventoryItemId);
    setSelectedProductId(null);
    setShowPrintModal(true);
  };

  const handlePrintProduct = (productId) => {
    setSelectedProductId(productId);
    setSelectedInventoryItemId(null);
    setShowPrintModal(true);
  };

  const handlePreview = (inventoryItemId, productId, uid) => {
    generatePreviewMutation.mutate({ inventoryItemId, productId, uid });
  };

  const handlePrint = () => {
    if (printMethod === 'client-side' && !selectedPrinterName) {
      toast.error('Please select a printer');
      return;
    }
    
    if (printMethod === 'network' && !networkConfig.host) {
      toast.error('Please enter printer host/IP address');
      return;
    }

    if (selectedInventoryItemId) {
      printLabelMutation.mutate({ inventoryItemId: selectedInventoryItemId });
    } else if (selectedProductId) {
      printLabelMutation.mutate({ productId: selectedProductId });
    }
  };

  return (
    <div className="p-6 bg-gray-50 dark:bg-gray-950 space-y-6">
      {/* Header */}
      <div>
        <h1 className="text-3xl font-bold text-gray-900 dark:text-white">Label Printing</h1>
        <p className="mt-1 text-sm text-gray-600 dark:text-gray-400">
          Print labels for FG products (2.5" × 5", ZPL format) - Honeywell/Zebra printers
        </p>
      </div>

      {/* Printer Configuration */}
      <Card>
        <CardHeader>
          <CardTitle>Printer Configuration</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="space-y-4">
            <div>
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                Print Method
              </label>
              <div className="flex gap-4">
                <button
                  type="button"
                  onClick={() => setPrintMethod('client-side')}
                  className={`flex items-center gap-2 px-4 py-2 rounded-lg border-2 transition-all ${
                    printMethod === 'client-side'
                      ? 'border-blue-500 bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300'
                      : 'border-gray-300 dark:border-gray-600 hover:border-gray-400'
                  }`}
                >
                  <Usb className="w-5 h-5" />
                  Client-Side (USB)
                </button>
                <button
                  type="button"
                  onClick={() => setPrintMethod('network')}
                  className={`flex items-center gap-2 px-4 py-2 rounded-lg border-2 transition-all ${
                    printMethod === 'network'
                      ? 'border-blue-500 bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300'
                      : 'border-gray-300 dark:border-gray-600 hover:border-gray-400'
                  }`}
                >
                  <Network className="w-5 h-5" />
                  Network
                </button>
              </div>
            </div>

            {printMethod === 'client-side' ? (
              <div className="space-y-4">
                <PrinterSelect
                  value={selectedPrinterName}
                  onChange={(printerName) => setSelectedPrinterName(printerName)}
                  label="Select Label Printer"
                  autoSelect={true}
                />
                <p className="text-sm text-gray-500 dark:text-gray-400">
                  Printers are loaded from the local print service. Connect the label printer and refresh if it does not appear.
                </p>
              </div>
            ) : (
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div>
                  <Input
                    label="Printer Host (IP Address)"
                    type="text"
                    value={networkConfig.host}
                    onChange={(e) => setNetworkConfig({ ...networkConfig, host: e.target.value })}
                    placeholder="192.168.1.100"
                  />
                </div>
                <div>
                  <Input
                    label="Port"
                    type="number"
                    value={networkConfig.port}
                    onChange={(e) => setNetworkConfig({ ...networkConfig, port: parseInt(e.target.value) || 9100 })}
                    placeholder="9100"
                  />
                </div>
              </div>
            )}
          </div>
        </CardContent>
      </Card>

      {/* FG Products List */}
      <Card>
        <CardHeader>
          <CardTitle>Finished Goods (FG) Products</CardTitle>
        </CardHeader>
        <CardContent>
          {isLoadingProducts ? (
            <div className="flex justify-center py-12">
              <LoadingSpinner size="lg" />
            </div>
          ) : fgProducts.length === 0 ? (
            <div className="text-center py-12 text-gray-500 dark:text-gray-400">
              <Package className="w-12 h-12 mx-auto mb-4 opacity-50" />
              <p>No FG products found</p>
            </div>
          ) : (
            <div className="space-y-4">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Product</TableHead>
                    <TableHead>SKU</TableHead>
                    <TableHead align="right">Actions</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {fgProducts.map((product) => (
                    <TableRow key={product.id}>
                      <TableCell className="font-medium">{product.name}</TableCell>
                      <TableCell>{product.sku || '—'}</TableCell>
                      <TableCell align="right">
                        <div className="flex gap-2 justify-end">
                          <Button
                            variant="outline"
                            size="sm"
                            onClick={() => handlePreview(null, product.id, null)}
                            disabled={generatePreviewMutation.isLoading}
                          >
                            <Eye className="w-4 h-4 mr-1" />
                            Preview
                          </Button>
                          <Button
                            variant="primary"
                            size="sm"
                            onClick={() => handlePrintProduct(product.id)}
                          >
                            <Printer className="w-4 h-4 mr-1" />
                            Print Label
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>

              {/* Inventory Items for Selected Product */}
              {selectedProductId && (
                <div className="mt-6 pt-6 border-t">
                  <h3 className="text-lg font-semibold mb-4">Inventory Items</h3>
                  {isLoadingItems ? (
                    <div className="flex justify-center py-8">
                      <LoadingSpinner />
                    </div>
                  ) : inventoryItems.length === 0 ? (
                    <p className="text-gray-500 dark:text-gray-400 text-center py-8">
                      No inventory items found for this product
                    </p>
                  ) : (
                    <Table>
                      <TableHeader>
                        <TableRow>
                          <TableHead>UID</TableHead>
                          <TableHead>Status</TableHead>
                          <TableHead align="right">Actions</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {inventoryItems.slice(0, 20).map((item) => (
                          <TableRow key={item.id}>
                            <TableCell>
                              <code className="text-sm font-mono">{item.uid}</code>
                            </TableCell>
                            <TableCell>
                              <Badge variant={item.status === 'IN_STOCK' ? 'success' : 'secondary'}>
                                {item.status}
                              </Badge>
                            </TableCell>
                            <TableCell align="right">
                              <div className="flex gap-2 justify-end">
                                <Button
                                  variant="outline"
                                  size="sm"
                                  onClick={() => handlePreview(item.id, null, item.uid)}
                                  disabled={generatePreviewMutation.isLoading}
                                >
                                  <Eye className="w-4 h-4 mr-1" />
                                  Preview
                                </Button>
                                <Button
                                  variant="primary"
                                  size="sm"
                                  onClick={() => handlePrintInventoryItem(item.id)}
                                >
                                  <Printer className="w-4 h-4 mr-1" />
                                  Print
                                </Button>
                              </div>
                            </TableCell>
                          </TableRow>
                        ))}
                      </TableBody>
                    </Table>
                  )}
                </div>
              )}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Print Modal */}
      <Modal
        isOpen={showPrintModal}
        onClose={() => setShowPrintModal(false)}
        title="Print Label"
        description="Select printer and print the label"
      >
        <div className="space-y-4">
          <div className="text-sm text-gray-600 dark:text-gray-400">
            {selectedInventoryItemId
              ? `Printing label for inventory item #${selectedInventoryItemId}`
              : `Printing label for product #${selectedProductId}`}
          </div>

          {printMethod === 'client-side' ? (
            <div className="space-y-4">
              <PrinterSelect
                value={selectedPrinterName}
                onChange={(printerName) => setSelectedPrinterName(printerName)}
                label="Select Label Printer"
                autoSelect={true}
              />
            </div>
          ) : (
            <div className="space-y-2">
              <Input
                label="Printer Host (IP Address)"
                type="text"
                value={networkConfig.host}
                onChange={(e) => setNetworkConfig({ ...networkConfig, host: e.target.value })}
                placeholder="192.168.1.100"
              />
              <Input
                label="Port"
                type="number"
                value={networkConfig.port}
                onChange={(e) => setNetworkConfig({ ...networkConfig, port: parseInt(e.target.value) || 9100 })}
                placeholder="9100"
              />
            </div>
          )}

          <div className="flex justify-end gap-4 pt-4 border-t">
            <Button variant="outline" onClick={() => setShowPrintModal(false)}>
              Cancel
            </Button>
            <Button
              variant="primary"
              onClick={handlePrint}
              disabled={
                printLabelMutation.isLoading ||
                (printMethod === 'client-side' && !selectedPrinterName) ||
                (printMethod === 'network' && !networkConfig.host)
              }
              loading={printLabelMutation.isLoading}
            >
              <Printer className="w-4 h-4 mr-2" />
              Print Label
            </Button>
          </div>
        </div>
      </Modal>

      {/* Preview Modal */}
      <Modal
        isOpen={showPreviewModal}
        onClose={() => setShowPreviewModal(false)}
        title="Label Preview"
        description="Preview of the label with QR code"
      >
        {previewData ? (
          <div className="space-y-4">
            {previewData.qrCodeImage && (
              <div className="flex justify-center">
                <img
                  src={`data:image/png;base64,${previewData.qrCodeImage}`}
                  alt="QR Code"
                  className="w-48 h-48 border rounded"
                />
              </div>
            )}
            <div className="text-sm space-y-2">
              <div>
                <strong>Product:</strong> {previewData.productName || 'N/A'}
              </div>
              <div>
                <strong>UID:</strong> <code className="font-mono">{previewData.uid || 'N/A'}</code>
              </div>
            </div>
            <div className="flex justify-end pt-4 border-t">
              <Button variant="outline" onClick={() => setShowPreviewModal(false)}>
                Close
              </Button>
            </div>
          </div>
        ) : (
          <div className="flex justify-center py-8">
            <LoadingSpinner />
          </div>
        )}
      </Modal>
    </div>
  );
}
