/**
 * WiFi Setup Screen
 *
 * Allows user to configure WiFi on WellNuo ESP32 sensors via Bluetooth.
 * Uses @orbital-systems/react-native-esp-idf-provisioning for BLE communication.
 */

import React, { useState, useEffect, useCallback } from 'react';
import {
  View,
  Text,
  StyleSheet,
  TouchableOpacity,
  TextInput,
  ScrollView,
  ActivityIndicator,
  Alert,
  FlatList,
  Platform,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { router, useLocalSearchParams } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
import { AppColors, Spacing, BorderRadius, FontSizes, FontWeights } from '@/constants/theme';
import {
  espProvisioning,
  type WellNuoDevice,
  type WifiNetwork,
  type ESPDevice,
} from '@/services/espProvisioning';

type Step = 'scan' | 'connect' | 'wifi-select' | 'wifi-password' | 'provisioning' | 'complete';

export default function WifiSetupScreen() {
  const params = useLocalSearchParams<{ lovedOneName?: string; beneficiaryId?: string }>();
  const lovedOneName = params.lovedOneName || '';

  // State
  const [step, setStep] = useState<Step>('scan');
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Devices
  const [devices, setDevices] = useState<WellNuoDevice[]>([]);
  const [selectedDevice, setSelectedDevice] = useState<WellNuoDevice | null>(null);

  // WiFi
  const [wifiNetworks, setWifiNetworks] = useState<WifiNetwork[]>([]);
  const [selectedWifi, setSelectedWifi] = useState<WifiNetwork | null>(null);
  const [wifiPassword, setWifiPassword] = useState('');
  const [showPassword, setShowPassword] = useState(false);

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      espProvisioning.disconnect();
    };
  }, []);

  // Step 1: Scan for BLE devices
  const handleScanDevices = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    setDevices([]);

    try {
      const foundDevices = await espProvisioning.scanForDevices(10000);

      if (foundDevices.length === 0) {
        setError('No WellNuo sensors found. Make sure your sensor is powered on and in setup mode.');
      } else {
        setDevices(foundDevices);
      }
    } catch (err: unknown) {
      const errorMessage = err instanceof Error ? err.message : 'Unknown error';
      setError(`Failed to scan: ${errorMessage}`);
    } finally {
      setIsLoading(false);
    }
  }, []);

  // Auto-scan on mount
  useEffect(() => {
    handleScanDevices();
  }, [handleScanDevices]);

  // Step 2: Connect to selected device
  const handleSelectDevice = async (device: WellNuoDevice) => {
    setSelectedDevice(device);
    setStep('connect');
    setIsLoading(true);
    setError(null);

    try {
      await espProvisioning.connect(device.device);
      setStep('wifi-select');
      // Auto-scan WiFi networks after connecting
      handleScanWifi();
    } catch (err: unknown) {
      const errorMessage = err instanceof Error ? err.message : 'Unknown error';
      setError(`Failed to connect: ${errorMessage}`);
      setStep('scan');
    } finally {
      setIsLoading(false);
    }
  };

  // Step 3: Scan for WiFi networks
  const handleScanWifi = async () => {
    setIsLoading(true);
    setError(null);
    setWifiNetworks([]);

    try {
      const networks = await espProvisioning.scanWifiNetworks();
      // Sort by signal strength
      const sorted = networks.sort((a, b) => b.rssi - a.rssi);
      setWifiNetworks(sorted);

      if (sorted.length === 0) {
        setError('No WiFi networks found. Make sure you are in range of your WiFi network.');
      }
    } catch (err: unknown) {
      const errorMessage = err instanceof Error ? err.message : 'Unknown error';
      setError(`Failed to scan WiFi: ${errorMessage}`);
    } finally {
      setIsLoading(false);
    }
  };

  // Step 4: Select WiFi network
  const handleSelectWifi = (network: WifiNetwork) => {
    setSelectedWifi(network);
    setWifiPassword('');
    setStep('wifi-password');
  };

  // Step 5: Provision with password
  const handleProvision = async () => {
    if (!selectedWifi) return;

    setStep('provisioning');
    setIsLoading(true);
    setError(null);

    try {
      await espProvisioning.provisionWifi(selectedWifi.ssid, wifiPassword);
      setStep('complete');
    } catch (err: unknown) {
      const errorMessage = err instanceof Error ? err.message : 'Unknown error';
      setError(`Failed to configure WiFi: ${errorMessage}`);
      setStep('wifi-password');
    } finally {
      setIsLoading(false);
    }
  };

  // Complete and navigate
  const handleComplete = async () => {
    await espProvisioning.disconnect();
    // Navigate to activate screen or back
    if (params.beneficiaryId) {
      router.replace({
        pathname: '/(auth)/activate',
        params: { beneficiaryId: params.beneficiaryId, lovedOneName },
      });
    } else {
      router.back();
    }
  };

  // Render signal strength icon
  const renderSignalIcon = (rssi: number) => {
    let iconName: 'wifi' | 'wifi-outline' = 'wifi';
    let color = AppColors.success;

    if (rssi < -70) {
      color = AppColors.warning;
    }
    if (rssi < -80) {
      color = AppColors.error;
    }

    return <Ionicons name={iconName} size={20} color={color} />;
  };

  // Step 1: Scan for devices
  if (step === 'scan' || step === 'connect') {
    return (
      <SafeAreaView style={styles.container} edges={['top', 'bottom']}>
        <View style={styles.content}>
          {/* Header */}
          <View style={styles.header}>
            <TouchableOpacity style={styles.backButton} onPress={() => router.back()}>
              <Ionicons name="arrow-back" size={24} color={AppColors.textPrimary} />
            </TouchableOpacity>
            <Text style={styles.title}>WiFi Setup</Text>
            <View style={styles.placeholder} />
          </View>

          {/* Icon */}
          <View style={styles.iconContainer}>
            <Ionicons name="bluetooth" size={64} color={AppColors.primary} />
          </View>

          {/* Instructions */}
          <Text style={styles.instructions}>
            {step === 'connect'
              ? `Connecting to ${selectedDevice?.name}...`
              : 'Searching for WellNuo sensors nearby...'}
          </Text>

          {/* Loading or device list */}
          {isLoading ? (
            <View style={styles.loadingContainer}>
              <ActivityIndicator size="large" color={AppColors.primary} />
              <Text style={styles.loadingText}>
                {step === 'connect' ? 'Connecting...' : 'Scanning for devices...'}
              </Text>
            </View>
          ) : error ? (
            <View style={styles.errorContainer}>
              <Ionicons name="alert-circle" size={48} color={AppColors.error} />
              <Text style={styles.errorText}>{error}</Text>
              <TouchableOpacity style={styles.retryButton} onPress={handleScanDevices}>
                <Text style={styles.retryButtonText}>Retry Scan</Text>
              </TouchableOpacity>
            </View>
          ) : (
            <FlatList
              data={devices}
              keyExtractor={(item) => item.name}
              style={styles.deviceList}
              renderItem={({ item }) => (
                <TouchableOpacity
                  style={styles.deviceItem}
                  onPress={() => handleSelectDevice(item)}
                >
                  <View style={styles.deviceIcon}>
                    <Ionicons name="hardware-chip" size={24} color={AppColors.primary} />
                  </View>
                  <View style={styles.deviceInfo}>
                    <Text style={styles.deviceName}>{item.name}</Text>
                    {item.wellId && (
                      <Text style={styles.deviceMeta}>Sensor ID: {item.wellId}</Text>
                    )}
                  </View>
                  <Ionicons name="chevron-forward" size={20} color={AppColors.textMuted} />
                </TouchableOpacity>
              )}
              ListEmptyComponent={
                <Text style={styles.emptyText}>No devices found</Text>
              }
            />
          )}

          {/* Rescan button */}
          {!isLoading && devices.length > 0 && (
            <TouchableOpacity style={styles.secondaryButton} onPress={handleScanDevices}>
              <Ionicons name="refresh" size={20} color={AppColors.primary} />
              <Text style={styles.secondaryButtonText}>Scan Again</Text>
            </TouchableOpacity>
          )}
        </View>
      </SafeAreaView>
    );
  }

  // Step 3: Select WiFi network
  if (step === 'wifi-select') {
    return (
      <SafeAreaView style={styles.container} edges={['top', 'bottom']}>
        <View style={styles.content}>
          {/* Header */}
          <View style={styles.header}>
            <TouchableOpacity
              style={styles.backButton}
              onPress={async () => {
                await espProvisioning.disconnect();
                setStep('scan');
              }}
            >
              <Ionicons name="arrow-back" size={24} color={AppColors.textPrimary} />
            </TouchableOpacity>
            <Text style={styles.title}>Select WiFi</Text>
            <View style={styles.placeholder} />
          </View>

          {/* Connected device info */}
          <View style={styles.connectedDevice}>
            <Ionicons name="checkmark-circle" size={20} color={AppColors.success} />
            <Text style={styles.connectedText}>Connected to {selectedDevice?.name}</Text>
          </View>

          {/* Instructions */}
          <Text style={styles.instructions}>
            Select the WiFi network for your sensor
          </Text>

          {/* Loading or WiFi list */}
          {isLoading ? (
            <View style={styles.loadingContainer}>
              <ActivityIndicator size="large" color={AppColors.primary} />
              <Text style={styles.loadingText}>Scanning WiFi networks...</Text>
            </View>
          ) : error ? (
            <View style={styles.errorContainer}>
              <Ionicons name="alert-circle" size={48} color={AppColors.error} />
              <Text style={styles.errorText}>{error}</Text>
              <TouchableOpacity style={styles.retryButton} onPress={handleScanWifi}>
                <Text style={styles.retryButtonText}>Retry Scan</Text>
              </TouchableOpacity>
            </View>
          ) : (
            <FlatList
              data={wifiNetworks}
              keyExtractor={(item, index) => `${item.ssid}-${index}`}
              style={styles.deviceList}
              renderItem={({ item }) => (
                <TouchableOpacity
                  style={styles.deviceItem}
                  onPress={() => handleSelectWifi(item)}
                >
                  {renderSignalIcon(item.rssi)}
                  <View style={styles.deviceInfo}>
                    <Text style={styles.deviceName}>{item.ssid}</Text>
                    <Text style={styles.deviceMeta}>{item.auth}</Text>
                  </View>
                  <Ionicons name="chevron-forward" size={20} color={AppColors.textMuted} />
                </TouchableOpacity>
              )}
              ListEmptyComponent={
                <Text style={styles.emptyText}>No WiFi networks found</Text>
              }
            />
          )}

          {/* Rescan button */}
          {!isLoading && (
            <TouchableOpacity style={styles.secondaryButton} onPress={handleScanWifi}>
              <Ionicons name="refresh" size={20} color={AppColors.primary} />
              <Text style={styles.secondaryButtonText}>Scan Again</Text>
            </TouchableOpacity>
          )}
        </View>
      </SafeAreaView>
    );
  }

  // Step 4: Enter WiFi password
  if (step === 'wifi-password' || step === 'provisioning') {
    return (
      <SafeAreaView style={styles.container} edges={['top', 'bottom']}>
        <ScrollView contentContainerStyle={styles.content} keyboardShouldPersistTaps="handled">
          {/* Header */}
          <View style={styles.header}>
            <TouchableOpacity
              style={styles.backButton}
              onPress={() => setStep('wifi-select')}
              disabled={step === 'provisioning'}
            >
              <Ionicons
                name="arrow-back"
                size={24}
                color={step === 'provisioning' ? AppColors.textMuted : AppColors.textPrimary}
              />
            </TouchableOpacity>
            <Text style={styles.title}>Enter Password</Text>
            <View style={styles.placeholder} />
          </View>

          {/* WiFi icon */}
          <View style={styles.iconContainer}>
            <Ionicons name="wifi" size={64} color={AppColors.primary} />
          </View>

          {/* Selected network */}
          <View style={styles.selectedNetwork}>
            <Text style={styles.selectedNetworkLabel}>Network:</Text>
            <Text style={styles.selectedNetworkName}>{selectedWifi?.ssid}</Text>
          </View>

          {/* Password input */}
          <View style={styles.inputContainer}>
            <TextInput
              style={styles.input}
              value={wifiPassword}
              onChangeText={setWifiPassword}
              placeholder="Enter WiFi password"
              placeholderTextColor={AppColors.textMuted}
              secureTextEntry={!showPassword}
              autoCorrect={false}
              editable={step !== 'provisioning'}
            />
            <TouchableOpacity
              style={styles.showPasswordButton}
              onPress={() => setShowPassword(!showPassword)}
            >
              <Ionicons
                name={showPassword ? 'eye-off' : 'eye'}
                size={24}
                color={AppColors.textMuted}
              />
            </TouchableOpacity>
          </View>

          {/* Error */}
          {error && (
            <View style={styles.inlineError}>
              <Ionicons name="alert-circle" size={16} color={AppColors.error} />
              <Text style={styles.inlineErrorText}>{error}</Text>
            </View>
          )}

          {/* Connect button */}
          <TouchableOpacity
            style={[styles.primaryButton, step === 'provisioning' && styles.buttonDisabled]}
            onPress={handleProvision}
            disabled={step === 'provisioning' || !wifiPassword}
          >
            {step === 'provisioning' ? (
              <>
                <ActivityIndicator color={AppColors.white} style={{ marginRight: 8 }} />
                <Text style={styles.primaryButtonText}>Configuring...</Text>
              </>
            ) : (
              <Text style={styles.primaryButtonText}>Connect to WiFi</Text>
            )}
          </TouchableOpacity>

          {/* Note for open networks */}
          {selectedWifi?.auth === 'Open' && (
            <Text style={styles.noteText}>
              This is an open network. You can leave the password empty.
            </Text>
          )}
        </ScrollView>
      </SafeAreaView>
    );
  }

  // Step 5: Complete
  return (
    <SafeAreaView style={styles.container} edges={['top', 'bottom']}>
      <View style={styles.content}>
        {/* Success */}
        <View style={styles.successContainer}>
          <View style={styles.successIcon}>
            <Ionicons name="checkmark-circle" size={80} color={AppColors.success} />
          </View>

          <Text style={styles.successTitle}>WiFi Configured!</Text>
          <Text style={styles.successMessage}>
            Your sensor <Text style={styles.highlight}>{selectedDevice?.name}</Text> is now
            connected to <Text style={styles.highlight}>{selectedWifi?.ssid}</Text>
          </Text>

          {/* Next steps */}
          <View style={styles.nextSteps}>
            <Text style={styles.nextStepsTitle}>What happens next:</Text>
            <View style={styles.stepItem}>
              <Ionicons name="checkmark" size={20} color={AppColors.success} />
              <Text style={styles.stepText}>Sensor will connect to your WiFi</Text>
            </View>
            <View style={styles.stepItem}>
              <Ionicons name="checkmark" size={20} color={AppColors.success} />
              <Text style={styles.stepText}>Data will start syncing to WellNuo</Text>
            </View>
            <View style={styles.stepItem}>
              <Ionicons name="checkmark" size={20} color={AppColors.success} />
              <Text style={styles.stepText}>You'll see updates in the dashboard</Text>
            </View>
          </View>
        </View>

        {/* Complete button */}
        <TouchableOpacity style={styles.primaryButton} onPress={handleComplete}>
          <Text style={styles.primaryButtonText}>Continue</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: AppColors.background,
  },
  content: {
    flex: 1,
    padding: Spacing.lg,
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: Spacing.xl,
  },
  backButton: {
    padding: Spacing.sm,
    marginLeft: -Spacing.sm,
  },
  title: {
    fontSize: FontSizes.xl,
    fontWeight: FontWeights.bold,
    color: AppColors.textPrimary,
  },
  placeholder: {
    width: 40,
  },
  iconContainer: {
    alignItems: 'center',
    marginBottom: Spacing.lg,
  },
  instructions: {
    fontSize: FontSizes.base,
    color: AppColors.textSecondary,
    textAlign: 'center',
    marginBottom: Spacing.lg,
  },
  loadingContainer: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  loadingText: {
    marginTop: Spacing.md,
    fontSize: FontSizes.base,
    color: AppColors.textSecondary,
  },
  errorContainer: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    padding: Spacing.lg,
  },
  errorText: {
    marginTop: Spacing.md,
    fontSize: FontSizes.base,
    color: AppColors.error,
    textAlign: 'center',
  },
  retryButton: {
    marginTop: Spacing.lg,
    paddingHorizontal: Spacing.xl,
    paddingVertical: Spacing.md,
    backgroundColor: AppColors.primary,
    borderRadius: BorderRadius.lg,
  },
  retryButtonText: {
    fontSize: FontSizes.base,
    fontWeight: FontWeights.semibold,
    color: AppColors.white,
  },
  deviceList: {
    flex: 1,
    marginBottom: Spacing.md,
  },
  deviceItem: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: AppColors.surface,
    borderRadius: BorderRadius.lg,
    padding: Spacing.md,
    marginBottom: Spacing.sm,
    gap: Spacing.md,
  },
  deviceIcon: {
    width: 40,
    height: 40,
    borderRadius: 20,
    backgroundColor: `${AppColors.primary}20`,
    alignItems: 'center',
    justifyContent: 'center',
  },
  deviceInfo: {
    flex: 1,
  },
  deviceName: {
    fontSize: FontSizes.base,
    fontWeight: FontWeights.medium,
    color: AppColors.textPrimary,
  },
  deviceMeta: {
    fontSize: FontSizes.sm,
    color: AppColors.textMuted,
    marginTop: 2,
  },
  emptyText: {
    fontSize: FontSizes.base,
    color: AppColors.textMuted,
    textAlign: 'center',
    marginTop: Spacing.xl,
  },
  secondaryButton: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: Spacing.sm,
    paddingVertical: Spacing.md,
    borderRadius: BorderRadius.lg,
    borderWidth: 1,
    borderColor: AppColors.primary,
  },
  secondaryButtonText: {
    fontSize: FontSizes.base,
    fontWeight: FontWeights.medium,
    color: AppColors.primary,
  },
  connectedDevice: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: Spacing.sm,
    backgroundColor: `${AppColors.success}15`,
    paddingVertical: Spacing.sm,
    paddingHorizontal: Spacing.md,
    borderRadius: BorderRadius.md,
    marginBottom: Spacing.md,
  },
  connectedText: {
    fontSize: FontSizes.sm,
    color: AppColors.success,
    fontWeight: FontWeights.medium,
  },
  selectedNetwork: {
    alignItems: 'center',
    marginBottom: Spacing.lg,
  },
  selectedNetworkLabel: {
    fontSize: FontSizes.sm,
    color: AppColors.textMuted,
  },
  selectedNetworkName: {
    fontSize: FontSizes.lg,
    fontWeight: FontWeights.semibold,
    color: AppColors.textPrimary,
    marginTop: 4,
  },
  inputContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: AppColors.surface,
    borderRadius: BorderRadius.lg,
    borderWidth: 1,
    borderColor: AppColors.border,
    marginBottom: Spacing.md,
  },
  input: {
    flex: 1,
    paddingHorizontal: Spacing.lg,
    paddingVertical: Spacing.md,
    fontSize: FontSizes.base,
    color: AppColors.textPrimary,
  },
  showPasswordButton: {
    padding: Spacing.md,
  },
  inlineError: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: Spacing.sm,
    marginBottom: Spacing.md,
  },
  inlineErrorText: {
    fontSize: FontSizes.sm,
    color: AppColors.error,
    flex: 1,
  },
  primaryButton: {
    flexDirection: 'row',
    backgroundColor: AppColors.primary,
    paddingVertical: Spacing.lg,
    borderRadius: BorderRadius.lg,
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: Spacing.md,
  },
  buttonDisabled: {
    opacity: 0.7,
  },
  primaryButtonText: {
    fontSize: FontSizes.lg,
    fontWeight: FontWeights.semibold,
    color: AppColors.white,
  },
  noteText: {
    fontSize: FontSizes.sm,
    color: AppColors.textMuted,
    textAlign: 'center',
    marginTop: Spacing.md,
  },
  successContainer: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  successIcon: {
    marginBottom: Spacing.xl,
  },
  successTitle: {
    fontSize: FontSizes['2xl'],
    fontWeight: FontWeights.bold,
    color: AppColors.textPrimary,
    marginBottom: Spacing.md,
  },
  successMessage: {
    fontSize: FontSizes.base,
    color: AppColors.textSecondary,
    textAlign: 'center',
    marginBottom: Spacing.xl,
    paddingHorizontal: Spacing.lg,
  },
  highlight: {
    fontWeight: FontWeights.bold,
    color: AppColors.primary,
  },
  nextSteps: {
    width: '100%',
    backgroundColor: AppColors.surface,
    borderRadius: BorderRadius.lg,
    padding: Spacing.lg,
  },
  nextStepsTitle: {
    fontSize: FontSizes.base,
    fontWeight: FontWeights.semibold,
    color: AppColors.textPrimary,
    marginBottom: Spacing.md,
  },
  stepItem: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: Spacing.md,
    marginBottom: Spacing.sm,
  },
  stepText: {
    fontSize: FontSizes.sm,
    color: AppColors.textSecondary,
    flex: 1,
  },
});
