(function( $ ){

    const { restUrl, _wpnonce } = BlogBeeWidgetConfig

    /**
     * MARK: Select2
     * 
     * @since 1.0.0
     */
    const BbeSelect2 = {
        /**
         * Initialization
         */
        init() {
            let containers = $( '.field.multiselect .widefat' )
            let self = this
            containers.each(function(){

                let _this = $( this )

                let fetch = _this.data( 'fetch' )

                let endpoint

                if( fetch === 'post' ) {
                    endpoint = 'get_posts'
                } else if( fetch === 'category' ) {
                    endpoint = 'get_taxonomy'
                } else {
                    endpoint = 'get_taxonomy'
                }

                _this.select2({
                    containerCssClass: 'bbe-select-two-dropdown',
                    multiple: true,
                    ajax: {
                        url: `${ restUrl }${ endpoint }`,
                        type: 'POST',
                        headers: {
                            'X-WP-Nonce': _wpnonce
                        },
                        contentType: 'application/json',
                        data: function( params ) {
                            return JSON.stringify({
                                s: params.term,
                                query_slug: fetch,
                                widget: true
                            })
                        },
                        processResults: function( results ) {
                            return {
                                results: results
                            }
                        }
                    },
                    cache: true
                })
            })
        }
    }

    /**
     * MARK: Checkbox
     * 
     * @since 1.0.0
     */
    const BbeCheckbox = {
        /**
         * Initialization
         */
        init() {
            let container = $( '.field.checkbox .widefat' )
            
            container.each(function(){
                let _container = $( this )
                _container.on( 'change', function(){
                    let _this = $( this ),
                        value = _this.val()
                    if( value === '1' ) {
                        _this.val( '0' )
                    } else {
                        _this.val( '1' )
                    }
                } )
            })
        }
    }

    /**
     * MARK: Upload
     * 
     * @since 1.0.0
     */
    const BbeUpload = {
        /**
         * Media frame
         * 
         * @since 1.0.0
         */
        mediaFrame: null,
        /**
         * Input field
         * 
         * @since 1.0.0
         */
        input: null,
        /**
         * Image tag
         * 
         * @since 1.0.0
         */
        imgTag: null,
        /**
         * Container
         * 
         * @since 1.0.0
         */
        container: null,
        /**
         * Initialization
         * 
         * @since 1.0.0
         */
        init() {
            this.bindClick()
        },
        /**
         * Bind click event
         * 
         * @since 1.0.0
         */
        bindClick() {
            let self = this

            let container = $( '.field.upload' )

            container.each(function() {
                let _container = $( this )
                _container.on( 'click', '.upload-button', function(){
                    let _this = $( this )
    
                    self.container = _this.parents( '.field.upload' )

                    if( self.container.hasClass( 'open' ) ) return;
    
                    self.input = self.container.find( '.widefat' )
    
                    self.imgTag = _this.siblings( '.upload-image' )
    
                    self.container.addClass( 'open' )

                    self.bindUpload()
                } )
            })
        },
        /**
         * Bind upload
         * 
         * @since 1.0.0
         */
        bindUpload() {
            if ( this.mediaFrame ) {
                this.mediaFrame.open()
                return;
            }

            this.mediaFrame = wp.media( {
                title: 'Select or Upload Image',
                button: { text: 'Use this image' },
                library: { type: 'image' },
                multiple: false
            } )

            this.mediaFrame.on( 'select', () => {
                const attachment = this.mediaFrame
                    .state()
                    .get( 'selection' )
                    .first()
                    .toJSON();

                this.imgTag.attr( 'src', attachment.url )
                /**
                 * Triggering both change and input event for compatibility with wp environment
                 * If trigger() is not used the update or save button will not trigger
                 * because wp uses input or change events in form fields to mark the widget as 'dirty'.
                 */
                this.input.val( attachment.id ).trigger( 'change' ).trigger( 'input' )
                this.container.removeClass( 'open' )
            } )

            this.mediaFrame.open()
        }
    }

    /**
     * MARK: Post list & grid widget
     * 
     * @since 1.0.0
     */
    const ListGridWidget = {
        /**
         * Container
         * 
         * @since 1.0.0
         */
        get container() {
            return $( '.bbe-widget-fields.blog_bee_post_list_widget' )
        },
        /**
         * Initialization
         * 
         * @since 1.0.0
         */
        init() {
            if( this.container.length ) {
                let self = this
                this.container.each(function() {
                    self.bindMultiselectContext( $( this ) )
                    self.bindSourceChange( $( this ) )
                })
            }
        },
        /**
         * Multiselect show hide
         * 
         * @param { Object } instance The widget container element
         * @since 1.0.0
         */
        bindMultiselectContext( instance ) {
            let postSource = instance.find( '.post_source' )

            let postSourceValue = postSource.find( '.widefat:checked' ).val()

            let unchecked = postSource.find( '.widefat:not(:checked)' )

            unchecked.each(function() {
                let id = $( this ).val()
                instance.find( `.${ id }` ).addClass( 'hide' )
            })
            
        },
        /**
         * Bind post source change
         * 
         * @param { Object } instance The widget container element
         * @since 1.0.0
         */
        bindSourceChange( instance ) {
            let postSource = instance.find( '.post_source .widefat' )

            postSource.on( 'change', function() {
                let _this = $( this )

                let value = _this.val()

                let unchecked = postSource.not( this )

                instance.find( `.${ value }` ).removeClass( 'hide' )
                
                unchecked.each(function() {
                    let id = $( this ).val()
                    instance.find( `.${ id }` ).addClass( 'hide' )
                })
            } )
        },
    }

    /**
     * MARK: Author widget
     * 
     * @since 1.0.0
     */
    const AuthorWidget = {
        /**
         * Container
         * 
         * @since 1.0.0
         */
        get container() {
            return $( '.bbe-widget-fields.blog_bee_author_info_widget' )
        },
        /**
         * Initialization
         * 
         * @since 1.0.0
         */
        init() {
            if( this.container.length ) {
                let self = this
                this.container.each(function() {
                    self.bindAuthorContext( $( this ) )
                    self.bindAuthorChange( $( this ) )
                })
            }
        },
        /**
         * Bind two column context
         * 
         * @param { Object } instance The widget container element
         * @since 1.0.0
         */
        bindAuthorContext( instance ) {
            let author = instance.find( '.author' )
            
            let currentAuthor = author.find( '.widefat' ).val()

            if( currentAuthor === 'custom' ) {
                author.nextAll().removeClass( 'hide' )
            } else {
                author.nextAll().addClass( 'hide' )
            }
        },
        /**
         * Bind post source change
         * 
         * @param { Object } instance The widget container element
         * @since 1.0.0
         */
        bindAuthorChange( instance ) {
            let author = instance.find( '.author' )

            author.find( '.widefat' ).on( 'change', function() {
                let currentAuthor = $( this ).val()

                if( currentAuthor === 'custom' ) {
                    author.nextAll( ':not(.author_radius)' ).removeClass( 'hide' )
                } else {
                    author.nextAll( ':not(.author_radius)' ).addClass( 'hide' )
                }
            } )
        },
    }

    /**
     * MARK: Load
     * 
     * @since 1.0.0
     */
    $( document ).on( 'load widget-added widget-updated', function(){

        BbeSelect2.init()

        BbeCheckbox.init()

        BbeUpload.init()

        ListGridWidget.init()

        AuthorWidget.init()
        
    } )
})( jQuery )