<?php
namespace Avirtum\GutenDraw\System;

defined( 'ABSPATH' ) || exit;

use Avirtum\GutenDraw\Models\AccessModel;
use Avirtum\GutenDraw\Models\DataModel;

class ListTable extends \WP_List_Table {
    public const ICON_COPY = '<svg class="gutendraw-icon gutendraw-copy" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
            <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
            </svg>';
    public const ICON_CHECK = '<svg class="gutendraw-icon gutendraw-check" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <polyline points="20 6 9 17 4 12"></polyline>
            </svg>';

    public function __construct() {
        parent::__construct([
            'singular' => 'gutendraw_item',
            'plural' => 'gutendraw_items',
            'ajax' => false
        ]);
    }

    public function column_cb( $item ) {
        return sprintf(
            '<input type="checkbox" name="%s[]" value="%s">',
            esc_attr( $this->_args['singular'] ), // let's simply repurpose the table's singular label
            esc_attr( $item['id'] ) // the value of the checkbox should be the record's ID
        );
    }

    public function column_title( $item ) {
        $page = sanitize_key( filter_input( INPUT_GET, 'page', FILTER_DEFAULT ) );
        $filter = sanitize_key( filter_input( INPUT_GET, 'filter', FILTER_DEFAULT ) );
        $draft = $item['status'] === DataModel::POST_STATUS_DRAFT ? ' — ' . '<span class="post-state">' . esc_html__('Draft', 'gutendraw') . '</span>' : '';

        $actions = [];
        if ( $filter == 'trash' ) {
            if ( AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_DELETE) ) {
                $args = [
                    'page' => $page,
                    'filter' => $filter,
                    'action' => 'restore',
                    'id' => $item['id']
                ];
                $url = add_query_arg($args, 'admin.php');
                $actions['restore'] = sprintf(
                    '<a href="%s">%s</a>',
                    esc_url(wp_nonce_url($url, 'restore-' . $item['id'])),
                    esc_html__('Restore', 'gutendraw')
                );

                $args = [
                    'page' => $page,
                    'filter' => $filter,
                    'action' => 'delete',
                    'id' => $item['id']
                ];
                $url = add_query_arg($args, 'admin.php');
                $actions['delete'] = sprintf(
                    '<a href="%s">%s</a>',
                    esc_url(wp_nonce_url($url, 'delete-' . $item['id'])),
                    esc_html__('Delete Permanently', 'gutendraw')
                );
            }

            return sprintf('<strong><span class="row-title">%s</span></strong>%s',
                $item['title'],
                $this->row_actions($actions)
            );
        }

        if ( AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_EDIT) ) {
            $args = [
                'page' => 'gutendraw',
                'action' => 'edit',
                'id' => $item['id']
            ];
            $url = add_query_arg($args, 'admin.php');
            $actions['edit'] = sprintf(
                '<a href="%s">%s</a>',
                esc_url($url),
                esc_html__('Edit', 'gutendraw')
            );
        }

        if ( AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_EDIT) && AccessModel::getTicket() ) {
            $args = [
                'page' => $page,
                'action' => 'copy',
                'id' => $item['id']
            ];
            $url = add_query_arg($args, 'admin.php');
            $actions['copy'] = sprintf(
                '<a href="%s">%s</a>',
                esc_url(wp_nonce_url($url, 'copy-' . $item['id'])),
                esc_html__('Duplicate', 'gutendraw')
            );
        }

        if ( AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_DELETE) ) {
            $args = [
                'page' => $page,
                'action' => 'trash',
                'id' => $item['id']
            ];
            $url = add_query_arg($args, 'admin.php');
            $actions['trash'] = sprintf(
                '<a href="%s">%s</a>',
                esc_url(wp_nonce_url($url, 'trash-' . $item['id'])),
                esc_html__('Move to Trash', 'gutendraw')
            );
        }

        if ( AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_EDIT) ) {
            return sprintf('<strong><a href="?page=gutendraw&action=edit&id=%s" class="row-title">%s</a>%s</strong>%s',
                $item['id'],
                $item['title'],
                $draft,
                $this->row_actions($actions)
            );
        }

        return sprintf('<strong><span class="row-title">%s</span>%s</strong>%s',
            $item['title'],
            $draft,
            $this->row_actions($actions)
        );
    }

    public function column_shortcode( $item ) {
        return sprintf(
            '<div class="gutendraw-shortcode"><span class="gutendraw-val">[gutendraw id="%s"]</span><div class="gutendraw-btn" title="%s" style="display:none;">%s%s</div></div>',
            $item['id'],
            esc_html__( 'Copy to clipboard', 'gutendraw' ),
            self::ICON_COPY,
            self::ICON_CHECK
        );
    }

    public function column_author( $item ) {
        return sprintf(
            '<a href="#">%s</a>',
            get_the_author_meta( 'display_name', $item['author'] )
        );
    }

    public function column_edited_by( $item ) {
        return sprintf(
            '<a href="#">%s</a>',
            get_the_author_meta( 'display_name', $item['edited_by'] )
        );
    }

    public function column_role( $item ) {
        if ( array_key_exists( 'role', $item ) && $item['role'] ) {
            global $wp_roles;
            $role = $wp_roles->roles[ $item['role'] ];

            if ( $role ) {
                return sprintf(
                    '%s',
                    translate_user_role( $role['name'] )
                );
            }
        }
    }

    public function column_created( $item ) {
        $t_time    = get_the_time( 'Y/m/d g:i:s a', $item['id'] );
        $time      = get_post_timestamp( $item['id'] );
        $time_diff = time() - $time;

        if ( $time && $time_diff > 0 && $time_diff < DAY_IN_SECONDS ) {
            // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
            $h_time = sprintf( '%s ago', human_time_diff( $time ) );
        } else {
            $h_time = get_the_time( 'Y/m/d', $item['id'] );
        }

        return sprintf('<span title="%s">%s</span>', esc_attr( $t_time ), esc_html( $h_time ) );
    }

    public function column_edited( $item ) {
        $t_time = get_the_modified_time( 'Y/m/d g:i:s a', $item['id'] );
        $time = get_post_timestamp( $item['id'], 'modified' );
        $time_diff = time() - $time;

        if ( $time && $time_diff > 0 && $time_diff < DAY_IN_SECONDS ) {
            // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
            $h_time = sprintf( '%s ago', human_time_diff( $time ) );
        } else {
            $h_time = get_the_modified_time( 'Y/m/d', $item['id'] );
        }

        return sprintf('<span title="%s">%s</span>', esc_attr( $t_time ), esc_html( $h_time ) );
    }

    public function get_columns() {
        $columns = [
            'cb' => '<input type="checkbox" />',
            'title' => esc_html__( 'Title', 'gutendraw' ),
            'shortcode' => esc_html__( 'Shortcode', 'gutendraw' ),
            'author' => esc_html__( 'Author', 'gutendraw' ),
            'edited_by' => esc_html__( 'Edited by', 'gutendraw' ),
            'role' => esc_html__( 'Role', 'gutendraw' ),
            'created' => esc_html__( 'Created', 'gutendraw' ),
            'edited' => esc_html__( 'Edited', 'gutendraw' )
        ];
        return $columns;
    }

    public function get_sortable_columns() {
        $sortable_columns = [
            'title' => [ 'title', false ],
            'created' => [ 'created', false ],
            'edited' => [ 'edited', false ]
        ];
        return $sortable_columns;
    }

    function get_views() {
        $page = sanitize_key( filter_input(INPUT_GET, 'page', FILTER_DEFAULT ) );
        $filter = sanitize_key( filter_input(INPUT_GET, 'filter', FILTER_DEFAULT ) );

        $url_all = add_query_arg( [ 'page' => $page ], 'admin.php' );
        $url_mine = add_query_arg( [ 'page' => $page, 'filter' => 'mine' ], 'admin.php' );
        $url_published = add_query_arg( [ 'page' => $page, 'filter' => 'published' ], 'admin.php' );
        $url_draft = add_query_arg( [ 'page' => $page, 'filter' => 'draft' ], 'admin.php' );
        $url_trash = add_query_arg( [ 'page' => $page, 'filter' => 'trash' ], 'admin.php' );

        $data = DataModel::getFilterCounts();
        $filter_links = [];

        if ( $data['all'] ) $filter_links['all'] = sprintf('<a href="%s" %s>%s <span class="count">(%d)</span></a>', esc_url( $url_all ), ( $filter ? '' : 'class="current"' ), esc_html__( 'All', 'gutendraw' ), $data['all'] );
        if ( $data['mine'] ) $filter_links['mine'] = sprintf('<a href="%s" %s>%s <span class="count">(%d)</span></a>', esc_url( $url_mine ),  ( $filter == 'mine'  ? 'class="current"' : '' ), esc_html__( 'Mine', 'gutendraw' ), $data['mine'] );
        if ( $data['published'] ) $filter_links['published'] = sprintf('<a href="%s" %s>%s <span class="count">(%d)</span></a>', esc_url( $url_published ),  ( $filter == 'published'  ? 'class="current"' : '' ), esc_html__( 'Published', 'gutendraw' ), $data['published'] );
        if ( $data['draft'] ) $filter_links['draft'] = sprintf('<a href="%s" %s>%s <span class="count">(%d)</span></a>', esc_url( $url_draft ),  ( $filter == 'draft'  ? 'class="current"' : '' ), esc_html__( 'Draft', 'gutendraw' ), $data['draft'] );
        if ( $data['trash'] ) $filter_links['trash'] = sprintf('<a href="%s" %s>%s <span class="count">(%d)</span></a>', esc_url( $url_trash ), ( $filter == 'trash' ? 'class="current"' : '' ), esc_html__( 'Trash', 'gutendraw' ), $data['trash'] );

        return $filter_links;
    }

    function get_bulk_actions() {
        $type = sanitize_key( filter_input(INPUT_GET, 'filter', FILTER_DEFAULT ) );

        $actions = [];
        if ( $type == 'trash' ) {
            if ( AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_DELETE) ) {
                $actions = [
                    'restore' => esc_html__('Restore', 'gutendraw'),
                    'delete' => esc_html__('Delete Permanently', 'gutendraw')
                ];
            }
        } else {
            if ( AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_EDIT) ) {
                $actions['copy'] = esc_html__( 'Duplicate', 'gutendraw' );
            }
            if ( AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_DELETE) ) {
                $actions['trash'] = esc_html__( 'Move to Trash', 'gutendraw' );
            }
        }
        return $actions;
    }

    public function process_actions() {
        // bulk action
        $nonce = sanitize_key( filter_input(INPUT_POST, '_wpnonce', FILTER_DEFAULT ) );
        $nonce_key = 'bulk-' . $this->_args['plural'];
        if ( wp_verify_nonce( $nonce, $nonce_key ) ) {
            $ids = filter_input(INPUT_POST, $this->_args['singular'], FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );

            if ( $ids ) {
                foreach ($ids as $id) {
                    $id = sanitize_key( $id );
                    switch ( $this->current_action() ) {
                        case 'copy': DataModel::copyItem( $id ); break;
                        case 'trash': DataModel::trashItem( $id ); break;
                        case 'restore': DataModel::restoreItem( $id ); break;
                        case 'delete': DataModel::deleteItem( $id ); break;
                    }
                }
            }

            return;
        }

        // one item action
        $id = sanitize_key( filter_input( INPUT_GET, 'id', FILTER_DEFAULT ) );
        $nonce = sanitize_key( filter_input(INPUT_GET, '_wpnonce', FILTER_DEFAULT ) );
        $nonce_key = $this->current_action() . '-' . $id;
        if ( wp_verify_nonce( $nonce, $nonce_key ) ) {
            switch ( $this->current_action() ) {
                case 'copy': DataModel::copyItem( $id ); break;
                case 'trash': DataModel::trashItem( $id ); break;
                case 'restore': DataModel::restoreItem( $id ); break;
                case 'delete': DataModel::deleteItem( $id ); break;
            }
        }
    }

    public function prepare_items() {
        $this->process_actions();

        $columns = $this->get_columns();
        $sortable = $this->get_sortable_columns();
        $hidden = [];

        $this->_column_headers = [ $columns, $hidden, $sortable ];

        $filter = sanitize_key( filter_input( INPUT_GET, 'filter', FILTER_DEFAULT, [ 'options' => [ 'default' => 'all' ] ] ) );
        $orderby = sanitize_key( filter_input( INPUT_GET, 'orderby', FILTER_DEFAULT, [ 'options' => [ 'default' => 'created' ] ] ) );
        $order = sanitize_key( filter_input( INPUT_GET, 'order', FILTER_DEFAULT, [ 'options' => [ 'default' => 'desc' ] ] ) );
        $search  = sanitize_text_field( filter_input(INPUT_POST, 's', FILTER_DEFAULT, [ 'options' => [ 'default' => null ] ] ) );

        $perpage = get_option( 'posts_per_page' );
        $page = $this->get_pagenum();
        $data = DataModel::getItems( $page, $perpage, $filter, $orderby, $order, $search );

        $this->items = $data['items'];

        $this->set_pagination_args([
            'total_items' => $data['total'],
            'total_pages' => $data['pages'],
            'per_page' => $perpage
        ]);
    }
}