<?php

class Wpadverts_CF_Taxonomies_Integration {
    
    protected $_post_types = null;

    protected $_form = array( "publish" => array( "null" ), "search" => array( "null" ) );

    public function __construct() {
        
        $this->_post_types = wpadverts_get_post_types();
        $this->_form = array( "publish" => array( 'wpad-form-add' ), "search" => array( 'wpad-form-search' ) );
        
        if(is_admin()) {
            add_action( "init", array( $this, "init_admin" ), 15 );
        } else {
            add_action( "init", array( $this, "init" ), 17 );
        }
    }
    
    public function init() {
        
        remove_shortcode( "adverts_add" );
        add_shortcode( "adverts_add", array( $this, "adverts_add") );
        
        add_filter( "shortcode_atts_adverts_list", array( $this, "atts_adverts_list" ), 9000 );

        if( defined( "PRESELECT_AD_CATEGORY_USE_DTD" ) && PRESELECT_AD_CATEGORY_USE_DTD ) {
            add_filter( "template_redirect", array( $this, "dtd_redirect" ) );
        }
    }
    
    /**
     * Admin Init
     * 
     * Registers edit and save actions in the Advert Category edition.
     * 
     * @since 1.0
     * @return void
     */
    public function init_admin() {
        foreach( $this->get_taxonomies() as $taxonomy ) {
            add_action( sprintf( '%s_edit_form_fields', $taxonomy ), array( $this, 'edit_meta_fields' ), 10, 2 );
            add_action( sprintf( 'edited_%s', $taxonomy ), array( $this, 'category_save' ), 10, 2 );  
        }
    }
    
    /**
     * Returns taxonomy names
     * 
     * Returns list of taxonomies assigned to the self::$_post_types
     * 
     * @since 1.3.1
     * @return array
     */
    public function get_taxonomies() {
        $list = get_object_taxonomies( $this->_post_types, 'objects' );
        
        if( is_array( $list ) ) {
            return array_keys( $list );
        } else {
            return array();
        }
    }
    
    
    /**
     * Displays form scheme field in advert category edition.
     * 
     * This function displays form scheme selection dropdown in the term edition
     * panel (wp-admin / Classifieds / Categories).
     * 
     * IMPORTANT: To have some form schemes listed you need to have the Custom Fields
     * add-on activated and some [adverts_add] form schemes created.
     * 
     * @param WP_Term $term     Term being edited
     */
    public function edit_meta_fields( $term ) {

        $loop = new WP_Query(array(
            'post_type' => 'wpadverts-form',
            'post_status' => $this->_form["publish"],
            'posts_per_page' => -1
        ));

        $term_id = get_term_meta( $term->term_id, "category_form_scheme", true );

        ?>
        <tr class="form-field">
            <th scope="row" valign="top">
                <label for="category_form_scheme">
                    <?php _e( 'Form Scheme', 'wpadverts-custom-fields' ); ?>
                </label>
            </th>
            <td>
                <select name="category_form_scheme">
                    <option value=""></option>
                    <?php foreach( $loop->posts as $scheme ): ?>
                    <option value="<?php echo esc_attr($scheme->ID) ?>" <?php selected($scheme->ID, $term_id) ?>><?php echo esc_html($scheme->post_title) ?></option>
                    <?php endforeach; ?>
                </select>
            </td>
        </tr>
        <?php

        $loop = new WP_Query(array(
            'post_type' => 'wpadverts-form',
            'post_status' => $this->_form["search"],
            'posts_per_page' => -1
        ));

        $term_id = get_term_meta( $term->term_id, "category_form_scheme_search", true );
        ?>
        <tr class="form-field">
            <th scope="row" valign="top">
                <label for="category_form_scheme_search">
                    <?php _e( 'Form Scheme Search', 'wpadverts-custom-fields' ); ?>
                </label>
            </th>
            <td>
                <select name="category_form_scheme_search">
                    <option value=""></option>
                    <?php foreach( $loop->posts as $scheme ): ?>
                    <option value="<?php echo esc_attr($scheme->ID) ?>" <?php selected($scheme->ID, $term_id) ?>><?php echo esc_html($scheme->post_title) ?></option>
                    <?php endforeach; ?>
                </select>
            </td>
        </tr>
        <?php
    }

    /**
     * Saves the category_form_scheme in meta table.
     * 
     * This function is executed when edition form in wp-admin / Classifieds / Categories
     * panel is submitted.
     * 
     * @param int $term_id      Edited Term ID
     * @return void
     */
    public function category_save( $term_id ) {

        $cfs = intval( adverts_request( "category_form_scheme" ) );

        if ( $cfs > 0 ) {
            update_term_meta( $term_id, "category_form_scheme", $cfs );
        } else {
            delete_term_meta( $term_id, "category_form_scheme" ); 
        }

        $cfss = intval( adverts_request( "category_form_scheme_search" ) );

        if ( $cfss > 0 ) {
            update_term_meta( $term_id, "category_form_scheme_search", $cfss );
        } else {
            delete_term_meta( $term_id, "category_form_scheme_search" ); 
        }
    }
    
    /**
     * New [adverts_add] shortcode
     * 
     * Shows the preselection interface or runs shortcode_adverts_add() if the
     * category is already preselected
     * 
     * @see shortcode_adverts_add()
     * 
     * @param array $atts   Shortcode attributes
     * @return string       HTML for the shortcode
     */
    public function adverts_add( $atts ) {
        
        if( ! is_array( $atts ) ) {
            $atts = array();
        }
        
        if( ! isset( $atts["preselect_category"] ) || $atts["preselect_category"] != "1" ) {
            return shortcode_adverts_add( $atts );
        }

        $term_slug =  trim( adverts_request( "preselected_category" ) );
        $is_preselected = false;
        $flash = array(
            "error" => array( ),
            "info" => array( )
        );

        if( ! empty( $term_slug ) ) {
            $term = get_term_by( "slug", adverts_request( "preselected_category" ), "advert_category" );

            if( ! is_wp_error( $term ) && is_object( $term ) ) {
                $is_preselected = true;
            } 
        }

        if( ! $is_preselected ) {
            return $this->display( $atts );
        }

        if( get_term_meta( $term->term_id, "wpadvert_is_restricted", true ) ) {
            $message = __( 'This category is disabled. <a href="%s">Go Back</a>.', "wpadverts-custom-fields" );

            $flash["error"][] = array(
                "message" => sprintf( $message, remove_query_arg( "preselected_category" ) ),
                "icon" => "adverts-icon-no"
            );

            ob_start();
            adverts_flash( $flash );
            return ob_get_clean();
        }

        add_filter( "adverts_form_load", array( $this, "form_load" ) );
        add_filter( "adverts_form_bind", array( $this, "form_bind" ), 10, 2 );

        $term_id = $term->term_id;
            
        do {
            $scheme_id = intval( get_term_meta( $term_id, "category_form_scheme", true ) );
            $term_id = get_term( $term_id )->parent;
        } while( $scheme_id === 0 && $term_id > 0);
            
        if( $scheme_id ) {
            $form_scheme = get_post( $scheme_id );

            
            if( $form_scheme ) {
                $atts["form_scheme"] = $form_scheme->post_name;
                $atts["form_scheme_id"] = $form_scheme->ID;
            }
        }

        return shortcode_adverts_add( $atts );
    }
    
    /**
     * Renders the category selection interface
     * 
     * This function is based on Adverts_Widget_Categories
     * 
     * @see Adverts_Widget_Categories::widget_multi_level()
     * 
     * @param array $atts   Shortcode attributes
     * @return string       HTML for the shortcode
     */
    public function display( $atts ) {

        $terms = get_terms( 'advert_category', array( 
            'hide_empty' => 0,
            'parent' => 0,
        ) );

        ob_start();

        include_once ADVERTS_PATH . 'includes/shortcodes.php';

        wp_enqueue_style( "adverts-frontend" );
        wp_enqueue_style( "adverts-icons" );

        $adverts_flash = array(
            "error" => array( ),
            "info" => array(            
                array( 
                    "message" => __( "Select category before creating an Advert", "wpadverts-custom-fields" ),
                    "icon" => "adverts-icon-tag"
                )
            )
        );
        adverts_flash($adverts_flash);

        ?>

        <div class="wpjb adverts-widget adverts-widget-categories adverts-widget-multi-level-categories">
            <div class="adverts-grid adverts-grid-compact">

                <?php
                    if ( ! empty( $terms ) && ! is_wp_error( $terms ) ):
                        if( defined( "PRESELECT_AD_CATEGORY_USE_DTD" ) && PRESELECT_AD_CATEGORY_USE_DTD ) {
                            $this->dtd();
                        } else {
                            $this->display_inner( $terms, 0 );
                        }
                    else:
                ?>
                <div class="adverts-grid-row">
                    <div class="adverts-col-100">
                        <span><?php _e("No categories found.", "adverts") ?></span>
                    </div>
                </div>
                <?php endif; ?> 
            </div>
        </div>


        <?php

        return ob_get_clean();
    }

    public function dtd() {
        $field = array(
            "name" => "preselected_dtd_category",
            "value" => "",
            "dtd_use_taxonomy" => "advert_category"
        );

        wp_enqueue_script( "adverts-frontend" );
        wp_enqueue_style( "adverts-frontend" );
        wp_enqueue_style( "adverts-icons" );

        ?>
        <form action="" method="post">
            <?php wp_nonce_field( "preselected-dtd-category" ) ?>
            <?php dependant_taxonomy_dropdown( $field ) ?>
            <input type="submit" value="Select" class="button preselect-ad-category-dtd-submit" />
        </form>

        <?php
    }

    /**
     * Prints category interface items
     * 
     * This function renders one category level and calls itself recursively
     * to render inner levels.
     * 
     * @see Adverts_Widget_Categories::print_terms_multi_level()
     * 
     * @param array $terms      
     * @param int $level
     */
    function display_inner( $terms, $level = 0 ) {

        foreach ( $terms as $term_item ):
            $default_icon = "folder";
            $icon = adverts_taxonomy_get( "advert_category", $term_item->term_id, "advert_category_icon", $default_icon );

            if ( $icon == "" ) {
                $icon = $default_icon;
            }

            ?>
            <div class="adverts-grid-row">
                <div class="adverts-col-100">
                    <span class="adverts-widget-grid-link <?php echo apply_filters("adverts_category_font_icon", "adverts-icon-".$icon, $term_item, "small") ?>">
                        <?php do_action( "adverts_category_pre_title", $term_item, "small") ?>
                        <?php if( get_term_meta( $term_item->term_id, "wpadvert_is_restricted", true ) ): ?>
                        <?php echo esc_html($term_item->name) ?>
                        <?php else: ?>
                        <a href="<?php echo esc_attr(add_query_arg("preselected_category", $term_item->slug)) ?>"><?php echo esc_html($term_item->name) ?></a>
                        <?php endif; ?>
                    </span>
                </div>
            </div>
            <?php

            $child_terms = get_terms( 'advert_category', array(
                'hide_empty' => 0,
                'parent' => (int)$term_item->term_id,
            ) );

            if ( ! empty( $child_terms ) && ! is_wp_error( $child_terms ) ):
                ?>
                <div class="adverts-multi-level <?php echo 'adverts-multi-level-'.$level ?>">
                <?php $this->display_inner( $child_terms, $level+1 ); ?>
                </div>
                <?php
            endif;

        endforeach;
    }
    
    /**
     * Locks the advert_cateogry field
     * 
     * This function makes the category field a single select field, sets value
     * to the preselected category and disables users ability to change the category.
     * 
     * @param array $form   Form scheme
     * @return array        Updated form scheme
     */
    public function form_load( $form ) {
        if( $form['name'] != "advert" ) {
            return $form;
        }

        $term = get_term_by( "slug", adverts_request( "preselected_category" ), "advert_category" );

        if( is_wp_error( $term ) || $term === null ) {
            return $form;
        }

        foreach( $form["field"] as $key => $field ) {
            if( $field["name"] == "advert_category" ) {
                $form["field"][$key]["attr"]["readonly"] = "readonly";
                $form["field"][$key]["value"] = $term->term_id;
                $form["field"][$key]["max_choices"] = 1;
            }
        }
        return $form;
    }

    /**
     * Sets value for the advert_category field
     * 
     * This function makes sure that the preselected category was not changed.
     * 
     * @param Adverts_Form $form    Form Object
     * @return void
     */
    public function form_bind( $form ) {

        $term = get_term_by( "slug", adverts_request( "preselected_category" ), "advert_category" );

        if( is_wp_error( $term ) || $term === null ) {
            return null;
        }

        $form->set_value( "advert_category", $term->term_id );
    }
    
    
    /**
     * Applies form_scheme_id param to [adverts_list] shortcode
     * 
     * This function applies form_scheme_id param to the [adverts_list] shortcode
     * when displaying it on the advert-category pages
     * 
     * @since   1.1.0
     * @param   array   $out    Shortcode atts
     * @return  array
     */
    public function atts_adverts_list( $out ) {
        
        if( is_tax( $this->get_taxonomies() ) ) {
            
            $term_id = get_queried_object_id();
            
            do {
                $form_id = get_term_meta( $term_id, "category_form_scheme_search", true );
                $term_id = get_term( $term_id )->parent;
            } while( $form_id === "" && $term_id > 0);

            if( intval( $form_id ) > 0 ) {

                $form_scheme = get_post( $form_id );

                $out["form_scheme_id"] = $form_id;
                $out["form_scheme"] = $form_scheme->post_name;
            }
        }

        return $out;
    }
    
   public function dtd_redirect( $template ) {

        if( ! wp_verify_nonce( adverts_request( '_wpnonce' ), 'preselected-dtd-category' ) ) {
            return $template;
        }

        $dtd_category = absint( adverts_request( 'preselected_dtd_category' ) );

        if( ! is_numeric( $dtd_category ) ) {
            return $template;
        }

        $term = get_term( $dtd_category );

        if( is_wp_error( $term ) ) {
            wp_die( __( "Incorrect category ID provided", 'wpadverts-custom-fields' ) );
        }

        $redirect_args = array( 
            "preselected_category" => $term->slug,
            "author-panel" => adverts_request( "author-panel" )
        );
        
        wp_redirect( add_query_arg( $redirect_args, get_permalink( get_the_ID() ) ) );
        exit;
    }
}