import RNBluetoothClassic, {
  BluetoothDevice,
} from "react-native-bluetooth-classic";

import { Ionicons } from "@expo/vector-icons";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import {
  Alert,
  AppState,
  Linking,
  PermissionsAndroid,
  Platform,
  Text,
  View,
} from "react-native";
import {
  CustomBottomSheet,
  CustomBottomSheetHandle,
  CustomBottomSheetSelect,
  CustomBottomSheetTitle,
  TabButton,
} from "../..";

export function BluetoothDeviceSelectModal({
  onDeviceSelected,
  handleSheetClose,
}: {
  onDeviceSelected: (deviceId: string) => Promise<void>;
  handleSheetClose?: () => void;
}) {
  const [bondedDevices, setBondedDevices] = useState<BluetoothDevice[]>(
    []
  );
  const [connectedDevice, setConnectedDevice] =
    useState<BluetoothDevice | null>(null);
  const [isBluetoothPermissionsGranted, setIsBluetoothPermissionsGranted] =
    useState(false);
  const [isBluetoothEnabled, setIsBluetoothEnabled] = useState(false);
  const [isPrinting, setIsPrinting] = useState(false);

  const bondedDeviceList = useMemo(() => {
    return bondedDevices.map((device) => ({
      id: device.id,
      icon: "bluetooth" as const,
      name: device.name || device.address,
      subTitle: device.address,
    }));
  }, [bondedDevices]);

  const sheetRef = useRef<CustomBottomSheetHandle>(null);

  const requestBluetoothPermissions = async (): Promise<boolean> => {
    if (Platform.OS !== "android") return true;

    const sdkInt = Platform.Version;
    const permissions =
      sdkInt >= 31
        ? [
            PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
            PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
          ]
        : [PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION];

    const granted = await PermissionsAndroid.requestMultiple(permissions);

    const deniedPermissions = Object.entries(granted).filter(
      ([_, status]) => status !== PermissionsAndroid.RESULTS.GRANTED
    );
    if (deniedPermissions.length === 0) {
      setIsBluetoothPermissionsGranted(true);
      return true;
    }

    return false;
  };

  const loadBluetoothDevices = async () => {
    try {
      const isEnabled = await RNBluetoothClassic.isBluetoothEnabled();
      if (isEnabled) setIsBluetoothEnabled(isEnabled);
      else {
        setIsBluetoothEnabled(false);
      }
      const bonded = await RNBluetoothClassic.getBondedDevices();
      setBondedDevices(bonded);

      for (const device of bonded) {
        try {
          const isConnected = await device.isConnected();

          if (isConnected) {
            setConnectedDevice(device);
            break;
          }
        } catch (error) {
          console.error("Error checking device connection:", error);
        }
      }
    } catch (error) {
      console.error("Error fetching bonded devices:", error);
      return;
    }
  };

  function checkPermission() {
    requestBluetoothPermissions().then((granted) => {
      if (granted) {
        loadBluetoothDevices();
      }
    });
  }

  useEffect(() => {
    RNBluetoothClassic.isBluetoothEnabled().then((isEnabled) => {
      setIsBluetoothEnabled(isEnabled);
      if (isEnabled) {
        checkPermission();
      }
    });
    const listener = RNBluetoothClassic.onStateChanged((state) => {
      if (state.enabled) {
        setIsBluetoothEnabled(true);
        checkPermission();
        return;
      }
      setIsBluetoothEnabled(false);
      setBondedDevices([]);
      setConnectedDevice(null);
    });
    const sub = AppState.addEventListener("change", (state) => {
      if (state === "active") {
        checkPermission();
      }
    });
    return () => {
      listener.remove();
      sub.remove();
    };
  }, []);

  const handleOnPress = useCallback(
    (deviceId: string) => {
      setIsPrinting(true);
      const device = bondedDevices.find((d) => d.id === deviceId);
      if (device) {
        onDeviceSelected(device.id).then(async () => {
          setIsPrinting(false);
          if (sheetRef.current) {
            sheetRef.current.hideSheet();
          }
        });
      } else {
        Alert.alert(
          "Devices Not Found",
          "Selected device not found in bonded devices.",
          [
            {
              text: "Ok",
              onPress: () => {
                sheetRef.current?.hideSheet();
                setIsPrinting(false);
              },
            },
          ]
        );
      }
    },
    [bondedDevices, onDeviceSelected, connectedDevice]
  );

  return (
    <CustomBottomSheet
      snapPoints={["90"]}
      handleSheetClose={handleSheetClose}
      ref={sheetRef}
    >
      <CustomBottomSheetTitle
        title="Print with Bluetooth"
        subTitle="Select a Bluetooth device to print"
      />
      {!connectedDevice &&
        bondedDevices.length === 0 &&
        isBluetoothPermissionsGranted &&
        isBluetoothEnabled && (
          <View className="flex items-center justify-center p-4">
            <Text>No paired device found</Text>
            <Text>Pair your Bluetooth printer from phone settings</Text>
          </View>
        )}

      {!isBluetoothPermissionsGranted && isBluetoothEnabled && (
        <TabButton onPress={() => Linking.openSettings()}>
          <Text>Open Settings</Text>
        </TabButton>
      )}
      {!isBluetoothEnabled && (
        <TabButton onPress={() => Linking.openSettings()}>
          <Text>Enable Bluetooth</Text>
        </TabButton>
      )}
      {isPrinting ? (
        <View className="flex items-center justify-center p-4 animate-spin">
          <Ionicons
            name="reload"
            style={{
              transform: [{ rotate: "0deg" }],
            }}
            size={24}
            color="black"
          />
        </View>
      ) : (
        <CustomBottomSheetSelect
          activeItem={connectedDevice?.id}
          items={bondedDeviceList}
          handleOnPress={handleOnPress}
        />
      )}
    </CustomBottomSheet>
  );
}
