import { useCallback, useEffect, useMemo, useState } from 'react';
import { ActivityIndicator, Pressable, RefreshControl, ScrollView, StyleSheet, Text, TextInput, View } from 'react-native';
import { useLocalSearchParams } from 'expo-router';

import { renderPrintLabel } from '@/src/lib/api';
import {
  connectNimbotDevice,
  disconnectNimbotDevice,
  getActiveNimbotConnection,
  printNimbotEncodedLabel,
  scanNimbotDevices,
} from '@/src/lib/nimbot';
import { useAuth } from '@/src/providers/auth-provider';

const PRIMARY = '#69c350';

type ListedDevice = {
  id: string;
  name: string;
  rssi: number | null;
};

export default function NimbotScreen() {
  const { token } = useAuth();
  const params = useLocalSearchParams<{
    itemName?: string;
    itemId?: string;
    serial?: string;
    customerName?: string;
    customerInventoryId?: string;
    serialNumber?: string;
  }>();

  const [devices, setDevices] = useState<ListedDevice[]>([]);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [scanning, setScanning] = useState(false);
  const [connectingId, setConnectingId] = useState<string | null>(null);
  const [printing, setPrinting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [info, setInfo] = useState<string | null>(null);

  const [manualLabelText, setManualLabelText] = useState('');

  const activeConnection = getActiveNimbotConnection();

  const normalizedInventoryId = useMemo(() => String(params.customerInventoryId || params.itemId || '').trim(), [params.customerInventoryId, params.itemId]);
  const normalizedSerial = useMemo(() => String(params.serialNumber || params.serial || '').trim(), [params.serial, params.serialNumber]);

  const prefilledText = useMemo(() => {
    const parts = [params.itemName, normalizedInventoryId ? `ID: ${normalizedInventoryId}` : null, normalizedSerial ? `SN: ${normalizedSerial}` : null]
      .filter(Boolean)
      .map((value) => String(value));
    return parts.join(' | ');
  }, [normalizedInventoryId, normalizedSerial, params.itemName]);

  useEffect(() => {
    if (!prefilledText) return;
    setManualLabelText(prefilledText);
  }, [prefilledText]);

  const loadDevices = useCallback(async () => {
    setError(null);
    setInfo(null);
    setScanning(true);

    try {
      const result = await scanNimbotDevices();
      setDevices(result);
      if (result.length === 0) {
        setInfo('Kein Nimbot gefunden. Drucker einschalten und nah an das iPhone halten.');
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Nimbot-Suche fehlgeschlagen.');
    } finally {
      setScanning(false);
      setLoading(false);
      setRefreshing(false);
    }
  }, []);

  useEffect(() => {
    void loadDevices();
  }, [loadDevices]);

  async function onRefresh() {
    setRefreshing(true);
    await loadDevices();
  }

  async function onConnect(deviceId: string) {
    setConnectingId(deviceId);
    setError(null);
    setInfo(null);

    try {
      const connected = await connectNimbotDevice(deviceId);
      setInfo(`Verbunden mit ${connected.device.name}`);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Verbindung fehlgeschlagen.');
    } finally {
      setConnectingId(null);
    }
  }

  async function onDisconnect() {
    setError(null);
    setInfo(null);

    try {
      await disconnectNimbotDevice();
      setInfo('Verbindung getrennt.');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Trennen fehlgeschlagen.');
    }
  }

  async function onPrint() {
    setError(null);
    setInfo(null);
    setPrinting(true);

    try {
      if (!token) {
        throw new Error('Nicht angemeldet. Bitte erneut einloggen.');
      }

      const text = manualLabelText.trim();
      if (!text) {
        throw new Error('Bitte Label-Inhalt eingeben.');
      }

      const context: Record<string, unknown> = {
        text,
        name: params.itemName || text,
      };

      if (normalizedInventoryId) {
        context.customerInventoryId = normalizedInventoryId;
      }
      if (normalizedSerial) {
        context.serialNumber = normalizedSerial;
      }
      if (params.customerName) {
        context.customerName = String(params.customerName);
      }

      const rendered = await renderPrintLabel(token, context, 584, 354);

      await printNimbotEncodedLabel(rendered.encoded, {
        density: 5,
        copies: 1,
        labelType: 1,
      });
      setInfo('Label wurde an den Nimbot gesendet.');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Label konnte nicht gedruckt werden.');
    } finally {
      setPrinting(false);
    }
  }

  const connectedId = activeConnection?.device.id || null;

  return (
    <ScrollView
      contentContainerStyle={styles.container}
      refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}>
      <View style={styles.card}>
        <Text style={styles.title}>Nimbot M2</Text>
        <Text style={styles.subtitle}>Bluetooth-Anbindung (Beta)</Text>

        {connectedId ? (
          <Text style={styles.connectedText}>Verbunden: {activeConnection?.device.name || connectedId}</Text>
        ) : (
          <Text style={styles.disconnectedText}>Nicht verbunden</Text>
        )}

        <View style={styles.actionRow}>
          <Pressable
            style={[styles.primaryButton, scanning ? styles.buttonDisabled : null]}
            onPress={() => void loadDevices()}
            disabled={scanning}>
            <Text style={styles.primaryButtonText}>{scanning ? 'Suche...' : 'Geräte suchen'}</Text>
          </Pressable>

          <Pressable
            style={[styles.secondaryButton, !connectedId ? styles.buttonDisabled : null]}
            onPress={() => void onDisconnect()}
            disabled={!connectedId}>
            <Text style={styles.secondaryButtonText}>Trennen</Text>
          </Pressable>
        </View>

        <TextInput
          value={manualLabelText}
          onChangeText={setManualLabelText}
          placeholder="Label-Inhalt für nächsten Druck"
          placeholderTextColor="#9ca3af"
          style={styles.input}
          multiline
        />

        <Pressable
          style={[styles.primaryButton, (!connectedId || printing) ? styles.buttonDisabled : null]}
          onPress={() => void onPrint()}
          disabled={!connectedId || printing}>
          <Text style={styles.primaryButtonText}>{printing ? 'Drucke...' : 'Label drucken'}</Text>
        </Pressable>

        {info ? <Text style={styles.info}>{info}</Text> : null}
        {error ? <Text style={styles.error}>{error}</Text> : null}
      </View>

      <View style={styles.card}>
        <Text style={styles.sectionTitle}>Gefundene Geräte</Text>

        {loading ? (
          <View style={styles.loadingBox}>
            <ActivityIndicator />
            <Text style={styles.loadingText}>Suche läuft...</Text>
          </View>
        ) : null}

        {!loading && devices.length === 0 ? <Text style={styles.empty}>Keine Geräte gefunden.</Text> : null}

        {!loading &&
          devices.map((device) => {
            const isConnected = connectedId === device.id;
            const isConnecting = connectingId === device.id;

            return (
              <View key={device.id} style={styles.deviceRow}>
                <View style={styles.deviceInfo}>
                  <Text style={styles.deviceName} numberOfLines={1}>
                    {device.name}
                  </Text>
                  <Text style={styles.deviceMeta} numberOfLines={1}>
                    {device.id}
                    {typeof device.rssi === 'number' ? ` · RSSI ${device.rssi}` : ''}
                  </Text>
                </View>

                <Pressable
                  style={[
                    styles.connectButton,
                    isConnected ? styles.connectButtonConnected : null,
                    isConnecting ? styles.buttonDisabled : null,
                  ]}
                  onPress={() => void onConnect(device.id)}
                  disabled={isConnecting || isConnected}>
                  <Text style={styles.connectButtonText}>
                    {isConnected ? 'Verbunden' : isConnecting ? 'Verbinde...' : 'Verbinden'}
                  </Text>
                </Pressable>
              </View>
            );
          })}
      </View>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 16,
    gap: 12,
    backgroundColor: '#f9fafb',
  },
  card: {
    backgroundColor: '#ffffff',
    borderRadius: 12,
    borderWidth: 1,
    borderColor: '#e5e7eb',
    padding: 12,
    gap: 10,
  },
  title: {
    color: '#111827',
    fontSize: 18,
    fontWeight: '700',
  },
  subtitle: {
    color: '#6b7280',
    fontSize: 13,
  },
  connectedText: {
    color: '#166534',
    fontSize: 13,
    fontWeight: '600',
  },
  disconnectedText: {
    color: '#6b7280',
    fontSize: 13,
  },
  actionRow: {
    flexDirection: 'row',
    gap: 8,
  },
  input: {
    borderWidth: 1,
    borderColor: '#d1d5db',
    borderRadius: 10,
    paddingHorizontal: 12,
    paddingVertical: 10,
    minHeight: 72,
    textAlignVertical: 'top',
    color: '#111827',
    backgroundColor: '#ffffff',
  },
  primaryButton: {
    minHeight: 40,
    borderRadius: 10,
    backgroundColor: PRIMARY,
    paddingHorizontal: 12,
    alignItems: 'center',
    justifyContent: 'center',
  },
  primaryButtonText: {
    color: '#ffffff',
    fontWeight: '700',
    fontSize: 13,
  },
  secondaryButton: {
    minHeight: 40,
    borderRadius: 10,
    borderWidth: 1,
    borderColor: '#d1d5db',
    backgroundColor: '#ffffff',
    paddingHorizontal: 12,
    alignItems: 'center',
    justifyContent: 'center',
  },
  secondaryButtonText: {
    color: '#111827',
    fontWeight: '600',
    fontSize: 13,
  },
  sectionTitle: {
    color: '#111827',
    fontSize: 16,
    fontWeight: '700',
  },
  deviceRow: {
    borderWidth: 1,
    borderColor: '#e5e7eb',
    borderRadius: 10,
    padding: 10,
    flexDirection: 'row',
    alignItems: 'center',
    gap: 10,
  },
  deviceInfo: {
    flex: 1,
    minWidth: 0,
  },
  deviceName: {
    color: '#111827',
    fontSize: 14,
    fontWeight: '600',
  },
  deviceMeta: {
    color: '#6b7280',
    fontSize: 12,
    marginTop: 2,
  },
  connectButton: {
    minHeight: 36,
    borderRadius: 9,
    borderWidth: 1,
    borderColor: PRIMARY,
    paddingHorizontal: 12,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#eff9ea',
  },
  connectButtonConnected: {
    borderColor: '#9ca3af',
    backgroundColor: '#f3f4f6',
  },
  connectButtonText: {
    color: '#3d7a30',
    fontSize: 12,
    fontWeight: '700',
  },
  loadingBox: {
    padding: 12,
    alignItems: 'center',
    gap: 8,
  },
  loadingText: {
    color: '#6b7280',
  },
  empty: {
    color: '#6b7280',
    fontSize: 13,
    paddingVertical: 4,
  },
  info: {
    color: '#1d4ed8',
    fontSize: 13,
  },
  error: {
    color: '#dc2626',
    fontSize: 13,
  },
  buttonDisabled: {
    opacity: 0.6,
  },
});
