import React, { Fragment, useRef, useState } from 'react';
import {
  ActivityIndicator,
  Platform,
  StyleSheet,
  Text,
  View,
} from 'react-native';
import { WebView, type WebViewMessageEvent } from 'react-native-webview';
import { serverSdkBaseUrl } from '../../lib/config';

type AgreementSubmittedType = {
  agreementId: string;
};

type OmnipayProps = {
  color: string;
  env: 'dev' | 'prod';
  publicKey: string;
  phoneNumber?: string;
  customerRef?: string;
  amount: number;
  lenderId?: string;
  feesId?: string;
  sublimitId?: string;
  onAgreementAccepted: ({ agreementId }: AgreementSubmittedType) => void;
  onClose?: () => void;
};

type Status = 'error' | 'loading' | 'success';

export const PaylaterAgreement = ({
  color,
  env,
  publicKey,
  phoneNumber,
  onAgreementAccepted,
  customerRef,
  amount,
  lenderId,
  feesId,
  sublimitId,
  onClose,
}: OmnipayProps): JSX.Element => {
  const webviewRef = useRef<WebView>(null);
  const [webviewStatus, setWebviewStatus] = useState<Status>('loading');
  const webHost = getWebHost();
  const webUrl = getWebUrl();

  const onWebviewMount = `
        window.nativeOs = ${Platform.OS};
        true;
      `;

  function getWebHost() {
    return serverSdkBaseUrl[env];
  }

  function getWebUrl() {
    const themeColor = color.includes('#') ? color.split('#')[1] : color;
    return `${webHost}paylater/agreement?theme=${themeColor}&publicKey=${publicKey}&phoneNumber=${
      phoneNumber || ''
    }&customerRef=${customerRef || ''}&amount=${amount}&lenderId=${
      lenderId || ''
    }&feesId=${feesId || ''}&sublimitId=${sublimitId || ''}`;
  }

  async function onWebviewMessage(e: WebViewMessageEvent) {
    try {
      if (e.nativeEvent && e.nativeEvent.data) {
        const eventData = JSON.parse(e.nativeEvent.data);
        const { dataKey, dataValue } = eventData;

        if (dataKey === 'agreement.accepted') {
          onAgreementAccepted({
            agreementId: dataValue.agreementId,
          });
          return;
        }

        if (dataKey === 'close.agreement') {
          if (onClose) {
            onClose();
          }
          return;
        }

        return;
      }
    } catch (error) {}
  }

  if (!publicKey.includes('OMNIPUBKEY_')) {
    return <Text>Invalid public key</Text>;
  }

  if (color.length < 3) {
    return <Text>Invalid color</Text>;
  }

  if (!['dev', 'prod'].includes(env)) {
    return <Text>Invalid environment</Text>;
  }

  if (!customerRef) {
    if (!phoneNumber) {
      return <Text>Phone number is required</Text>;
    }
    if (phoneNumber?.length < 10) {
      return <Text>Invalid phone number</Text>;
    }
  }

  if (!amount || isNaN(Number(amount)) || Number(amount) <= 0) {
    return <Text>Amount is required and should be greater than 0</Text>;
  }

  return (
    <Fragment>
      <View style={styles.full}>
        <WebView
          source={{
            uri: webUrl,
          }}
          style={styles.webview}
          injectedJavaScriptBeforeContentLoaded={onWebviewMount}
          onMessage={onWebviewMessage}
          ref={webviewRef}
          onLoadEnd={() => setWebviewStatus('success')}
        />
        {webviewStatus === 'loading' && (
          <View style={styles.webviewLoader}>
            <ActivityIndicator size="small" color={color} />
          </View>
        )}
      </View>
    </Fragment>
  );
};

const styles = StyleSheet.create({
  hide: {
    display: 'none',
  },
  full: {
    flex: 1,
    width: '100%',
    height: '100%',
  },
  webview: {
    flex: 1,
    width: '100%',
    height: '100%',
  },
  webviewLoader: {
    zIndex: 3,
    backgroundColor: 'white',
    alignItems: 'center',
    justifyContent: 'center',
    flex: 1,
    width: '100%',
    height: '100%',
    position: 'absolute',
    top: 0,
    left: 0,
  },
});
