import { useState, useEffect, useRef } from 'react';
import { sprintf, __, getLocaleData } from '@wordpress/i18n';
import { registerPaymentMethod } from '@woocommerce/blocks-registry';
import { decodeEntities } from '@wordpress/html-entities';
import { getSetting } from '@woocommerce/settings';
import { 
    CheckboxControl,
    FormFileUpload,
    __experimentalNumberControl as NumberControl,
    RadioControl,
    SelectControl,
    TextControl,
} from '@wordpress/components';

import "flatpickr/dist/themes/airbnb.css";
import Flatpickr from "react-flatpickr";
import { German } from 'flatpickr/dist/l10n/de.js';
import { French } from 'flatpickr/dist/l10n/fr.js';
import { Italian } from 'flatpickr/dist/l10n/it.js';
import { Bulgarian } from 'flatpickr/dist/l10n/bg.js';
import { Czech } from 'flatpickr/dist/l10n/cs.js';
import { Danish } from 'flatpickr/dist/l10n/da.js';
import { Greek } from 'flatpickr/dist/l10n/gr.js';
import { Spanish } from 'flatpickr/dist/l10n/es.js';
import { Estonian } from 'flatpickr/dist/l10n/et.js';
import { Croatian } from 'flatpickr/dist/l10n/hr.js';
import { Hungarian } from 'flatpickr/dist/l10n/hu.js';
import { Icelandic } from 'flatpickr/dist/l10n/is.js';
import { Lithuanian } from 'flatpickr/dist/l10n/lt.js';
import { Latvian } from 'flatpickr/dist/l10n/lv.js';
import { Macedonian } from 'flatpickr/dist/l10n/mk.js';
import { Norwegian } from 'flatpickr/dist/l10n/no.js';
import { Dutch } from 'flatpickr/dist/l10n/nl.js';
import { Polish } from 'flatpickr/dist/l10n/pl.js';
import { Portuguese } from 'flatpickr/dist/l10n/pt.js';
import { Romanian } from 'flatpickr/dist/l10n/ro.js';
import { Russian } from 'flatpickr/dist/l10n/ru.js';
import { Slovak } from 'flatpickr/dist/l10n/sk.js';
import { Slovenian } from 'flatpickr/dist/l10n/sl.js';
import { Serbian } from 'flatpickr/dist/l10n/sr.js';
import { Swedish } from 'flatpickr/dist/l10n/sv.js';
import { Turkish } from 'flatpickr/dist/l10n/tr.js';

import '../../scss/front/blocks.scss';

const settings = getSetting( 'cembrapay_data', {} );

const fieldLabels = cembrapayBlocks && cembrapayBlocks.fieldLabels ? cembrapayBlocks.fieldLabels : {};

const defaultLabel = __(
	'CembraPay',
	'woo-gutenberg-products-block'
);

const label = decodeEntities( fieldLabels.title || settings.title ) || defaultLabel;

const legendStyle = {
    // fontSize: '11px',
    fontWeight: 500,
    lineHeight: 1.4,
    // textTransform: 'uppercase',
    display: 'block',
    marginBottom: 'calc(8px)',
    marginTop: 'calc(8px)',
    padding: '0px'
};

const salutationOptions = [
    { 
        label: fieldLabels.salutation_field_label_female || settings.salutation_field_label_female ||  __( 'Female', 'cembrapay' ), 
        value: 'F' 
    },
    { 
        label: fieldLabels.salutation_field_label_male || settings.salutation_field_label_male ||  __( 'Male', 'cembrapay' ), 
        value: 'M' 
    },
    { 
        label: fieldLabels.salutation_field_label_other || settings.salutation_field_label_other ||  __( 'Other', 'cembrapay' ), 
        value: 'N' 
    }
];

const invoiceTypeEmailLabel = fieldLabels.invoice_via_email || settings.invoice_via_email || __('Invoice sent via email to: {email}', 'cembrapay');
const invoiceTypePostLabel = fieldLabels.invoice_via_post || settings.invoice_via_post || __('Invoice sent by Post (4.25 CHF per letter) to: {address}', 'cembrapay');

const installments = (company) => {

    let installments = [];

    if( 
        ( 'yes' == settings.use_cembrapay_invoice && ( 'all' == settings.cembrapay_invoice_for || 'b2c' == settings.cembrapay_invoice_for && ! company )
        || ( 'yes' == settings.use_cembrapay_invoice && 'b2b' == settings.cembrapay_invoice_for && company ) ) 
        // || ( ( 'no' == settings.use_installments || 0 == settings.use_installments ) && ! company )
    ) {
        installments.push( {
            label: fieldLabels.cembrapay_invoice_template || settings.cembrapay_invoice_template,
            value: 'CEMBRAPAY-INVOICE'
        } );
    }

    if( 
        ( 'yes' == settings.use_installments_full && ( 'all' == settings.installments_full_for || 'b2c' == settings.installments_full_for && ! company )
        || ( 'yes' == settings.use_installments_full && 'b2b' == settings.installments_full_for && company ) ) 
        // || ( ( 'no' == settings.use_installments || 0 == settings.use_installments ) && company )
    ) {
        installments.push( {
            label: fieldLabels.installments_full_template || settings.installments_full_template,
            value: 'SINGLE-INVOICE'
        } );
    }

    if( 
        ( 'yes' == settings.use_installments_3 && ( 'all' == settings.installments_3_for || 'b2c' == settings.installments_3_for && ! company )
        || ( 'yes' == settings.use_installments_3 && 'b2b' == settings.installments_3_for && company ) ) 
    ) {
        installments.push( {
            label: fieldLabels.installments_3_template || settings.installments_3_template,
            value: 'INSTALLMENT_3'
        } );
    }

    if( 
        ( 'yes' == settings.use_installments_4 && ( 'all' == settings.installments_4_for || 'b2c' == settings.installments_4_for && ! company )
        || ( 'yes' == settings.use_installments_4 && 'b2b' == settings.installments_4_for && company ) ) 
    ) {
        installments.push( {
            label: fieldLabels.installments_4_template || settings.installments_4_template,
            value: 'INSTALLMENT_4'
        } );
    }

    if( 
        ( 'yes' == settings.use_installments_6 && ( 'all' == settings.installments_6_for || 'b2c' == settings.installments_6_for && ! company )
        || ( 'yes' == settings.use_installments_6 && 'b2b' == settings.installments_6_for && company ) ) 
    ) {
        installments.push( {
            label: fieldLabels.installments_6_template || settings.installments_6_template,
            value: 'INSTALLMENT_6'
        } );
    }

    if( 
        ( 'yes' == settings.use_installments_12 && ( 'all' == settings.installments_12_for || 'b2c' == settings.installments_12_for && ! company )
        || ( 'yes' == settings.use_installments_12 && 'b2b' == settings.installments_12_for && company ) ) 
    ) {
        installments.push( {
            label: fieldLabels.installments_12_template || settings.installments_12_template,
            value: 'INSTALLMENT_12'
        } );
    }

    if( 
        ( 'yes' == settings.use_installments_24 && ( 'all' == settings.installments_24_for || 'b2c' == settings.installments_24_for && ! company )
        || ( 'yes' == settings.use_installments_24 && 'b2b' == settings.installments_24_for && company ) ) 
    ) {
        installments.push( {
            label: fieldLabels.installments_24_template || settings.installments_24_template,
            value: 'INSTALLMENT_24'
        } );
    }

    if( 
        ( 'yes' == settings.use_installments_36 && ( 'all' == settings.installments_36_for || 'b2c' == settings.installments_36_for && ! company )
        || ( 'yes' == settings.use_installments_36 && 'b2b' == settings.installments_36_for && company ) ) 
    ) {
        installments.push( {
            label: fieldLabels.installments_36_template || settings.installments_36_template,
            value: 'INSTALLMENT_36'
        } );
    }

    if( 
        ( 'yes' == settings.use_installments_48 && ( 'all' == settings.installments_48_for || 'b2c' == settings.installments_48_for && ! company )
        || ( 'yes' == settings.use_installments_48 && 'b2b' == settings.installments_48_for && company ) ) 
    ) {
        installments.push( {
            label: fieldLabels.installments_48_template || settings.installments_48_template,
            value: 'INSTALLMENT_48'
        } );
    }

    return installments;

}

const termsAndConditions = () => {

    const lang = cembrapayBlocks.locale;

    switch( lang ) {
        case 'de':
            return (
                <>
                Ich akzeptiere die <a href="https://www.cembrapay.ch/de/terms/CP" target="_blank" rel="noopener noreferrer">AGB</a> und die <a href="https://www.cembrapay.ch/de/privacy" target="_blank" rel="noopener noreferrer">Datenschutzerklärung von CembraPay</a>.
                </>
            )
        break;
        case 'fr':
            return (
                <>
                J'ai pris connaissance et j\'accepte les <a href="https://www.cembrapay.ch/fr/terms/CP" target="_blank" rel="noopener noreferrer">CG</a> et <a href="https://www.cembrapay.ch/fr/privacy" target="_blank" rel="noopener noreferrer">la politique de confidentialité de CembraPay</a>.
                </>
            )
        break;
        case 'it':
            return (
                <>
                Confermo di aver letto e di accettare accettato le <a href="https://www.cembrapay.ch/it/terms/CP" target="_blank" rel="noopener noreferrer">CG</a> und die <a href="https://www.cembrapay.ch/it/privacy" target="_blank" rel="noopener noreferrer">l\'Informativa sulla privacy di CembraPay</a>.
                </>
            )
        break;
        default:
            return (
                <>
                I have read and accept the <a href="https://www.cembrapay.ch/en/terms/CP" target="_blank" rel="noopener noreferrer">Terms and Conditions</a> and the <a href="https://www.cembrapay.ch/en/privacy" target="_blank" rel="noopener noreferrer">Data Privacy Policy of CembraPay</a>.
                </>
            );
    }

}

/**
 * Content component
 */
const Content = (props) => {

    // console.log(cembrapayBlocks);
    
    const { eventRegistration, emitResponse } = props;
	const { onPaymentProcessing } = eventRegistration;
    const { company } = props.billing.billingAddress;

    const billingAddress = props.billing.billingAddress.address_1 + ' ' + props.billing.billingAddress.address_2 + ', ' + props.billing.billingAddress.postcode + ' ' + props.billing.billingAddress.city + ', ' + props.billing.billingAddress.state + ', ' + props.billing.billingAddress.country;

    const allInstallments = installments( props.billing.billingData.company );

    const [ salutation, setSalutation ] = useState( 'F' );
    const [ birthdate, setBirthdate ] = useState( '' );
    const [ birthdateDay, setBirthdateDay ] = useState( '' );
    const [ birthdateMonth, setBirthdateMonth ] = useState( '' );
    const [ birthdateYear, setBirthdateYear ] = useState( '' );
    const [ companyReg, setCompanyReg ] = useState( '' );
    const [ installment, setInstallment ] = useState( allInstallments.length ? allInstallments[0].value : '' );
    const [ invoiceType, setInvoiceType ] = useState( '' );
    const [ termsAgreed, setTermsAgreed ] = useState( false );

    const fpRef = useRef();

    const today = new Date();

	useEffect( () => {
		const unsubscribe = onPaymentProcessing( async () => {

            let requestAllInstallments;
            let requestInstallment;

            if( 0 == settings.use_installments || 'no' == settings.use_installments ) {
                requestAllInstallments = installments( props.billing.billingData.company );
                requestInstallment = requestAllInstallments.length ? requestAllInstallments[0].value : '';
            }

			// Here we can do any processing we need, and then emit a response.
			// For example, we might validate a custom field, or perform an AJAX request, and then emit a response indicating it is valid or not.
			return {
                type: emitResponse.responseTypes.SUCCESS,
                meta: {
                    paymentMethodData: {
                        'billing_company': props.billing.billingData.company,
                        'cembrapay_salutation': salutation,
                        'cembrapay_birthdate_day': birthdateDay,
                        'cembrapay_birthdate_month': birthdateMonth,
                        'cembrapay_birthdate_year': birthdateYear,
                        'cembrapay_birthdate': birthdate,
                        'cembrapay_company_reg': companyReg,
                        'cembrapay_installment': requestInstallment || installment,
                        'cembrapay_invoice_type': invoiceType,
                        'cembrapay-tc': termsAgreed
                    },
                },
            };

			// return {
			// 	type: emitResponse.responseTypes.ERROR,
			// 	message: 'There was an error',
			// };
		} );
		// Unsubscribes when this component is unmounted.
		return () => {
			unsubscribe();
		};
	}, [
		emitResponse.responseTypes.ERROR,
		emitResponse.responseTypes.SUCCESS,
		onPaymentProcessing,
        salutation,
        birthdateDay,
        birthdateMonth,
        birthdateYear,
        birthdate,
        companyReg,
        installment,
        invoiceType,
        termsAgreed
	] );

    const lang = cembrapay.locale || 'en';
    
    const locales = {
        de: German,
        fr: French,
        it: Italian,
        bg: Bulgarian,
        cs: Czech,
        da: Danish,
        gr: Greek,
        es: Spanish,
        et: Estonian,
        hr: Croatian,
        hu: Hungarian,
        is: Icelandic,
        lt: Lithuanian,
        lv: Latvian,
        mk: Macedonian,
        no: Norwegian,
        nl: Dutch,
        pl: Polish,
        pt: Portuguese,
        ro: Romanian,
        ru: Russian,
        sk: Slovak,
        sl: Slovenian,
        sr: Serbian,
        sv: Swedish,
        tr: Turkish
    };
    
    const selectedLocale = locales[lang] || flatpickr.l10ns.default;
    
    return (
        <>
        <p>{ settings.description || '' }</p>
        { 2 == settings.auth_type &&
            <>
            { 1 == settings.use_salutation_field && 
                <div className="cembrapay-salutation">
                { 1 == settings.salutation_field_functionality &&
                <>
                <label style={legendStyle}>{ fieldLabels.salutation_field_label || settings.salutation_field_label ||  __( 'Salutation', 'cembrapay' ) }</label>
                <SelectControl
                    label={ null }
                    value={ salutation }
                    options={ salutationOptions }
                    onChange={ ( value ) => setSalutation( value ) }
                    __next40pxDefaultSize
                    __nextHasNoMarginBottom
                />
                </>
                }
                { 2 == settings.salutation_field_functionality &&
                <>
                <p style={ legendStyle }>
                    { fieldLabels.salutation_field_label || settings.salutation_field_label ||  __( 'Salutation', 'cembrapay' ) }
                    { 1 == settings.salutation_field_required && <span className="required">*</span> }
                </p>
                <div className="cembrapay-fieldset-no-margin-top">
                    <RadioControl
                        selected={ salutation }
                        options={ salutationOptions }
                        onChange={ ( value ) => setSalutation( value ) }
                    />
                </div>
                </>
                }
                </div>
            }
            { 1 == settings.use_birthdate_field && ! props.billing.billingData.company &&
                <div className="cembrapay-birthdate">
                { 1 == settings.birthdate_field_type &&
                <>
                <p style={ legendStyle }>{ fieldLabels.birthdate_field_label || settings.birthdate_field_label || __('Birthdate', 'cembrapay') }</p>
                <div className="cembrapay-fieldset-no-margin-top">
                    <fieldset>
                        <div style={{
                            display: 'flex',
                            flexWrap: 'wrap',
                            marginBottom: '10px'
                        }}>
                            <div className="cembrapay_birthdate_day_container" style={ { width: '20%' } }>
                                <legend style={ legendStyle }>
                                    { fieldLabels.birthdate_field_day_label || settings.birthdate_field_day_label || __('Day', 'cembrapay') } 
                                    <span className="required">*</span>
                                </legend>
                                <NumberControl
                                    __next40pxDefaultSize
                                    isShiftStepEnabled={ true }
                                    onChange={ value => {
                                        value = parseInt( value ) < 0 ? 0 : value;
                                        setBirthdateDay( value );
                                    } }
                                    shiftStep={ 1 }
                                    value={ birthdateDay }
                                />
                            </div>
                            <div className="cembrapay_birthdate_month_container" style={ { width: '20%' } }>
                                <legend style={ legendStyle }>
                                    { fieldLabels.birthdate_field_month_label || settings.birthdate_field_month_label || __('Month', 'cembrapay') } 
                                    <span className="required">*</span>
                                </legend>
                                <NumberControl
                                    __next40pxDefaultSize
                                    isShiftStepEnabled={ true }
                                    onChange={ value => {
                                        value = parseInt( value ) < 0 ? 0 : value;
                                        setBirthdateMonth( value );
                                    } }
                                    shiftStep={ 1 }
                                    value={ birthdateMonth }
                                />
                            </div>
                            <div className="cembrapay_birthdate_year_container" style={ { width: '50%' } }>
                                <legend style={ legendStyle }>
                                    { fieldLabels.birthdate_field_year_label || settings.birthdate_field_year_label || __('Year', 'cembrapay') } 
                                    <span className="required">*</span>
                                </legend>
                                <NumberControl
                                    __next40pxDefaultSize
                                    isShiftStepEnabled={ true }
                                    onChange={ value => {
                                        value = parseInt( value ) < 0 ? 0 : value;
                                        setBirthdateYear( value );
                                    } }
                                    shiftStep={ 1 }
                                    value={ birthdateYear }
                                />
                            </div>
                        </div>
                    </fieldset>
                </div>
                </>
                }
                { 2 == settings.birthdate_field_type &&
                <>
                <p style={ legendStyle }>
                    { fieldLabels.birthdate_field_label || settings.birthdate_field_label || __('Birthdate', 'cembrapay') } 
                    <span className="required">*</span>
                </p>
                <div className="cembrapay-fieldset-no-margin-top">
                    <fieldset>
                        <Flatpickr
                            ref={fpRef}
                            value={birthdate}
                            options={
                                {
                                    dateFormat: cembrapayBlocks.dateFormat || 'd.m.Y',
                                    defaultDate: cembrapayBlocks.defaultBirthdate ? cembrapayBlocks.defaultBirthdate : '1990-01-01',
                                    maxDate: new Date(today.getFullYear(), today.getMonth(), today.getDate()),
                                    locale: {
                                        ...selectedLocale,
                                        firstDayOfWeek: 1
                                    }
                                }
                            }
                            onOpen={() => {
                                if ( ! birthdate && fpRef.current && fpRef.current.flatpickr) {
                                    fpRef.current.flatpickr.jumpToDate(cembrapayBlocks.defaultBirthdate || '1990-01-01');
                                }
                            }}
                            onChange={(_, dateStr) => {
                                setBirthdate(dateStr);
                            }}
                        />
                    </fieldset>
                </div>
                </>
                }
                </div>
            }
            </>
        }
        { 1 == settings.use_company_reg_field && company && 
            <>
            <p style={ legendStyle }>
                { fieldLabels.company_reg_field_label || settings.company_reg_field_label || __('Company registration number', 'cembrapay') } 
                { 1 == settings.company_reg_field_required && <span className="required">*</span> }
            </p>
            <div className="cembrapay-fieldset-no-margin-top">
                <fieldset>
                    <TextControl
                        value={ companyReg }
                        onChange={ ( value ) => setCompanyReg( value ) }
                        __next40pxDefaultSize
                        __nextHasNoMarginBottom
                    />
                </fieldset>
            </div>
            </>
        }
        { 1 == settings.use_installments &&
            <>
            <p style={ legendStyle }>
                { fieldLabels.installments_intro_text || settings.installments_intro_text || __('Please choose your payment plan', 'cembrapay') } 
            </p>
            <div className="cembrapay-fieldset-no-margin-top">
                <RadioControl
                    selected={ installment }
                    options={ installments(company) }
                    onChange={ ( value ) => setInstallment( value ) }
                />
            </div>
            </>
        }
        { 1 == settings.use_invoice_type && 
            <>
            <p style={ legendStyle }>
                { fieldLabels.invoice_type_intro_text || settings.invoice_type_intro_text || __('Select invoice type', 'cembrapay') } 
            </p>
            <RadioControl
                selected={ invoiceType }
                options={ [
                    {
                        label: invoiceTypeEmailLabel.replace( '{email}', props.billing.billingData.email ),
                        value: 'EMAIL'
                    },
                    {
                        label: invoiceTypePostLabel.replace( '{address}', billingAddress ),
                        value: 'POSTAL'
                    }
                ]}
                onChange={ ( value ) => setInvoiceType( value ) }
            />
            </>
        }
        { 2 == settings.auth_type &&
            <div className="cembrapay-tc">
                <CheckboxControl
                    __nextHasNoMarginBottom
                    label={termsAndConditions()}
                    checked={ termsAgreed }
                    onChange={ termsAgreed => setTermsAgreed( termsAgreed ) }
                />
            </div>
        }
        </>
    )
	return decodeEntities( settings.description || '' );
};
/**
 * Label component
 *
 * @param {*} props Props from payment API.
 */
const Label = ( props ) => {
	const { PaymentMethodLabel } = props.components;
	return (
        <>
        { 1 == settings.display_gateway_logo && cembrapayBlocks.logo && 
        <>
        <img src={ cembrapayBlocks.logo } style={{ marginRight: '5px' }} /> 
        </>
        }
        <PaymentMethodLabel text={ label } />
        </>
    );
};

/**
 * Dummy payment method config object.
 */
const Dummy = {
	name: "cembrapay",
	label: <Label />,
	content: <Content />,
	edit: <Content />,
	canMakePayment: () => true,
	ariaLabel: label,
	supports: {
		features: settings.supports,
	},
};

registerPaymentMethod( Dummy );
