import CameraFlip from "components/Camera/Buttons/CameraFlip";
import Close from "components/Camera/Buttons/Close";
import Flash from "components/Camera/Buttons/Flash";
import Location from "components/Camera/Buttons/Location";
import PhotoLibraryIcon from "components/Camera/Buttons/PhotoLibraryIcon";
import TakePhoto from "components/Camera/Buttons/TakePhoto";
import Zoom from "components/Camera/Buttons/Zoom";
import TabletButtons from "components/Camera/TabletButtons";
import { View } from "components/styledComponents";
import React from "react";
import type { GestureResponderEvent, ViewStyle } from "react-native";
import DeviceInfo from "react-native-device-info";
import type { CameraDeviceFormat, TakePhotoOptions } from "react-native-vision-camera";
import { useLayoutPrefs } from "sharedHooks";

import AIDebugButton from "./AIDebugButton";

const isTablet = DeviceInfo.isTablet();

interface Props {
  handleZoomButtonPress: ( _event: GestureResponderEvent ) => void;
  confidenceThreshold?: number;
  cropRatio?: string;
  flipCamera: ( _event: GestureResponderEvent ) => void;
  fps?: number;
  handleClose: ( ) => void;
  hasFlash: boolean;
  modelLoaded: boolean;
  numStoredResults?: number;
  rotatableAnimatedStyle: ViewStyle;
  debugFormat?: CameraDeviceFormat;
  // Those five are debug only so I don't bother with types
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
  setConfidenceThreshold?: Function;
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
  setCropRatio?: Function;
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
  setFPS?: Function;
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
  setNumStoredResults?: Function;
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
  changeDebugFormat?: Function;
  showPrediction: boolean;
  showZoomButton: boolean;
  takePhoto: () => Promise<void>;
  takePhotoOptions: TakePhotoOptions;
  takingPhoto: boolean;
  toggleFlash: ( _event: GestureResponderEvent ) => void;
  zoomTextValue: string;
  useLocation: boolean;
  toggleLocation: ( _event: GestureResponderEvent ) => void;
  deleteSentinelFile: ( ) => Promise<void>;
}

const AICameraButtons = ( {
  handleZoomButtonPress,
  changeDebugFormat,
  confidenceThreshold,
  cropRatio,
  debugFormat,
  flipCamera,
  fps,
  handleClose,
  hasFlash,
  modelLoaded,
  numStoredResults,
  rotatableAnimatedStyle,
  setConfidenceThreshold,
  setCropRatio,
  setFPS,
  setNumStoredResults,
  showPrediction,
  showZoomButton,
  takePhoto,
  takePhotoOptions,
  takingPhoto,
  toggleFlash,
  zoomTextValue,
  useLocation,
  toggleLocation,
  deleteSentinelFile
}: Props ) => {
  const { isDefaultMode } = useLayoutPrefs();
  if ( isTablet ) {
    return (
      <TabletButtons
        handleZoomButtonPress={handleZoomButtonPress}
        disabled={!modelLoaded || takingPhoto}
        disabledPhotoLibrary={takingPhoto}
        flipCamera={flipCamera}
        hasFlash={hasFlash}
        hasPhotoLibraryButton
        rotatableAnimatedStyle={rotatableAnimatedStyle}
        showPrediction={showPrediction}
        showZoomButton={showZoomButton}
        takePhoto={takePhoto}
        takePhotoOptions={takePhotoOptions}
        toggleFlash={toggleFlash}
        zoomTextValue={zoomTextValue}
        useLocation={useLocation}
        toggleLocation={toggleLocation}
        isDefaultMode={isDefaultMode}
        deleteSentinelFile={deleteSentinelFile}
      />
    );
  }
  return (
    <View className="bottom-10 absolute right-5 left-5" pointerEvents="box-none">
      <View
        className="absolute left-0 bottom-[17px] h-full justify-end flex gap-y-9"
        pointerEvents="box-none"
      >
        <View><Close handleClose={handleClose} /></View>
      </View>
      <View
        className="absolute right-0 bottom-[6px] h-full justify-end items-end flex gap-y-9"
        pointerEvents="box-none"
      >
        <AIDebugButton
          confidenceThreshold={confidenceThreshold}
          setConfidenceThreshold={setConfidenceThreshold}
          fps={fps}
          setFPS={setFPS}
          numStoredResults={numStoredResults}
          setNumStoredResults={setNumStoredResults}
          cropRatio={cropRatio}
          setCropRatio={setCropRatio}
          debugFormat={debugFormat}
          changeDebugFormat={changeDebugFormat}
          // TODO: The following are just to get accessibility tests to pass...
          // without making anything truly accessible. The test seems to think
          // AIDebugButton is itself not accessible, but it's really
          // complaining about the sliders within. If the sliders make it into
          // production, they'll need to be made to pass that test.
          accessibilityRole="adjustable"
          accessibilityValue={{ min: 0, max: 100, now: 50 }}
        />
        {!isDefaultMode && (
          <View>
            <Location
              toggleLocation={toggleLocation}
              useLocation={useLocation}
              rotatableAnimatedStyle={rotatableAnimatedStyle}
            />
          </View>
        )}
        {showZoomButton && (
          <View>
            <Zoom
              zoomTextValue={zoomTextValue}
              handleZoomButtonPress={handleZoomButtonPress}
              rotatableAnimatedStyle={rotatableAnimatedStyle}
            />
          </View>
        )}
        <View>
          <Flash
            toggleFlash={toggleFlash}
            hasFlash={hasFlash}
            takePhotoOptions={takePhotoOptions}
            rotatableAnimatedStyle={rotatableAnimatedStyle}
          />
        </View>
        <View><CameraFlip flipCamera={flipCamera} /></View>
        <View>
          <PhotoLibraryIcon
            rotatableAnimatedStyle={rotatableAnimatedStyle}
            disabled={takingPhoto}
            deleteSentinelFile={deleteSentinelFile}
          />
        </View>
      </View>
      <View className="flex-row justify-center items-center w-full" pointerEvents="box-none">
        <TakePhoto
          disabled={!modelLoaded || takingPhoto}
          takePhoto={takePhoto}
          showPrediction={showPrediction}
        />
      </View>
    </View>
  );
};

export default AICameraButtons;
