import React, { Component } from 'react';
import { Image, StyleSheet, View } from 'react-native';
import * as creditCard from 'credit-card';
import moment from 'moment';
import * as t from 'tcomb-form-native';
import { creditCardAboveLabelTemplate, creditCardFloatingLabelTemplate, creditCardHiddenLabelTemplate, creditCardInlineLabelTemplate, Form, FormLabelPosition, maskedInputAboveLabelTemplate, maskedInputFloatingLabelTemplate, maskedInputHiddenLabelTemplate, maskedInputInlineLabelTemplate } from './Form';
function getFieldTemplates(labelPosition) {
    switch (labelPosition) {
        case FormLabelPosition.Above:
            return {
                creditCard: creditCardAboveLabelTemplate,
                maskedInput: maskedInputAboveLabelTemplate
            };
        case FormLabelPosition.Floating:
            return {
                creditCard: creditCardFloatingLabelTemplate,
                maskedInput: maskedInputFloatingLabelTemplate
            };
        case FormLabelPosition.Hidden:
            return {
                creditCard: creditCardHiddenLabelTemplate,
                maskedInput: maskedInputHiddenLabelTemplate
            };
        case FormLabelPosition.Inline:
            return {
                creditCard: creditCardInlineLabelTemplate,
                maskedInput: maskedInputInlineLabelTemplate
            };
        default:
            return {
                creditCard: creditCardInlineLabelTemplate,
                maskedInput: maskedInputInlineLabelTemplate
            };
    }
}
const NameType = t.refinement(t.String, (str) => {
    return str.length >= 4;
});
const FIELD_TYPES = t.struct({
    number: NameType,
    name: t.String,
    expirationDate: t.String,
    cvv: t.String
});
const FIELD_TYPES_HIDE_NAME = t.struct({
    number: NameType,
    expirationDate: t.String,
    cvv: t.String
});
const styles = StyleSheet.create({
    cardImages: {
        flexDirection: 'row',
        justifyContent: 'space-around',
        marginBottom: 5,
        marginTop: 5
    },
    inlineForm: {
        alignSelf: 'stretch',
        flexDirection: 'row'
    },
    inlineFormWrap: {
        width: '40%',
        maxWidth: 250
    }
});
export class CreditCardForm extends Component {
    constructor() {
        super(...arguments);
        this.fieldOptions = (labelPosition) => {
            const defaultFieldOptions = {
                name: {
                    label: 'Name',
                    placeholder: 'Name',
                    autoCorrect: false,
                    error: 'Please enter your name'
                },
                number: {
                    auto: 'none',
                    label: 'Card Number',
                    placeholder: 'Credit Card Number',
                    returnKeyType: 'next',
                    autoCorrect: false,
                    autoCapitalize: 'none',
                    keyboardType: 'phone-pad',
                    error: 'Please enter a valid card number',
                    template: getFieldTemplates(labelPosition).creditCard,
                    config: {
                        cardImageStyle: {
                            marginLeft: 2,
                            marginTop: -1
                        },
                        cardImageWidth: 26,
                        creditCardTypeImages: this.props.supportedCards,
                        defaultCardImage: this.props.defaultCardImage
                    }
                },
                cvv: {
                    error: 'Invalid CSC',
                    keyboardType: 'phone-pad',
                    label: 'CSC',
                    placeholder: 'CSC',
                    template: getFieldTemplates(labelPosition).maskedInput,
                    config: {
                        type: 'custom',
                        options: {
                            mask: '9999'
                        }
                    }
                },
                expirationDate: {
                    error: 'Invalid MM/YY',
                    template: getFieldTemplates(labelPosition).maskedInput,
                    label: 'Exp. Date',
                    placeholder: 'Exp. Date (MM/YY)',
                    keyboardType: 'phone-pad',
                    config: {
                        type: 'custom',
                        options: {
                            mask: '99/99'
                        }
                    }
                }
            };
            return Object.assign({}, defaultFieldOptions, this.props.fieldsOptions);
        };
        this.getValue = () => {
            return this.formRef.getValue();
        };
        this._saveFormRef = (ref) => {
            this.formRef = ref;
        };
        this.validate = () => {
            if (this.formRef) {
                const validation = this.formRef.validate();
                if (validation.isValid()) {
                    return this.validateCreditCard(this.formRef.getValue());
                }
                else {
                    return false;
                }
            }
            return true;
        };
        this.validateCreditCard = (value) => {
            const expirationDate = moment(value.expirationDate, 'MM/YY');
            const validationResult = creditCard.validate({
                cardType: creditCard.determineCardType(value.number),
                number: value.number,
                cvv: value.cvv,
                expiryMonth: expirationDate.month() + 1,
                expiryYear: expirationDate.year()
            });
            let valid = true;
            if (!validationResult.validCardNumber) {
                this.formRef.getComponent('number').setState({ hasError: true });
                valid = false;
            }
            if (!validationResult.validExpiryMonth || !validationResult.validExpiryYear ||
                creditCard.isExpired(expirationDate.month() + 1, expirationDate.year())) {
                this.formRef.getComponent('expirationDate').setState({ hasError: true });
                valid = false;
            }
            if (!validationResult.validCvv) {
                this.formRef.getComponent('cvv').setState({ hasError: true });
                valid = false;
            }
            return valid;
        };
    }
    render() {
        const cards = this.props.supportedCards || [];
        return (<View style={this.props.style}>
        <View style={[styles.cardImages, this.props.supportedCardsStyle, { marginBottom: 15 }]}>
          {this.props.supportedCardsLabel}
          {cards.map(({ type, image }) => {
            return (<Image accessibilityLabel={type} key={`supported-card-${type}`} source={image} style={this.props.supportedIconStyle}/>);
        })}
        </View>
        <Form fieldsOptions={this.fieldOptions(this.props.labelPosition)} fieldsStyleConfig={this.props.fieldsStyleConfig} fieldsTypes={this.props.hideName ? FIELD_TYPES_HIDE_NAME : FIELD_TYPES} ref={this._saveFormRef} value={this.props.value} onChange={this.props.onChange} labelPosition={this.props.labelPosition}/>
      </View>);
    }
}
CreditCardForm.defaultProps = {
    labelPosition: FormLabelPosition.Inline
};
//# sourceMappingURL=CreditCardForm.js.map