import React, { useEffect, useRef, useState } from 'react';
import {
  AccessibilityProps,
  HostComponent,
  LayoutAnimation,
} from 'react-native';
import {
  PaymentMethodMessagingElementAppearance,
  PaymentMethodMessagingElementState,
} from '../types/components/PaymentMethodMessagingElementComponent';
import { PaymentMethodMessagingElementConfiguration } from '../types/components/PaymentMethodMessagingElementComponent';
import NativePaymentMethodMessagingElement, {
  NativeProps,
} from '../specs/NativePaymentMethodMessagingElement';
import { addListener } from '../events';

export interface Props extends AccessibilityProps {
  appearance?: PaymentMethodMessagingElementAppearance;
  configuration: PaymentMethodMessagingElementConfiguration;
  onStateChange?(event: PaymentMethodMessagingElementState): void;
}

/**
 * This feature is in Public Preview. It may not be feature complete and have breaking changes as we develop and update functionality.
 * Payment Method Messaging Element to display promotional information about available BNPL plans.
 *
 * @example
 * ```tsx
 * <PaymentMethodMessagingElement
 *    appearance={{
 *      style: Style.Dark,
 *      textColor: '#FFFFFF',
 *      infoIconColor: '#CCCCCC',
 *      font: {
 *        family: 'Courier',
 *        size: 16,
 *      },
 *    }}
 *    configuration={{
 *      currencyCode: 'usd',
 *      amount: 5000,
 *      countryCode: 'US',
 *    }}
 *    onStateChange={(event) => {
 *      console.log('PMME loaded with result:', event);
 *    }
 * />
 * ```
 * @param __namedParameters Props
 * @returns JSX.Element
 * @category ReactComponents
 */
export const PaymentMethodMessagingElement = ({
  appearance,
  configuration,
  onStateChange,
  ...props
}: Props) => {
  const viewRef = useRef<React.ComponentRef<HostComponent<NativeProps>>>(null);

  const [height, setHeight] = useState<number | undefined>();

  useEffect(() => {
    // listen for height changes
    const sub = addListener(
      'paymentMethodMessagingElementDidUpdateHeight',
      ({ height: h }) => {
        LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
        setHeight(h);
      }
    );
    return () => sub.remove();
  });

  useEffect(() => {
    // listen for load complete
    const sub = addListener(
      'paymentMethodMessagingElementConfigureResult',
      ({ status: s }) => {
        let state: PaymentMethodMessagingElementState;

        if (s === 'loaded') {
          state = { status: 'loaded' };
        } else if (s === 'loading') {
          state = { status: 'loading' };
        } else if (s === 'no_content') {
          state = { status: 'no_content' };
        } else {
          state = {
            status: 'failed',
            error: new Error(
              'Failed to configure payment method messaging element'
            ),
          };
        }
        onStateChange?.(state);
      }
    );
    return () => sub.remove();
  }, [onStateChange]);

  return (
    <NativePaymentMethodMessagingElement
      appearance={appearance}
      style={[{ width: '100%', height: height }]}
      configuration={configuration}
      {...props}
      ref={viewRef}
    />
  );
};
