import React, { useState, forwardRef, useImperativeHandle, useRef } from 'react';
import { Col, Row, Grid } from 'react-native-easy-grid';
import range from 'lodash/range';
import * as Animatable from 'react-native-animatable';
import * as Haptics from 'expo-haptics';

import styles from './styles';
import Button from './Button';
import Dots from './Dots';
import { TYPE } from '../constants';
import { themes } from '../../../constants/colors';
import { PASSCODE_LENGTH } from '../../../constants/localAuthentication';
import LockIcon from './LockIcon';
import Title from './Title';
import Subtitle from './Subtitle';

interface IPasscodeBase {
	theme: string;
	type: string;
	previousPasscode: string;
	title: string;
	subtitle: string;
	showBiometry: string;
	onEndProcess: Function;
	onError: Function;
	onBiometryPress(): void;
}

const Base = forwardRef(({
	theme, type, onEndProcess, previousPasscode, title, subtitle, onError, showBiometry, onBiometryPress
}: IPasscodeBase, ref) => {
	const rootRef = useRef<any>();
	const dotsRef = useRef<any>();
	const [passcode, setPasscode] = useState('');

	const clearPasscode = () => setPasscode('');

	const wrongPasscode = () => {
		clearPasscode();
		dotsRef?.current?.shake(500);
		Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
	};

	const animate = (animation: string, duration = 500) => {
		rootRef?.current?.[animation](duration);
	};

	const onPressNumber = (text: string) => setPasscode((p) => {
		const currentPasscode = p + text;
		if (currentPasscode?.length === PASSCODE_LENGTH) {
			switch (type) {
				case TYPE.CHOOSE:
					onEndProcess(currentPasscode);
					break;
				case TYPE.CONFIRM:
					if (currentPasscode !== previousPasscode) {
						onError();
					} else {
						onEndProcess(currentPasscode);
					}
					break;
				case TYPE.ENTER:
					onEndProcess(currentPasscode);
					break;
				default:
					break;
			}
		}
		return currentPasscode;
	});

	const onPressDelete = () => setPasscode((p) => {
		if (p?.length > 0) {
			const newPasscode = p.slice(0, -1);
			return newPasscode;
		}
		return '';
	});

	useImperativeHandle(ref, () => ({
		wrongPasscode, animate, clearPasscode
	}));

	return (
		<Animatable.View ref={rootRef} style={styles.container}>
			<Grid style={[styles.grid, { backgroundColor: themes[theme].passcodeBackground }]}>
				<LockIcon theme={theme} />
				<Title text={title} theme={theme} />
				<Subtitle text={subtitle!} theme={theme} />
				<Row style={styles.row}>
					<Animatable.View ref={dotsRef}>
						<Dots passcode={passcode} theme={theme} length={PASSCODE_LENGTH} />
					</Animatable.View>
				</Row>
				<Row style={[styles.row, styles.buttonRow]}>
					{range(1, 4).map((i: any) => (
						<Col key={i} style={styles.colButton}>
							<Button text={i} theme={theme} onPress={onPressNumber} />
						</Col>
					))}
				</Row>
				<Row style={[styles.row, styles.buttonRow]}>
					{range(4, 7).map((i: any) => (
						<Col key={i} style={styles.colButton}>
							<Button text={i} theme={theme} onPress={onPressNumber} />
						</Col>
					))}
				</Row>
				<Row style={[styles.row, styles.buttonRow]}>
					{range(7, 10).map((i: any) => (
						<Col key={i} style={styles.colButton}>
							<Button text={i} theme={theme} onPress={onPressNumber} />
						</Col>
					))}
				</Row>
				<Row style={[styles.row, styles.buttonRow]}>
					{showBiometry
						? (
							<Col style={styles.colButton}>
								<Button icon='fingerprint' theme={theme} onPress={onBiometryPress} />
							</Col>
						)
						: <Col style={styles.colButton} />}
					<Col style={styles.colButton}>
						<Button text='0' theme={theme} onPress={onPressNumber} />
					</Col>
					<Col style={styles.colButton}>
						<Button icon='backspace' theme={theme} onPress={onPressDelete} />
					</Col>
				</Row>
			</Grid>
		</Animatable.View>
	);
});

export default Base;