'use client';

import React, { useState, useEffect, useCallback, useRef } from 'react';
import { io, Socket } from 'socket.io-client';
import {
  Smartphone, QrCode, Plus, Trash2, Wifi, WifiOff, RefreshCw,
  Link2, Cloud, Settings, LogOut, Copy, Check, ChevronDown,
  Loader2, AlertCircle, CheckCircle2, XCircle, Key, Shield,
  MessageSquare, Send, ExternalLink, Info, Server, Zap
} from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogDescription } from '@/components/ui/dialog';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Separator } from '@/components/ui/separator';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  Alert,
  AlertDescription,
  AlertTitle,
} from '@/components/ui/alert';
import { useToast } from '@/hooks/use-toast';

// ── Types ──────────────────────────────────────────────────────────────────
interface Device {
  id: string;
  body: string;
  name: string | null;
  status: string;
  webhook: string | null;
  connectionDriver: string;
  metaBusinessAccountId: string | null;
  metaPhoneNumberId: string | null;
  metaAccessToken: string | null;
  metaWebhookVerifyToken: string | null;
  metaBusinessName: string | null;
  metaDisplayPhoneNumber: string | null;
  metaVerifiedName: string | null;
  metaConnectedAt: string | null;
  messageSent: number;
  createdAt: string;
  updatedAt: string;
}

type ViewMode = 'devices' | 'scan' | 'meta-connect';

// ── Constants ──────────────────────────────────────────────────────────────
const WA_GATEWAY_PORT = 3100;

/**
 * Socket.IO & Gateway Connection Configuration for cPanel Node.js Hosting
 * 
 * FIX for "timeout" & "xhr poll error":
 * 1. WebSocket transport ONLY — prevents "xhr poll error" on cPanel/Apache
 * 2. Extended connection timeout — shared hosting has higher latency
 * 3. Auto-retry with exponential backoff
 * 4. Ping/pong keepalive to maintain connection through proxy
 * 
 * In dev mode: connects directly to gateway port 3100
 * In cPanel/prod mode: connects through Caddy proxy using XTransformPort
 */

/**
 * Detect if we're in development mode (direct connection to gateway)
 * or production/cPanel mode (connection through proxy)
 */
function isDevMode() {
  if (typeof window === 'undefined') return false;
  const hostname = window.location.hostname;
  // Development: localhost or direct IP access on port 3000
  return hostname === 'localhost' || hostname === '127.0.0.1';
}

function getSocketConfig() {
  const dev = isDevMode();
  
  // In development, connect directly to the gateway on port 3100
  // In production (cPanel), connect through Caddy proxy using XTransformPort
  const url = dev ? `http://localhost:${WA_GATEWAY_PORT}` : undefined;
  
  return {
    // Direct connection URL (dev only)
    ...(url ? { url } : {}),
    // Use WebSocket ONLY to prevent "xhr poll error" on cPanel
    transports: ['websocket'],
    path: '/socket.io/',
    // Extended timeouts for shared hosting
    timeout: 45000,            // 45s connection timeout (was 20s)
    reconnection: true,
    reconnectionAttempts: 10,
    reconnectionDelay: 1000,
    reconnectionDelayMax: 10000,
    forceNew: true,
    upgrade: false,            // Don't try to upgrade — already on WebSocket
    rememberUpgrade: false,
    // Query params for Caddy proxy routing (production only)
    ...(!dev ? { query: { XTransformPort: String(WA_GATEWAY_PORT) } } : {}),
  };
}

/**
 * Build URL for gateway REST API requests
 * In dev: direct connection to gateway port
 * In prod: through Caddy proxy using XTransformPort
 */
function getGatewayApiUrl(endpoint) {
  if (isDevMode()) {
    return `http://localhost:${WA_GATEWAY_PORT}${endpoint}`;
  }
  const separator = endpoint.includes('?') ? '&' : '?';
  return `${endpoint}${separator}XTransformPort=${WA_GATEWAY_PORT}`;
}

// ── Main Component ─────────────────────────────────────────────────────────
export default function WhatsAppGateway() {
  const [devices, setDevices] = useState<Device[]>([]);
  const [loading, setLoading] = useState(true);
  const [viewMode, setViewMode] = useState<ViewMode>('devices');
  const [selectedDevice, setSelectedDevice] = useState<Device | null>(null);
  const [addDialogOpen, setAddDialogOpen] = useState(false);
  const [metaDialogOpen, setMetaDialogOpen] = useState(false);
  const { toast } = useToast();

  // Fetch devices
  const fetchDevices = useCallback(async () => {
    try {
      const res = await fetch('/api/devices');
      const data = await res.json();
      if (data.devices) {
        setDevices(data.devices);
      }
    } catch (err) {
      console.error('Failed to fetch devices:', err);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchDevices();
  }, [fetchDevices]);

  // Add device
  const [newDeviceBody, setNewDeviceBody] = useState('');
  const [newDeviceName, setNewDeviceName] = useState('');
  const [newDeviceDriver, setNewDeviceDriver] = useState('baileys');
  const [adding, setAdding] = useState(false);

  const handleAddDevice = async () => {
    if (!newDeviceBody.trim()) return;
    setAdding(true);
    try {
      const res = await fetch('/api/devices', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          body: newDeviceBody.trim(),
          name: newDeviceName.trim() || newDeviceBody.trim(),
          connectionDriver: newDeviceDriver,
        }),
      });
      const data = await res.json();
      if (data.device) {
        toast({ title: 'Device Added', description: `${newDeviceBody} has been added successfully.` });
        setNewDeviceBody('');
        setNewDeviceName('');
        setAddDialogOpen(false);
        fetchDevices();
      } else {
        toast({ title: 'Error', description: data.error || 'Failed to add device', variant: 'destructive' });
      }
    } catch (err) {
      toast({ title: 'Error', description: 'Failed to add device', variant: 'destructive' });
    } finally {
      setAdding(false);
    }
  };

  // Delete device
  const handleDeleteDevice = async (id: string, body: string) => {
    if (!confirm(`Delete device ${body}? This will also disconnect it.`)) return;
    try {
      const res = await fetch(`/api/devices/${id}`, { method: 'DELETE' });
      if (res.ok) {
        toast({ title: 'Device Deleted', description: `${body} has been removed.` });
        fetchDevices();
        if (selectedDevice?.id === id) {
          setViewMode('devices');
          setSelectedDevice(null);
        }
      }
    } catch (err) {
      toast({ title: 'Error', description: 'Failed to delete device', variant: 'destructive' });
    }
  };

  // ── Render ─────────────────────────────────────────────────────────────
  return (
    <div className="min-h-screen flex flex-col bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-950 dark:to-slate-900">
      {/* Header */}
      <header className="sticky top-0 z-50 bg-white/80 dark:bg-slate-950/80 backdrop-blur-md border-b border-slate-200 dark:border-slate-800">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-3">
              <div className="w-10 h-10 bg-emerald-500 rounded-xl flex items-center justify-center">
                <MessageSquare className="w-5 h-5 text-white" />
              </div>
              <div>
                <h1 className="text-xl font-bold text-slate-900 dark:text-white">
                  WhatsApp Gateway
                </h1>
                <p className="text-xs text-slate-500 dark:text-slate-400">
                  Multi-Device • Meta Cloud API v23.0 • cPanel Ready
                </p>
              </div>
            </div>
            <div className="flex items-center gap-2">
              <Badge variant="outline" className="bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-950 dark:text-emerald-300 dark:border-emerald-800">
                <Wifi className="w-3 h-3 mr-1" />
                {devices.filter(d => d.status === 'Connected').length} Online
              </Badge>
              <Dialog open={addDialogOpen} onOpenChange={setAddDialogOpen}>
                <DialogTrigger asChild>
                  <Button size="sm" className="bg-emerald-600 hover:bg-emerald-700">
                    <Plus className="w-4 h-4 mr-1" /> Add Device
                  </Button>
                </DialogTrigger>
                <DialogContent>
                  <DialogHeader>
                    <DialogTitle>Add New Device</DialogTitle>
                    <DialogDescription>Add a WhatsApp number to connect via QR scan or Meta Cloud API.</DialogDescription>
                  </DialogHeader>
                  <div className="space-y-4 py-2">
                    <div className="space-y-2">
                      <Label>WhatsApp Number</Label>
                      <Input
                        placeholder="e.g. 6281234567890"
                        value={newDeviceBody}
                        onChange={(e) => setNewDeviceBody(e.target.value)}
                      />
                      <p className="text-xs text-muted-foreground">Country code + number, no + or spaces</p>
                    </div>
                    <div className="space-y-2">
                      <Label>Display Name (optional)</Label>
                      <Input
                        placeholder="e.g. Business WA"
                        value={newDeviceName}
                        onChange={(e) => setNewDeviceName(e.target.value)}
                      />
                    </div>
                    <div className="space-y-2">
                      <Label>Connection Type</Label>
                      <Select value={newDeviceDriver} onValueChange={setNewDeviceDriver}>
                        <SelectTrigger>
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="baileys">
                            <div className="flex items-center gap-2">
                              <QrCode className="w-4 h-4" />
                              <span>QR Scan (Baileys)</span>
                            </div>
                          </SelectItem>
                          <SelectItem value="meta_cloud_api">
                            <div className="flex items-center gap-2">
                              <Cloud className="w-4 h-4" />
                              <span>Meta Cloud API</span>
                            </div>
                          </SelectItem>
                        </SelectContent>
                      </Select>
                      <p className="text-xs text-muted-foreground">
                        QR Scan uses Baileys library. Meta Cloud API uses official WhatsApp Business API.
                      </p>
                    </div>
                    <Button
                      onClick={handleAddDevice}
                      disabled={!newDeviceBody.trim() || adding}
                      className="w-full bg-emerald-600 hover:bg-emerald-700"
                    >
                      {adding ? <Loader2 className="w-4 h-4 mr-2 animate-spin" /> : <Plus className="w-4 h-4 mr-2" />}
                      Add Device
                    </Button>
                  </div>
                </DialogContent>
              </Dialog>
            </div>
          </div>
        </div>
      </header>

      {/* Main Content */}
      <main className="flex-1 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 w-full">
        {viewMode === 'devices' && (
          <DeviceList
            devices={devices}
            loading={loading}
            onScan={(device) => {
              setSelectedDevice(device);
              setViewMode('scan');
            }}
            onMetaConnect={(device) => {
              setSelectedDevice(device);
              setMetaDialogOpen(true);
            }}
            onDelete={(id, body) => handleDeleteDevice(id, body)}
            onRefresh={fetchDevices}
          />
        )}
        {viewMode === 'scan' && selectedDevice && (
          <QRScanView
            device={selectedDevice}
            onBack={() => {
              setViewMode('devices');
              setSelectedDevice(null);
              fetchDevices();
            }}
            onConnected={() => fetchDevices()}
          />
        )}
      </main>

      {/* Meta Connect Dialog */}
      {selectedDevice && (
        <MetaConnectDialog
          device={selectedDevice}
          open={metaDialogOpen}
          onOpenChange={(open) => {
            setMetaDialogOpen(open);
            if (!open) fetchDevices();
          }}
          onSave={async (metaData) => {
            try {
              const res = await fetch(`/api/devices/${selectedDevice.id}`, {
                method: 'PATCH',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                  ...metaData,
                  connectionDriver: 'meta_cloud_api',
                  status: 'Connected',
                  metaConnectedAt: new Date().toISOString(),
                }),
              });
              if (res.ok) {
                toast({ title: 'Meta API Connected', description: 'Device configured with Meta Cloud API.' });
                setMetaDialogOpen(false);
                fetchDevices();
              }
            } catch (err) {
              toast({ title: 'Error', description: 'Failed to save Meta configuration', variant: 'destructive' });
            }
          }}
        />
      )}

      {/* Footer */}
      <footer className="mt-auto border-t bg-white/80 dark:bg-slate-950/80 backdrop-blur-md py-4">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
          <div className="flex flex-col sm:flex-row items-center justify-between gap-2 text-xs text-slate-500">
            <span>WhatsApp Gateway v3.0 • Meta Cloud API v23.0 • Baileys 7.x</span>
            <span className="flex items-center gap-1">
              <Zap className="w-3 h-3" /> WebSocket Transport • cPanel Compatible
            </span>
          </div>
        </div>
      </footer>
    </div>
  );
}

// ── Device List Component ──────────────────────────────────────────────────
function DeviceList({
  devices,
  loading,
  onScan,
  onMetaConnect,
  onDelete,
  onRefresh,
}: {
  devices: Device[];
  loading: boolean;
  onScan: (device: Device) => void;
  onMetaConnect: (device: Device) => void;
  onDelete: (id: string, body: string) => void;
  onRefresh: () => void;
}) {
  if (loading) {
    return (
      <div className="flex items-center justify-center py-20">
        <Loader2 className="w-8 h-8 animate-spin text-emerald-500" />
      </div>
    );
  }

  if (devices.length === 0) {
    return (
      <Card className="max-w-md mx-auto mt-12">
        <CardContent className="pt-6 text-center">
          <Smartphone className="w-12 h-12 mx-auto text-slate-300 mb-4" />
          <h3 className="text-lg font-semibold mb-2">No Devices Yet</h3>
          <p className="text-sm text-muted-foreground mb-4">
            Add a WhatsApp number to get started. You can connect via QR scan or Meta Cloud API.
          </p>
          <Alert className="text-left mb-4">
            <Zap className="h-4 w-4" />
            <AlertTitle>cPanel Compatible — Fixed</AlertTitle>
            <AlertDescription className="text-xs">
              WebSocket-only transport prevents &quot;xhr poll error&quot; and &quot;timeout&quot; errors
              that occur on cPanel/Apache hosting. No HTTP long-polling is used.
            </AlertDescription>
          </Alert>
        </CardContent>
      </Card>
    );
  }

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <h2 className="text-lg font-semibold">Devices ({devices.length})</h2>
        <Button variant="outline" size="sm" onClick={onRefresh}>
          <RefreshCw className="w-4 h-4 mr-1" /> Refresh
        </Button>
      </div>
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
        {devices.map((device) => (
          <Card key={device.id} className="relative overflow-hidden">
            {/* Status indicator bar */}
            <div className={`absolute top-0 left-0 right-0 h-1 ${
              device.status === 'Connected'
                ? 'bg-emerald-500'
                : 'bg-slate-300 dark:bg-slate-700'
            }`} />
            <CardContent className="pt-5">
              <div className="flex items-start justify-between mb-3">
                <div className="flex items-center gap-2">
                  <div className={`w-8 h-8 rounded-full flex items-center justify-center ${
                    device.status === 'Connected'
                      ? 'bg-emerald-100 text-emerald-600 dark:bg-emerald-900 dark:text-emerald-300'
                      : 'bg-slate-100 text-slate-400 dark:bg-slate-800 dark:text-slate-500'
                  }`}>
                    {device.status === 'Connected' ? <Wifi className="w-4 h-4" /> : <WifiOff className="w-4 h-4" />}
                  </div>
                  <div>
                    <p className="font-medium text-sm">{device.name || device.body}</p>
                    <p className="text-xs text-muted-foreground">{device.body}</p>
                  </div>
                </div>
                <Badge variant={device.status === 'Connected' ? 'default' : 'secondary'}
                  className={device.status === 'Connected' ? 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300' : ''}>
                  {device.status}
                </Badge>
              </div>

              <div className="flex items-center gap-2 mb-3">
                <Badge variant="outline" className="text-xs">
                  {device.connectionDriver === 'meta_cloud_api' ? (
                    <><Cloud className="w-3 h-3 mr-1" /> Meta API</>
                  ) : (
                    <><QrCode className="w-3 h-3 mr-1" /> Baileys</>
                  )}
                </Badge>
                {device.messageSent > 0 && (
                  <Badge variant="outline" className="text-xs">
                    <Send className="w-3 h-3 mr-1" /> {device.messageSent}
                  </Badge>
                )}
              </div>

              <Separator className="my-3" />

              <div className="flex gap-2">
                {device.connectionDriver === 'baileys' ? (
                  <Button
                    size="sm"
                    variant="default"
                    className="flex-1 bg-emerald-600 hover:bg-emerald-700"
                    onClick={() => onScan(device)}
                  >
                    <QrCode className="w-4 h-4 mr-1" />
                    {device.status === 'Connected' ? 'Re-Scan' : 'Scan QR'}
                  </Button>
                ) : (
                  <Button
                    size="sm"
                    variant="outline"
                    className="flex-1"
                    onClick={() => onMetaConnect(device)}
                  >
                    <Cloud className="w-4 h-4 mr-1" /> Configure
                  </Button>
                )}
                <Button
                  size="sm"
                  variant="outline"
                  className="text-red-600 hover:text-red-700 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950"
                  onClick={() => onDelete(device.id, device.body)}
                >
                  <Trash2 className="w-4 h-4" />
                </Button>
              </div>
            </CardContent>
          </Card>
        ))}
      </div>
    </div>
  );
}

// ── QR Scan View Component ─────────────────────────────────────────────────
function QRScanView({
  device,
  onBack,
  onConnected,
}: {
  device: Device;
  onBack: () => void;
  onConnected: () => void;
}) {
  const [socket, setSocket] = useState<Socket | null>(null);
  const [connected, setConnected] = useState(false);
  const [qrCode, setQrCode] = useState<string | null>(null);
  const [statusMessage, setStatusMessage] = useState('Connecting to gateway...');
  const [statusType, setStatusType] = useState<'loading' | 'info' | 'success' | 'error' | 'warning'>('loading');
  const [logs, setLogs] = useState<string[]>([]);
  const [userInfo, setUserInfo] = useState<{ name?: string; number?: string; ppUrl?: string }>({});
  const [retryCount, setRetryCount] = useState(0);
  const [transportType, setTransportType] = useState<string>('');
  const [gatewayOnline, setGatewayOnline] = useState(false);
  const maxRetries = 10;
  const socketRef = useRef<Socket | null>(null);
  const keepaliveRef = useRef<NodeJS.Timeout | null>(null);

  const appendLog = useCallback((text: string) => {
    const ts = new Date().toLocaleTimeString();
    setLogs(prev => [...prev.slice(-50), `${ts} - ${text}`]);
  }, []);

  const disconnectSocket = useCallback(() => {
    // Stop keepalive ping
    if (keepaliveRef.current) {
      clearInterval(keepaliveRef.current);
      keepaliveRef.current = null;
    }
    if (socketRef.current) {
      try { socketRef.current.removeAllListeners(); } catch {}
      try { socketRef.current.disconnect(); } catch {}
      socketRef.current = null;
    }
  }, []);

  // Check gateway health before connecting
  const checkGatewayHealth = useCallback(async () => {
    try {
      const res = await fetch(getGatewayApiUrl('/api/health'), {
        signal: AbortSignal.timeout(5000),
      });
      if (res.ok) {
        const data = await res.json();
        setGatewayOnline(true);
        appendLog(`[Gateway] Online — v${data.version}, transport: ${data.transport_mode}`);
        return true;
      }
    } catch (err) {
      appendLog('[Gateway] Health check failed — gateway may be offline');
    }
    setGatewayOnline(false);
    return false;
  }, [appendLog]);

  const initScan = useCallback(() => {
    disconnectSocket();

    setQrCode(null);
    setConnected(false);
    setStatusMessage('Connecting to gateway...');
    setStatusType('loading');

    appendLog('[Scan] Initializing WebSocket connection...');

    // ── KEY FIX: Socket.IO Connection for cPanel ────────────────────
    //
    // ROOT CAUSE of "timeout" & "xhr poll error":
    // - cPanel/Apache doesn't properly forward Socket.IO HTTP long-polling
    // - The polling transport causes "xhr poll error" because Apache strips
    //   or corrupts the polling requests/responses
    // - When polling fails, Socket.IO never upgrades to WebSocket, causing
    //   a "timeout" as the connection never completes
    //
    // SOLUTION:
    // - Use WebSocket transport ONLY (no polling at all)
    // - WebSocket connections work through Apache/cPanel proxy correctly
    // - Extended timeout (45s) for shared hosting latency
    // - Auto-reconnect with increasing delay
    // - Keepalive ping/pong to prevent idle disconnection
    //
    const config = getSocketConfig();
    const newSocket = io(config);

    socketRef.current = newSocket;
    setSocket(newSocket);

    // ── Connection timeout ─────────────────────────────────────────────
    const connectTimeout = setTimeout(() => {
      if (!newSocket.connected) {
        appendLog('[Timeout] No response within 45s — gateway may be offline');
        setStatusMessage('Connection timed out. Check if the gateway service is running.');
        setStatusType('error');

        if (retryCount < maxRetries) {
          setRetryCount(prev => prev + 1);
        }
      }
    }, 45000);

    // ── Socket Events ──────────────────────────────────────────────────
    newSocket.on('connect', () => {
      clearTimeout(connectTimeout);
      setRetryCount(0);
      const transport = newSocket.io.engine.transport.name;
      setTransportType(transport);
      appendLog(`[Socket] ✅ Connected (sid: ${newSocket.id}, transport: ${transport})`);
      setStatusMessage('Socket connected. Starting WhatsApp connection...');
      setStatusType('info');

      // Start WhatsApp connection
      newSocket.emit('StartConnection', device.body);
      appendLog('[Scan] StartConnection sent');

      // ── Keepalive: Ping gateway every 20s ──────────────────────────
      if (keepaliveRef.current) clearInterval(keepaliveRef.current);
      keepaliveRef.current = setInterval(() => {
        if (newSocket.connected) {
          newSocket.emit('ping-gateway');
        }
      }, 20000);
    });

    // Track transport upgrades
    newSocket.io.engine.on('upgrade', (t: any) => {
      setTransportType(t.name);
      appendLog(`[Socket] Transport upgraded to: ${t.name}`);
    });

    newSocket.on('pong-gateway', (data: { timestamp: number; transport: string }) => {
      const latency = Date.now() - data.timestamp;
      appendLog(`[Keepalive] Pong received (${latency}ms, transport: ${data.transport})`);
    });

    newSocket.on('qrcode', (r: { token: string; data: string; message: string }) => {
      if (r.token === device.body) {
        setQrCode(r.data);
        setStatusMessage(r.message || 'Scan this QR code with your WhatsApp');
        setStatusType('warning');
        appendLog('[QR] ✅ QR code received. Please scan with WhatsApp.');
      }
    });

    newSocket.on('connection-open', (r: { token: string; user: any; ppUrl: string }) => {
      if (r.token === device.body) {
        setConnected(true);
        setQrCode(null);
        setStatusMessage('Device connected successfully!');
        setStatusType('success');
        setUserInfo({
          name: r.user?.name || r.user?.id?.split('@')[0] || 'Unknown',
          number: r.token,
          ppUrl: r.ppUrl || '',
        });
        appendLog('[Connected] ✅ Device connected successfully!');

        // Update device status in DB
        fetch(`/api/devices/${device.id}`, {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ status: 'Connected' }),
        }).catch(() => {});

        onConnected();
      }
    });

    newSocket.on('pairing-code', (r: { token: string; code: string }) => {
      if (r.token === device.body) {
        appendLog(`[Pairing Code] ${r.code}`);
        setStatusMessage(`Pairing code: ${r.code}`);
        setStatusType('info');
      }
    });

    newSocket.on('Unauthorized', (r: { token: string }) => {
      if (r.token === device.body) {
        setStatusMessage('Unauthorized access');
        setStatusType('error');
        appendLog('[Error] Unauthorized');
      }
    });

    newSocket.on('message', (r: { token: string; message: string }) => {
      if (r.token === device.body) {
        appendLog(r.message);
        if (r.message.includes('Connection closed') || r.message.includes('logged out')) {
          setConnected(false);
          setStatusMessage(r.message);
          setStatusType('error');
        } else {
          setStatusMessage(r.message);
          setStatusType('info');
        }
      }
    });

    newSocket.on('disconnect', (reason: string) => {
      clearTimeout(connectTimeout);
      appendLog(`[Socket] Disconnected: ${reason}`);
      if (!connected) {
        setStatusMessage('Connection lost. Click retry to reconnect.');
        setStatusType('error');
      }
    });

    newSocket.on('connect_error', (err: Error) => {
      clearTimeout(connectTimeout);
      const errMsg = err.message;
      
      // More descriptive error messages
      let userMessage = errMsg;
      if (errMsg.includes('timeout') || errMsg.includes('Transport unknown')) {
        userMessage = 'Connection timed out — gateway may be offline or port is blocked';
      } else if (errMsg.includes('xhr poll error')) {
        userMessage = 'HTTP polling failed — WebSocket is required. Check your proxy configuration.';
      } else if (errMsg.includes('Transport unknown') || errMsg.includes('websocket')) {
        userMessage = 'WebSocket connection failed — ensure the gateway port is accessible';
      }

      appendLog(`[Socket] ❌ Error: ${errMsg}`);
      setStatusMessage(userMessage);
      setStatusType('error');

      setRetryCount(prev => {
        const newCount = prev + 1;
        if (newCount >= maxRetries) {
          appendLog(`[Error] Max retries (${maxRetries}) reached. Please check the gateway service.`);
        }
        return newCount;
      });
    });
  }, [device.body, device.id, disconnectSocket, appendLog, retryCount, onConnected, connected]);

  useEffect(() => {
    // Check gateway health first, then connect
    checkGatewayHealth().then(() => {
      initScan();
    });
    
    return () => {
      disconnectSocket();
    };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handleRetry = () => {
    setRetryCount(0);
    checkGatewayHealth().then(() => initScan());
  };

  const handleLogout = () => {
    if (socketRef.current) {
      socketRef.current.emit('LogoutDevice', device.body);
      appendLog('[Logout] Logging out...');
      setConnected(false);
      setQrCode(null);
      setUserInfo({});

      // Update device status
      fetch(`/api/devices/${device.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ status: 'Disconnect' }),
      }).catch(() => {});
    }
  };

  const handleConnectViaCode = () => {
    if (socketRef.current) {
      socketRef.current.emit('ConnectViaCode', device.body);
      appendLog('[Pairing] Requesting pairing code...');
      setStatusMessage('Requesting pairing code...');
      setStatusType('loading');
    }
  };

  return (
    <div className="space-y-4">
      {/* Back button + header */}
      <div className="flex items-center gap-3">
        <Button variant="ghost" size="sm" onClick={onBack}>
          ← Back
        </Button>
        <div className="flex-1">
          <h2 className="text-lg font-semibold flex items-center gap-2">
            <Smartphone className="w-5 h-5" />
            {device.name || device.body}
          </h2>
          <p className="text-sm text-muted-foreground">{device.body}</p>
        </div>
        <div className="flex items-center gap-2">
          {gatewayOnline && (
            <Badge variant="outline" className="text-xs bg-emerald-50 text-emerald-700 border-emerald-200">
              <Server className="w-3 h-3 mr-1" /> Gateway Online
            </Badge>
          )}
          {transportType && (
            <Badge variant="outline" className="text-xs">
              <Zap className="w-3 h-3 mr-1" /> {transportType}
            </Badge>
          )}
          <Badge variant={connected ? 'default' : 'secondary'}
            className={connected ? 'bg-emerald-100 text-emerald-700' : ''}>
            {connected ? <Wifi className="w-3 h-3 mr-1" /> : <WifiOff className="w-3 h-3 mr-1" />}
            {connected ? 'Connected' : 'Disconnected'}
          </Badge>
        </div>
      </div>

      <div className="grid gap-4 lg:grid-cols-3">
        {/* QR Code / Status */}
        <div className="lg:col-span-2">
          <Card>
            <CardContent className="pt-6">
              <div className="flex flex-col items-center justify-center min-h-[400px]">
                {/* Status indicator */}
                {statusType === 'loading' && !qrCode && (
                  <div className="text-center">
                    <Loader2 className="w-16 h-16 animate-spin text-emerald-500 mx-auto mb-4" />
                    <p className="text-muted-foreground">{statusMessage}</p>
                    {retryCount > 0 && (
                      <p className="text-xs text-amber-500 mt-2">
                        Retry attempt {retryCount}/{maxRetries}
                      </p>
                    )}
                    {!gatewayOnline && (
                      <Alert variant="destructive" className="mt-4 max-w-sm">
                        <Server className="h-4 w-4" />
                        <AlertTitle className="text-xs">Gateway Offline</AlertTitle>
                        <AlertDescription className="text-xs">
                          The WhatsApp Gateway service (port {WA_GATEWAY_PORT}) is not responding.
                          Please make sure the Node.js service is running on your cPanel hosting.
                        </AlertDescription>
                      </Alert>
                    )}
                  </div>
                )}

                {/* QR Code */}
                {qrCode && !connected && (
                  <div className="text-center">
                    <div className="inline-block p-4 bg-white rounded-2xl shadow-lg border-2 border-emerald-200 mb-4">
                      <img
                        src={qrCode}
                        alt="WhatsApp QR Code"
                        className="w-64 h-64 sm:w-72 sm:h-72"
                      />
                    </div>
                    <p className="text-sm text-amber-600 dark:text-amber-400 font-medium">
                      {statusMessage}
                    </p>
                    <p className="text-xs text-muted-foreground mt-1">
                      Open WhatsApp → Linked Devices → Link a device
                    </p>
                  </div>
                )}

                {/* Connected */}
                {connected && (
                  <div className="text-center">
                    <CheckCircle2 className="w-16 h-16 text-emerald-500 mx-auto mb-4" />
                    <p className="text-lg font-semibold text-emerald-600 dark:text-emerald-400">
                      Device Connected!
                    </p>
                    <p className="text-sm text-muted-foreground mt-1">
                      {userInfo.name}
                    </p>
                    <Button
                      variant="outline"
                      className="mt-4 text-red-600 hover:bg-red-50"
                      onClick={handleLogout}
                    >
                      <LogOut className="w-4 h-4 mr-2" /> Logout Device
                    </Button>
                  </div>
                )}

                {/* Error */}
                {statusType === 'error' && !qrCode && !connected && (
                  <div className="text-center">
                    <XCircle className="w-16 h-16 text-red-400 mx-auto mb-4" />
                    <p className="text-red-600 dark:text-red-400 font-medium">{statusMessage}</p>
                    <div className="flex gap-2 mt-4 justify-center">
                      <Button onClick={handleRetry} variant="default" className="bg-emerald-600 hover:bg-emerald-700">
                        <RefreshCw className="w-4 h-4 mr-2" /> Retry
                      </Button>
                      <Button onClick={handleConnectViaCode} variant="outline">
                        <Key className="w-4 h-4 mr-2" /> Use Pairing Code
                      </Button>
                    </div>
                  </div>
                )}
              </div>
            </CardContent>
          </Card>
        </div>

        {/* Sidebar: Info + Logs */}
        <div className="space-y-4">
          {/* Connection Info */}
          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="text-sm">WhatsApp Info</CardTitle>
            </CardHeader>
            <CardContent>
              <div className="flex justify-center mb-4">
                {userInfo.ppUrl ? (
                  <img src={userInfo.ppUrl} alt="Profile" className="w-16 h-16 rounded-full" />
                ) : (
                  <div className="w-16 h-16 bg-slate-200 dark:bg-slate-700 rounded-full flex items-center justify-center">
                    <Smartphone className="w-6 h-6 text-slate-400" />
                  </div>
                )}
              </div>
              <div className="space-y-2 text-sm">
                <div className="flex justify-between">
                  <span className="text-muted-foreground">Name</span>
                  <span className="font-medium">{userInfo.name || 'N/A'}</span>
                </div>
                <div className="flex justify-between">
                  <span className="text-muted-foreground">Number</span>
                  <span className="font-medium">{userInfo.number || 'N/A'}</span>
                </div>
                <div className="flex justify-between">
                  <span className="text-muted-foreground">Driver</span>
                  <span className="font-medium">Baileys</span>
                </div>
                <div className="flex justify-between">
                  <span className="text-muted-foreground">Transport</span>
                  <span className="font-medium text-emerald-600">WebSocket</span>
                </div>
              </div>
            </CardContent>
          </Card>

          {/* Actions */}
          {!connected && (
            <Card>
              <CardContent className="pt-4 space-y-2">
                <Button
                  variant="outline"
                  size="sm"
                  className="w-full"
                  onClick={handleRetry}
                  disabled={retryCount >= maxRetries}
                >
                  <RefreshCw className="w-4 h-4 mr-2" /> Retry Connection
                </Button>
                <Button
                  variant="outline"
                  size="sm"
                  className="w-full"
                  onClick={handleConnectViaCode}
                >
                  <Key className="w-4 h-4 mr-2" /> Connect via Pairing Code
                </Button>
              </CardContent>
            </Card>
          )}

          {/* Logs */}
          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="text-sm">Connection Logs</CardTitle>
            </CardHeader>
            <CardContent>
              <ScrollArea className="h-48 w-full rounded-md border bg-slate-50 dark:bg-slate-900 p-2">
                <pre className="text-xs font-mono whitespace-pre-wrap">
                  {logs.length > 0 ? logs.join('\n') : 'Waiting for logs...'}
                </pre>
              </ScrollArea>
            </CardContent>
          </Card>

          {/* Fix Notice */}
          <Alert>
            <Zap className="h-4 w-4" />
            <AlertTitle className="text-xs">cPanel Compatible — Fixed</AlertTitle>
            <AlertDescription className="text-xs">
              WebSocket-only transport prevents &quot;xhr poll error&quot; and &quot;timeout&quot;.
              No HTTP long-polling — works through Apache/cPanel proxy.
              Current transport: <strong>{transportType || 'connecting...'}</strong>
            </AlertDescription>
          </Alert>
        </div>
      </div>
    </div>
  );
}

// ── Meta Cloud API Connect Dialog ──────────────────────────────────────────
function MetaConnectDialog({
  device,
  open,
  onOpenChange,
  onSave,
}: {
  device: Device;
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSave: (metaData: Record<string, string>) => Promise<void>;
}) {
  const [metaBusinessAccountId, setMetaBusinessAccountId] = useState(device.metaBusinessAccountId || '');
  const [metaPhoneNumberId, setMetaPhoneNumberId] = useState(device.metaPhoneNumberId || '');
  const [metaAccessToken, setMetaAccessToken] = useState(device.metaAccessToken || '');
  const [metaWebhookVerifyToken, setMetaWebhookVerifyToken] = useState(device.metaWebhookVerifyToken || '');
  const [saving, setSaving] = useState(false);
  const [testing, setTesting] = useState(false);
  const [testResult, setTestResult] = useState<{ ok: boolean; msg: string } | null>(null);
  const { toast } = useToast();

  useEffect(() => {
    setMetaBusinessAccountId(device.metaBusinessAccountId || '');
    setMetaPhoneNumberId(device.metaPhoneNumberId || '');
    setMetaAccessToken(device.metaAccessToken || '');
    setMetaWebhookVerifyToken(device.metaWebhookVerifyToken || '');
  }, [device]);

  const handleTest = async () => {
    if (!metaAccessToken || !metaPhoneNumberId) {
      toast({ title: 'Error', description: 'Access Token and Phone Number ID are required', variant: 'destructive' });
      return;
    }
    setTesting(true);
    setTestResult(null);
    try {
      const res = await fetch(getGatewayApiUrl(`/api/meta/phone-number/${metaPhoneNumberId}?accessToken=${encodeURIComponent(metaAccessToken)}`));
      const data = await res.json();
      if (data.status) {
        setTestResult({ ok: true, msg: `Verified: ${data.data?.verified_name || data.data?.display_phone_number || 'OK'}` });
      } else {
        setTestResult({ ok: false, msg: data.data?.error?.message || 'Verification failed' });
      }
    } catch (err: any) {
      setTestResult({ ok: false, msg: err.message });
    } finally {
      setTesting(false);
    }
  };

  const handleSave = async () => {
    if (!metaBusinessAccountId || !metaPhoneNumberId || !metaAccessToken) {
      toast({ title: 'Error', description: 'All required fields must be filled', variant: 'destructive' });
      return;
    }
    setSaving(true);
    try {
      await onSave({
        metaBusinessAccountId,
        metaPhoneNumberId,
        metaAccessToken,
        metaWebhookVerifyToken: metaWebhookVerifyToken || `verify_${Date.now()}`,
      });
    } finally {
      setSaving(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-lg">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Cloud className="w-5 h-5 text-blue-500" />
            Meta Cloud API Configuration
          </DialogTitle>
          <DialogDescription>Configure WhatsApp Business API (Meta Cloud API v23.0) for this device.</DialogDescription>
        </DialogHeader>

        <div className="space-y-4 py-2">
          <Alert>
            <Info className="h-4 w-4" />
            <AlertTitle className="text-xs">Prerequisites</AlertTitle>
            <AlertDescription className="text-xs">
              <ul className="list-disc list-inside space-y-1 mt-1">
                <li>Meta App with WhatsApp product at developers.facebook.com</li>
                <li>Phone Number ID and WhatsApp Business Account ID</li>
                <li>Permanent or System User access token</li>
              </ul>
            </AlertDescription>
          </Alert>

          <div className="space-y-2">
            <Label>WhatsApp Business Account ID *</Label>
            <Input
              placeholder="e.g. 1234567890"
              value={metaBusinessAccountId}
              onChange={(e) => setMetaBusinessAccountId(e.target.value)}
            />
          </div>

          <div className="space-y-2">
            <Label>Phone Number ID *</Label>
            <Input
              placeholder="e.g. 9876543210"
              value={metaPhoneNumberId}
              onChange={(e) => setMetaPhoneNumberId(e.target.value)}
            />
          </div>

          <div className="space-y-2">
            <Label>Access Token *</Label>
            <Textarea
              placeholder="Paste your Meta access token here..."
              value={metaAccessToken}
              onChange={(e) => setMetaAccessToken(e.target.value)}
              className="font-mono text-xs"
              rows={3}
            />
          </div>

          <div className="space-y-2">
            <Label>Webhook Verify Token</Label>
            <Input
              placeholder="Auto-generated if empty"
              value={metaWebhookVerifyToken}
              onChange={(e) => setMetaWebhookVerifyToken(e.target.value)}
            />
            <p className="text-xs text-muted-foreground">Used for webhook verification. Leave empty to auto-generate.</p>
          </div>

          {testResult && (
            <Alert variant={testResult.ok ? 'default' : 'destructive'}>
              {testResult.ok ? <CheckCircle2 className="h-4 w-4" /> : <XCircle className="h-4 w-4" />}
              <AlertTitle className="text-xs">{testResult.ok ? 'Verified' : 'Error'}</AlertTitle>
              <AlertDescription className="text-xs">{testResult.msg}</AlertDescription>
            </Alert>
          )}

          <div className="flex gap-2">
            <Button
              variant="outline"
              onClick={handleTest}
              disabled={testing || !metaAccessToken || !metaPhoneNumberId}
              className="flex-1"
            >
              {testing ? <Loader2 className="w-4 h-4 mr-2 animate-spin" /> : <Shield className="w-4 h-4 mr-2" />}
              Test Connection
            </Button>
            <Button
              onClick={handleSave}
              disabled={saving || !metaBusinessAccountId || !metaPhoneNumberId || !metaAccessToken}
              className="flex-1 bg-blue-600 hover:bg-blue-700"
            >
              {saving ? <Loader2 className="w-4 h-4 mr-2 animate-spin" /> : <Link2 className="w-4 h-4 mr-2" />}
              Save & Connect
            </Button>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
