import {Dimensions, NativeModules, NativeSyntheticEvent, StyleSheet, View, ViewProps} from 'react-native'
import React from 'react'
import {default as NativeCameraView} from './internal/DocvSdkViewNativeComponent'
import {CaptureRegion, DetectionType} from './types'
const {TruliooCaptureSdkModule} = NativeModules

type CaptureRegionEvent = NativeSyntheticEvent<
  Readonly<{
    captureRegion: string
  }>
>

/**
 * Component to render and control camera functionality, can have animations displayed around the capture area, the background masking coloration and transparency adjusted.
 */
export interface ITruliooCamera {
  id: string
  detectionType?: DetectionType
  /**
   * To resume the camera feed again after a capture
   */
  resumeCamera: () => void
}

export interface CameraProps extends ViewProps {
  /**
   * A Hex code formatted string: #RRGGBBAA for coloring the masking around the capture area
   */
  backgroundColor?: string

  /**
   * Animation component to be rendered around the document capture area.
   * If nothing is passed in, the SDK will render the default animations.
   * If this is set as undefined, nothing will be rendered
   */
  animationComponent?: React.ReactNode

  /**
   * Callback function that triggers upon rendering of the camera.
   * This gives the point coordinates of the capture region area of the SDK
   * for both document and selfie capture.
   */
  onCaptureRegionChange?: (captureRegion: CaptureRegion) => void
}

export class TruliooCamera implements ITruliooCamera {
  id: string
  detectionType: DetectionType | undefined

  constructor(id: string, detectionType: DetectionType | undefined = undefined) {
    this.id = id
    this.detectionType = detectionType
  }

  View: React.FC<CameraProps> = ({animationComponent = null, onCaptureRegionChange = () => {}, ...rest}: CameraProps) => {
    const nativeProps = {
      cameraId: this.id,
      shouldShowAnimation: animationComponent == null,
      ...rest,
    }

    const screenWidth = Dimensions.get('window').width
    let animationWidth = screenWidth - this.styles.animationPadding.padding

    if (this.detectionType === DetectionType.BIOMETRIC_SELFIE) {
      animationWidth = screenWidth * 0.8
    }

    const animationFrame = animationComponent ? <View style={[this.styles.animation, {width: animationWidth}]}>{animationComponent}</View> : null

    const onCaptureRegionChanged = (event: CaptureRegionEvent) => {
      const captureRegion = JSON.parse(event.nativeEvent.captureRegion) as CaptureRegion
      onCaptureRegionChange(captureRegion)
    }

    return (
      <View style={this.styles.container}>
        <NativeCameraView
          nativeCameraViewProps={JSON.stringify(nativeProps)}
          onCaptureRegionChanged={onCaptureRegionChanged}
          style={this.styles.camera}
        />
        {animationFrame}
      </View>
    )
  }

  styles = StyleSheet.create({
    camera: {
      width: '100%',
      height: '100%',
    },
    container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
    },
    animation: {
      position: 'absolute',
      alignItems: 'center',
      zIndex: 1,
      aspectRatio: 1,
    },
    animationPadding: {
      padding: 38,
    },
  })

  resumeCamera = () => {
    TruliooCaptureSdkModule.resumeCamera(this.id)
  }
}
