<?php

namespace WPIS;

class EstatePostType extends EstateProperties {

    static public $postTypeName = 'wpis_estates';
    static public $postTypeMetaPrefix = 'wpis';
    static public $taxonomies;
    static private $db;

    static public function init() {

        $class = new self();

        self::$db = $GLOBALS['wpdb'];

        if( SettingsManager::get('enableImportCustomPostType') ){
            self::$postTypeName = SettingsManager::get('customPostType');
        }
        else {
            add_action( 'init', [$class, 'registerPostType']);
            add_filter( 'add_menu_classes', [$class, 'addMenuPostCount']);
            add_filter( 'manage_' . self::$postTypeName .  '_posts_columns', [$class, 'setCustomColumns'] );
            add_action( 'manage_' . self::$postTypeName .  '_posts_custom_column' , [$class, 'applyCustomColumns'], 10, 2 );
            add_filter( 'post_class', [$class, 'addSoftDeletedRowClass'], 10, 3 );
            add_action( 'add_meta_boxes', [$class, 'createMetabox']);
            add_action( 'save_post', [$class, 'saveMetaboxData'], 10, 2);
        }

        if( SettingsManager::get('enableTaxonomies') ){
            $class->initTaxonomies();
            add_action( 'init' , [$class, 'registerTaxonomies'] );
        }

        add_action( 'init', [$class, 'handleRedirection' ]);
    }

    public function registerPostType(){

        register_post_type(
            self::$postTypeName,
            [
                'labels'      => [
                    'name'          => __('Properties', 'wpis'),
                    'singular_name' => __('Property', 'wpis'),
                ],
                'public'       => true,
                'has_archive'  => true,
                'show_in_rest' => false,
                'rewrite'      => [
                    'slug' => SettingsManager::get('postTypeEstateSlug', self::$postTypeName)
                ],
                'menu_icon' => 'dashicons-admin-home',
                'supports'  => [
                    'title',
                    'editor',
                    'thumbnail'
                ]
            ]
        );
    }

    public function addMenuPostCount( $menu ) {
        $count = wp_count_posts(  self::$postTypeName, 'readable' );
        $count = $count->publish;
        $softDeletedCount = $this->getSoftDeletedPostCount();

        foreach($menu as $index => $item){
            if( $item[2] === 'edit.php?post_type=' . self::$postTypeName){
                $mainCounterClass = 'wpis_adminPostCount';
                if( $softDeletedCount === 0 ){
                    $mainCounterClass .= ' wpis_adminPostCount--solo';
                }

                $item[0] .= '<span class="wpis_adminPostCounts">';
                $item[0] .= '  <span class="' . $mainCounterClass . '">' . $count . '</span>';
                if( $softDeletedCount > 0 ){
                    $item[0] .= '  <span class="wpis_adminPostCount wpis_adminPostCount--danger">' . $softDeletedCount . '</span>';
                }
                $item[0] .= '</span>';
                $menu[$index] = $item;
            }
        }

        return $menu;
    }

    private function getSoftDeletedPostCount() {
        $postsTable = self::$db->posts;
        $postmetaTable = self::$db->postmeta;
        $softDeletedMetaKey = self::$postTypeMetaPrefix . '_soft_deleted';

        $query = self::$db->prepare(
            "
            SELECT COUNT(DISTINCT p.ID)
            FROM {$postsTable} p
            INNER JOIN {$postmetaTable} pm
                ON pm.post_id = p.ID
            WHERE p.post_type = %s
                AND p.post_status = 'publish'
                AND pm.meta_key = %s
                AND pm.meta_value <> ''
                AND pm.meta_value <> '0'
            ",
            self::$postTypeName,
            $softDeletedMetaKey
        );

        return (int) self::$db->get_var($query);
    }

    public function setCustomColumns($columns) {

        $columns['thumbnail'] = __( 'Image', 'wpis' );
        $columns['type-category'] = __( 'Category', 'wpis' );
        $columns['price'] = __( 'Price', 'wpis' );
        $columns['purpose'] = __( 'Purpose', 'wpis' );
        $columns['status'] = __( 'Status', 'wpis' );
        $columns['reference'] = __( 'Reference', 'wpis' );
        $columns['eid'] = __( 'Estate ID', 'wpis' );
        $columns['locked'] = '<i class="fa fa-lock"></i>';
        $columns['undeletable'] = '<i class="fa fa-trash"></i>';

        $columnClone = $columns;

        $order = [
            'cb',
            'thumbnail',
            'title',
            'type-category',
            'price',
            'purpose',
            'status',
            'eid',
            'reference',
            'locked',
            'undeletable',
            'date'
        ];

        usort($columns, function ($a, $b) use ($order) {
            if( isset($columns) ){
                $pos_a = array_search($columns[$a], $order);
                $pos_b = array_search($columns[$b], $order);
                return $pos_a - $pos_b;
            }
        });

        $columnsMapped = [];

        foreach( $order as $i => $value ){
            $columnsMapped[$order[$i]] = $columnClone[$value];
        }

        return $columnsMapped;
    }

    public function applyCustomColumns( $column, $post_id ) {
        switch ( $column ) {

            case 'thumbnail' :
                echo get_the_post_thumbnail( $post_id, [50, 50] );
                break;

            case 'type-category' :
                $type = get_post_meta( $post_id , self::$postTypeMetaPrefix . '_' . 'category_label' , true );
                $category = get_post_meta( $post_id , self::$postTypeMetaPrefix . '_' . 'subcategory_label' , true );
                $typeCategory = Tools::ucfirst($type) . ' / ' . Tools::ucfirst($category);
                echo $typeCategory;
                break;

            case 'price' :
                if( $price = get_post_meta( $post_id , self::$postTypeMetaPrefix . '_' . 'finance_price' , true ) ){
                    $price = round( $price );
                    $price = number_format_i18n($price);
                    $price = str_replace(',', ' ', $price);
                    $currency = get_post_meta( $post_id , self::$postTypeMetaPrefix . '_' . 'finance_currency' , true );
                    echo $price . ' '  . $currency;
                }
                break;

            case 'purpose' :
                $purpose = get_post_meta( $post_id , self::$postTypeMetaPrefix . '_' . 'purpose_label' , true );
                $purpose = Tools::ucfirst($purpose);
                echo $purpose;
                break;

            case 'status' :
                $purpose = get_post_meta( $post_id , self::$postTypeMetaPrefix . '_' . 'status_label' , true );
                $purpose = Tools::ucfirst($purpose);
                $isSoftDeleted = (bool) get_post_meta($post_id, self::$postTypeMetaPrefix . '_' . 'soft_deleted', true);

                echo $purpose;

                if( $isSoftDeleted ){
                    echo '<br><small style="color: #d63638; font-weight: 600;">Soft deleted</small>';
                }
                break;

            case 'eid' :
                $id = get_post_meta( $post_id , self::$postTypeMetaPrefix . '_' . 'id' , true );
                echo '<code style="border-radius: 3px;border: 1px solid grey;">' . $id . '</code>';
                break;

            case 'reference' :
                $reference = get_post_meta( $post_id , self::$postTypeMetaPrefix . '_' . 'reference' , true );
                echo $reference ?: 'N/A';
                break;

            case 'locked' :
                $isLocked = get_post_meta( $post_id , self::$postTypeMetaPrefix . '_' . 'locked' , true );
                echo $isLocked ? '<i class="icon-lock-on fas fa-lock"></i>' : '<i class="icon-lock-off fas fa-lock-open"></i>';
                break;

            case 'undeletable' :
                $isUndeletable = get_post_meta( $post_id , self::$postTypeMetaPrefix . '_' . 'undeletable' , true );
                echo $isUndeletable ? '<i class="icon-undeletable-off fas fa-times-circle"></i>' : '<i class="icon-undeletable-on fas fa-check-circle"></i>';
                break;
        }
    }

    public function addSoftDeletedRowClass( $classes, $class, $post_id ) {
        if ( ! is_admin() ) {
            return $classes;
        }

        if ( get_post_type( $post_id ) !== self::$postTypeName ) {
            return $classes;
        }

        $isSoftDeleted = (bool) get_post_meta($post_id, self::$postTypeMetaPrefix . '_' . 'soft_deleted', true);
        if ( $isSoftDeleted ) {
            $classes[] = 'wpis-soft-deleted-row';
        }

        return $classes;
    }

    private function initTaxonomies() {
        self::$taxonomies = [
            [
                'slug'         => 'estate_cities',
                'single_name'  => 'Ville',
                'plural_name'  => 'Villes',
                'rewrite'      => ['slug' => SettingsManager::get('taxonomyEstateCitySlug', 'city')],
            ],
            [
                'slug'         => 'estate_categories',
                'single_name'  => 'Type de bien',
                'plural_name'  => 'Types de bien',
                'rewrite'      => ['slug' => SettingsManager::get('taxonomyEstateCategorySlug', 'category')],
            ],
            [
                'slug'         => 'estate_purposes',
                'single_name'  => 'Type de transaction',
                'plural_name'  => 'Types de transaction',
                'rewrite'      => ['slug' => SettingsManager::get('taxonomyEstatePurposeSlug', 'type')],
            ],
            [
                'slug'         => 'estate_ammeneties',
                'single_name'  => 'Équipement',
                'plural_name'  => 'Équipements',
                'rewrite'      => ['slug' => SettingsManager::get('taxonomyEstateAmenetySlug', 'amenities')],
            ]
        ];
    }

    public function registerTaxonomies() {
        foreach( self::$taxonomies as $taxonomy ){
            $taxonomy['post_type'] = self::$postTypeName;

            $labels = array(
                'name' => $taxonomy['plural_name'],
                'singular_name' => $taxonomy['single_name'],
                'search_items' =>  'Search ' . $taxonomy['plural_name'],
                'all_items' => 'All ' . $taxonomy['plural_name'],
                'parent_item' => 'Parent ' . $taxonomy['single_name'],
                'parent_item_colon' => 'Parent ' . $taxonomy['single_name'] . ':',
                'edit_item' => 'Edit ' . $taxonomy['single_name'],
                'update_item' => 'Update ' . $taxonomy['single_name'],
                'add_new_item' => 'Add New ' . $taxonomy['single_name'],
                'new_item_name' => 'New ' . $taxonomy['single_name'] . ' Name',
                'menu_name' => $taxonomy['plural_name']
            );

            $rewrite = isset( $taxonomy['rewrite'] ) ? $taxonomy['rewrite'] : array( 'slug' => $taxonomy['slug'] );
            $hierarchical = isset( $taxonomy['hierarchical'] ) ? $taxonomy['hierarchical'] : true;

            register_taxonomy( $taxonomy['slug'], $taxonomy['post_type'], array(
                'hierarchical' => $hierarchical,
                'labels' => $labels,
                'show_ui' => true,
                'query_var' => true,
                'rewrite' => $rewrite,
            ));
        }
    }

    public function handleRedirection() {

        add_action( 'parse_request', function( $wp ){
            if ( preg_match( '#^wpis-estate-id/(.*)#', $wp->request, $matches ) ) {
                $id = $matches[1];

                $result = self::$db->get_row(
                    self::$db->prepare( 'SELECT post_id FROM ' . self::$db->postmeta . ' WHERE meta_key = "wpis_id" AND meta_value = %s',
                    $id
                ));

                if( ! $result ){
                    status_header( '404' );
                    header('Content-Type: text/html', true);
                    locate_template( array ( '404.php', 'index.php' ), TRUE, TRUE );
                    exit;
                }

                $permalink = get_permalink($result->post_id);
                wp_redirect( $permalink, 301 );

                exit;
            }
        } );

    }

    public function createMetabox(){

        // Gallery metabox
        $label = '<span class="estateMetabox__label"><i class="estateMetabox__label_icon fas fa-images"></i>%s</span>';
        add_meta_box(
            self::$postTypeMetaPrefix . '_'  . 'pictures',
            sprintf($label, 'Images du bien'),
            [$this, 'generateMetaboxBodyGallery'],
            [self::$postTypeName, ProjectPostType::$postTypeName],
            'normal',
            'high'
        );

        // Property Metabox
        $label = '<span class="estateMetabox__label"><i class="estateMetabox__label_icon fas fa-home"></i>%s</span>';
        add_meta_box(
            self::$postTypeMetaPrefix . '_'  . 'data',
            sprintf($label, 'ImmoSync: Propriétés du bien'),
            [$this, 'generateMetaboxBodyData'],
            [self::$postTypeName, ProjectPostType::$postTypeName],
            'normal',
            'low'
        );
    }

    private function generateMetaboxBody( $post, $groupId ){
        foreach(self::$postTypeMetas as $group) {
            if( $group['id'] === $groupId ){
                echo '<div class="wpis_options_wrapper">';
                foreach($group['fields'] as $field){
                    $field = str_replace('.', '_', $field);

                    $value = get_post_meta($post->ID, self::$postTypeMetaPrefix . '_' . $field['reference'], true);
                    $labelHtml =
                        '<p class="post-attributes-label-wrapper">' .
                        '   <label class="post-attributes-label" for="parent_id">' . __($field['label'], 'wpis') . '</label>' .
                        '</p>';

                    if( $field['type'] === 'readonly' ) {
                        echo $labelHtml;
                        echo '<input
                            style="width: 100%; border-radius: 3px; border: 1px solid #ddd; padding: 4px 8px; margin-bottom: 6px;"
                            value="' . $value .'"
                            disabled="disabled"
                            type="text"
                            name="' . self::$postTypeMetaPrefix . '_'  . $field['reference'] . '"></input>';
                    }

                    if( $field['type'] === 'text' ) {
                        echo $labelHtml;
                        echo '<input
                            style="width: 100%; border-radius: 3px; border: 1px solid #ddd; padding: 4px 8px; margin-bottom: 6px;"
                            value="' . $value .'"
                            type="text"
                            name="' . self::$postTypeMetaPrefix . '_'  . $field['reference'] . '"></input>';
                    }

                    if( $field['type'] === 'number' ) {
                        echo $labelHtml;
                        echo '<input
                            style="width: 100%; border-radius: 3px; border: 1px solid #ddd; padding: 4px 8px; margin-bottom: 6px;"
                            value="' . round(intval($value)) .'"
                            type="number"
                            name="' . self::$postTypeMetaPrefix . '_'  . $field['reference'] . '"></input>';
                    }

                    if( $field['type'] === 'date' ) {
                        $value = substr($value, 0, 10);
                        echo $labelHtml;
                        echo '<input
                            style="width: 100%; border-radius: 3px; border: 1px solid #ddd; padding: 4px 8px; margin-bottom: 6px;"
                            value="' . $value .'"
                            type="date"
                            name="' . self::$postTypeMetaPrefix . '_'  . $field['reference'] . '"></input>';
                    }

                    if( $field['type'] === 'boolean' ) {
                        echo '<section class="slider-checkbox">';
                        echo '  <input type="checkbox" ' . ($value ? 'checked' : '') . ' id="' . $field['reference'] . '" name="' . self::$postTypeMetaPrefix . '_'  . $field['reference'] . '" />';
                        echo '  <label class="label" for="' . $field['reference'] . '">' . __($field['label'], 'wpis') . '</label>';
                        echo '</section>';
                    }

                    if( $field['type'] === 'file-collection' ) {
                        foreach($value as $file) {
                            echo '<a href="' . $file->url . '" target="_blank">';
                            echo $file->filename . '.' . $file->format;
                            echo '</a>';
                        }
                    }
                }
                echo '</div>';
            }
        }
    }

    public function generateMetaboxBodyGallery( $post ) {
        $medias = get_attached_media('image', $post->ID);

        echo '<ul id="estateMetaboxPictures" class="estateMetabox__pictures">';
        foreach ($medias as $media) {
            echo '<li>';
            echo '  <figure>';
            echo wp_get_attachment_image($media->ID, 'thumbnail', false, ["class" => "selectable-image", "data-attachment_id" => $media->ID]);
            echo '  </figure>';
            echo '</li>';
        }
        echo '</ul>';
        echo "<script>jQuery(document).ready(function($) {
            $('#estateMetaboxPictures').on('click', '.selectable-image', function(e) {
                e.preventDefault();

                var attachment_id = $(this).data('attachment_id');

                // Define the media frame.
                var frame = wp.media({
                    title: 'Edit Media',
                    button: {
                        text: 'Update'
                    },
                    multiple: false,
                    library: { type: 'image' },
                    frame: 'post'
                });

                frame.on('open', function() {
                    var selection = frame.state().get('selection');
                    selection.add(wp.media.attachment(attachment_id));
                });

                frame.open();
            });
        });
        </script>
        ";
    }

    public function generateMetaboxBodyData( $post ){


        ?>
        <div id="estateMetaboxData" class="estateMetabox__data">
            <ul class="tabs">
        <?php
            $i = 1;
            foreach(self::$postTypeMetas as $group) {
                if( $group['id'] === 'hidden' ){
                    continue;
                }
                echo  '<li class="tab-link' . ($i === 1 ? ' current' : '') . '" data-tab="tab-' . $i . '"><span class="estateMetabox__label"><i class="estateMetabox__label_icon fas ' . $group['icon'] . '"></i>' . $group['label'] . '</span></li>';
                $i++;
            }
        ?>
            </ul>
        <?php
            $i = 1;
            foreach(self::$postTypeMetas as $group) {
                if( $group['id'] === 'hidden' ){
                    continue;
                }
                echo '<div id="tab-' . $i . '" class="tab-content' . ($i === 1 ? ' current' : '') . '">';
                if( $group['id'] === 'options' && get_post_meta($post->ID, self::$postTypeMetaPrefix . '_soft_deleted', true) ){
                    echo '<div style="width: 100%; background: #ffe5e5; border-left: 4px solid #e57373; color: #b71c1c; padding: 12px 16px; box-sizing: border-box; font-size: 16px; border-radius: 4px;">';
                    echo '  <span style="font-weight: bold; color: #e57373;"><i class="dashicons dashicons-info"></i> Information :</span> ';
                    echo "  Ce bien a été supprimé depuis le logiciel d'origine. Il est donc hors de la synchronisation. Seule une image a été conservée.";
                    echo '</div>';
                }
                else {
                    echo '<div class="wpis_options_wrapper">';

                    foreach($group['fields'] as $field){
                        $field = str_replace('.', '_', $field);

                        $value = get_post_meta($post->ID, self::$postTypeMetaPrefix . '_' . $field['reference'], true);
                        $labelHtml =
                            '<p class="post-attributes-label-wrapper">' .
                            '   <label class="post-attributes-label" for="parent_id">' . __($field['label'], 'wpis') . '</label>' .
                            '</p>';

                        if( $field['type'] === 'readonly' ) {
                            echo '<div class="option-wrapper">';
                            echo $labelHtml;
                            echo '<input
                                style="width: 100%; border-radius: 3px; border: 1px solid #ddd; padding: 4px 8px; margin-bottom: 6px;"
                                value="' . $value .'"
                                disabled="disabled"
                                type="text"
                                name="' . self::$postTypeMetaPrefix . '_'  . $field['reference'] . '"></input>';
                            echo '</div>';
                        }

                        if( $field['type'] === 'text' ) {
                            echo '<div class="option-wrapper">';
                            echo $labelHtml;
                            echo '<input
                            style="width: 100%; border-radius: 3px; border: 1px solid #ddd; padding: 4px 8px; margin-bottom: 6px;"
                            value="' . $value .'"
                            type="text"
                            name="' . self::$postTypeMetaPrefix . '_'  . $field['reference'] . '"></input>';
                            echo '</div>';
                        }

                        if( $field['type'] === 'number' ) {
                            $value = $value === '' ? '' : round(intval($value));
                            echo '<div class="option-wrapper">';
                            echo $labelHtml;
                            echo '<input
                            style="width: 100%; border-radius: 3px; border: 1px olid #ddd; padding: 4px 8px; margin-bottom: 6px;"
                            value="' . $value .'"
                            type="number"
                            name="' . self::$postTypeMetaPrefix . '_'  . $field['reference'] . '"></input>';
                            echo '</div>';
                        }

                        if( $field['type'] === 'date' ) {
                            $value = substr($value, 0, 10);
                            echo '<div class="option-wrapper">';
                            echo $labelHtml;
                            echo '<input
                            style="width: 100%; border-radius: 3px; border: 1px solid #ddd; padding: 4px 8px; margin-bottom: 6px;"
                            value="' . $value .'"
                            type="date"
                            name="' . self::$postTypeMetaPrefix . '_'  . $field['reference'] . '"></input>';
                            echo '</div>';
                        }

                        if( $field['type'] === 'boolean' ) {
                            echo '<div class="option-wrapper type-slider">';
                            echo '  <section class="slider-checkbox">';
                            echo '    <input type="checkbox" ' . ($value ? 'checked' : '') . ' id="' . $field['reference'] . '" name="' . self::$postTypeMetaPrefix . '_'  . $field['reference'] . '" />';
                            echo '    <label class="label" for="' . $field['reference'] . '">' . __($field['label'], 'wpis') . '</label>';
                            echo '  </section>';
                            echo '</div>';
                        }

                        if( $field['type'] === 'file-collection' ) {
                            echo '<div class="option-wrapper">';
                            foreach($value as $file) {
                                echo '<a href="' . $file->url . '" target="_blank">';
                                echo $file->filename . '.' . $file->format;
                                echo '</a>';
                            }
                            if( empty($value) ){
                                echo 'Il n\'y a aucun fichier disponible pour ce bien';
                            }
                            echo '</div>';
                        }
                    }
                    echo '</div>';
                }
                echo '</div>';
                $i++;
            }
        ?>
        </div>
        <script>
            jQuery(document).ready(function($) {
                $('ul.tabs li').click(function() {
                    var tab_id = $(this).attr('data-tab');

                    $('ul.tabs li').removeClass('current');
                    $('.tab-content').removeClass('current');

                    $(this).addClass('current');
                    $("#" + tab_id).addClass('current');
                });
            });
        </script>
        <?php
    }

    public function saveMetaboxData( $post_id, $post ) {

        $post_type = get_post_type_object( $post->post_type );

        if ( isset($post_type->cap) && !current_user_can( $post_type->cap->edit_post, $post_id ) )
            return $post_id;

        foreach(self::$postTypeMetas as $group) {
            if( $group['id'] !== 'hidden' ){
                foreach($group['fields'] as $field){
                    if( !empty($_POST) ){
                        $meta = self::$postTypeMetaPrefix . '_' . str_replace('.', '_', $field['reference']);
                        if( $field['type'] === 'boolean'){
                            $value = (isset( $_POST[$meta] ) && $_POST[$meta] === 'on') ? 1 : 0;
                            update_post_meta( $post_id, $meta, $value );
                        }
                        elseif( isset( $_POST[$meta] ) ) {
                            update_post_meta( $post_id, $meta, $_POST[$meta] );
                        }
                    }
                }
            }
        }
    }
}