( function ( wp ) {
    if ( ! wp || ! wp.blocks || ! wp.element ) {
        return;
    }

    const el = wp.element.createElement;
    const registerBlockType = wp.blocks.registerBlockType;
    const __ = wp.i18n.__;

    const useState = wp.element.useState;
    const useEffect = wp.element.useEffect;
    const apiFetch = wp.apiFetch;

    const InspectorControls = ( wp.blockEditor && wp.blockEditor.InspectorControls ) || null;
    const PanelBody = wp.components.PanelBody;
    const ToggleControl = wp.components.ToggleControl;
    const TextControl = wp.components.TextControl;
    const SelectControl = wp.components.SelectControl;
    const Button = wp.components.Button;
    const Spinner = wp.components.Spinner;
    const ServerSideRender = wp.serverSideRender;

    function buildLocationOptions( locations, currentValue ) {
        const opts = [
            { label: __( 'Primary location (Local SEO settings)', 'wp-seo-next' ), value: 'primary' },
            { label: __( 'Business info from settings', 'wp-seo-next' ), value: 'settings' },
        ];

        if ( Array.isArray( locations ) ) {
            locations.forEach( function ( item ) {
                if ( ! item || ! item.id ) {
                    return;
                }
                const title = item.title ? item.title : '#' + item.id;
                const label = title + ' (#' + item.id + ')';
                opts.push( { label: label, value: String( item.id ) } );
            } );
        }

        // Ensure current value exists as an option (custom slug/id).
        const has = opts.some( function ( o ) {
            return o.value === currentValue;
        } );
        if ( currentValue && ! has ) {
            opts.unshift( { label: __( 'Custom:', 'wp-seo-next' ) + ' ' + currentValue, value: currentValue } );
        }

        return opts;
    }

    registerBlockType( 'wpsn/nap', {
        title: __( 'Business info (NAP)', 'wp-seo-next' ),
        icon: 'id',
        category: 'widgets',
        description: __( 'Output consistent business NAP (name, address, phone) from Local SEO settings/locations.', 'wp-seo-next' ),
        attributes: {
            location: { type: 'string', default: 'primary' },
            template: { type: 'string', default: 'plain' },
            microdata: { type: 'boolean', default: false },
            showName: { type: 'boolean', default: true },
            showAddress: { type: 'boolean', default: true },
            showPhone: { type: 'boolean', default: true },
            showEmail: { type: 'boolean', default: false },
            showHours: { type: 'boolean', default: false },
            showMapLink: { type: 'boolean', default: false },
            layout: { type: 'string', default: 'stack' },
        },
        supports: {
            html: false,
        },
        edit: function ( props ) {
            const attrs = props.attributes || {};
            const setAttributes = props.setAttributes;

            const loc = attrs.location || 'primary';
            const tpl = attrs.template || 'plain';
            const layout = attrs.layout || 'stack';

            const [ locItems, setLocItems ] = useState( [] );
            const [ locLoading, setLocLoading ] = useState( true );
            const [ locError, setLocError ] = useState( '' );

            const loadLocations = function () {
                if ( ! apiFetch ) {
                    setLocLoading( false );
                    return;
                }

                setLocLoading( true );
                setLocError( '' );

                apiFetch( { path: '/wpsn/v1/local/locations?per_page=200&page=1' } )
                    .then( function ( res ) {
                        const items = res && res.items ? res.items : [];
                        setLocItems( items );
                        setLocLoading( false );
                    } )
                    .catch( function ( err ) {
                        const msg = err && err.message ? err.message : __( 'Failed to load locations.', 'wp-seo-next' );
                        setLocError( msg );
                        setLocLoading( false );
                    } );
            };

            useEffect( function () {
                loadLocations();
            }, [] );

            const locationOptions = buildLocationOptions( locItems, loc );

            const inspector = InspectorControls
                ? el(
                      InspectorControls,
                      {},
                      el(
                          PanelBody,
                          { title: __( 'NAP Settings', 'wp-seo-next' ), initialOpen: true },
                          el( SelectControl, {
                              label: __( 'Template', 'wp-seo-next' ),
                              value: tpl,
                              options: [
                                  { label: __( 'Plain (one-line address)', 'wp-seo-next' ), value: 'plain' },
                                  { label: __( 'Multiline address', 'wp-seo-next' ), value: 'multiline' },
                                  { label: __( 'Icons', 'wp-seo-next' ), value: 'icons' },
                                  { label: __( 'Icons + multiline address', 'wp-seo-next' ), value: 'icons_multiline' },
                              ],
                              onChange: function ( v ) {
                                  setAttributes( { template: v } );
                              },
                          } ),
                          el( ToggleControl, {
                              label: __( 'Enable microdata (HTML itemscope/itemprop)', 'wp-seo-next' ),
                              checked: !! attrs.microdata,
                              onChange: function ( v ) {
                                  setAttributes( { microdata: !! v } );
                              },
                          } ),
                          el( SelectControl, {
                              label: __( 'Layout', 'wp-seo-next' ),
                              value: layout,
                              options: [
                                  { label: __( 'Stack', 'wp-seo-next' ), value: 'stack' },
                                  { label: __( 'Inline', 'wp-seo-next' ), value: 'inline' },
                              ],
                              onChange: function ( v ) {
                                  setAttributes( { layout: v } );
                              },
                          } ),
                          el( SelectControl, {
                              label: __( 'Location', 'wp-seo-next' ),
                              value: loc,
                              options: locationOptions,
                              onChange: function ( v ) {
                                  setAttributes( { location: v } );
                              },
                          } ),
                          locLoading ? el( Spinner, {} ) : null,
                          ! locLoading
                              ? el(
                                    Button,
                                    { isSecondary: true, onClick: loadLocations, style: { marginTop: '8px' } },
                                    __( 'Reload locations', 'wp-seo-next' )
                                )
                              : null,
                          locError ? el( 'p', { style: { color: '#b32d2e', marginTop: '8px' } }, locError ) : null,
                          el( ToggleControl, {
                              label: __( 'Show name', 'wp-seo-next' ),
                              checked: !! attrs.showName,
                              onChange: function ( v ) {
                                  setAttributes( { showName: !! v } );
                              },
                          } ),
                          el( ToggleControl, {
                              label: __( 'Show address', 'wp-seo-next' ),
                              checked: !! attrs.showAddress,
                              onChange: function ( v ) {
                                  setAttributes( { showAddress: !! v } );
                              },
                          } ),
                          el( ToggleControl, {
                              label: __( 'Show phone', 'wp-seo-next' ),
                              checked: !! attrs.showPhone,
                              onChange: function ( v ) {
                                  setAttributes( { showPhone: !! v } );
                              },
                          } ),
                          el( ToggleControl, {
                              label: __( 'Show email', 'wp-seo-next' ),
                              checked: !! attrs.showEmail,
                              onChange: function ( v ) {
                                  setAttributes( { showEmail: !! v } );
                              },
                          } ),
                          el( ToggleControl, {
                              label: __( 'Show opening hours', 'wp-seo-next' ),
                              checked: !! attrs.showHours,
                              onChange: function ( v ) {
                                  setAttributes( { showHours: !! v } );
                              },
                          } ),
                          el( ToggleControl, {
                              label: __( 'Show map link', 'wp-seo-next' ),
                              checked: !! attrs.showMapLink,
                              onChange: function ( v ) {
                                  setAttributes( { showMapLink: !! v } );
                              },
                          } )
                      ),
                      el(
                          PanelBody,
                          { title: __( 'Advanced', 'wp-seo-next' ), initialOpen: false },
                          el( TextControl, {
                              label: __( 'Custom location override', 'wp-seo-next' ),
                              help: __( 'Optional. Use "primary", "settings", a Location post ID, or a Location slug.', 'wp-seo-next' ),
                              value: loc,
                              onChange: function ( v ) {
                                  setAttributes( { location: v } );
                              },
                          } )
                      )
                  )
                : null;

            return el(
                'div',
                { className: props.className },
                inspector,
                el( ServerSideRender, {
                    block: 'wpsn/nap',
                    attributes: attrs,
                } )
            );
        },
        save: function () {
            // Dynamic block.
            return null;
        },
    } );
} )( window.wp );
