<?php

namespace Yalogica\NinjaDraw\System;

defined('ABSPATH') || exit;

use Freemius;
use Yalogica\NinjaDraw\Models\AccessModel;
use Yalogica\NinjaDraw\Models\DataModel;
use Yalogica\NinjaDraw\Models\FreemiusModel;


class ListTable extends \WP_List_Table
{
  public const ICON_COPY = '<svg class="ninjadraw-icon ninjadraw-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="ninjadraw-icon ninjadraw-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' => 'ninjadraw_item',
      'plural' => 'ninjadraw_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', 'ninjadraw') . '</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', 'ninjadraw')
        );

        $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', 'ninjadraw')
        );
      }

      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' => 'ninjadraw',
        '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', 'ninjadraw')
      );
    }

    if (AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_EDIT) && FreemiusModel::isLicensed()) {
      $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', 'ninjadraw')
      );
    }

    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', 'ninjadraw')
      );
    }

    if (AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_EDIT)) {
      return sprintf(
        '<strong><a href="?page=ninjadraw&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="ninjadraw-shortcode"><span class="ninjadraw-val">[ninjadraw id="%s"]</span><div class="ninjadraw-btn" title="%s" style="display:none;">%s%s</div></div>',
      $item['id'],
      esc_html__('Copy to clipboard', 'ninjadraw'),
      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", "ninjadraw"),
      "shortcode" => esc_html__("Shortcode", "ninjadraw"),
      "author" => esc_html__("Author", "ninjadraw"),
      "edited_by" => esc_html__("Edited by", "ninjadraw"),
      "role" => esc_html__("Role", "ninjadraw"),
      "created" => esc_html__("Created", "ninjadraw"),
      "edited" => esc_html__("Edited", "ninjadraw")
    ];
    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', 'ninjadraw'), $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', 'ninjadraw'), $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', 'ninjadraw'), $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', 'ninjadraw'), $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', 'ninjadraw'), $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', 'ninjadraw'),
          'delete' => esc_html__('Delete Permanently', 'ninjadraw')
        ];
      }
    } else {
      if (AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_EDIT) && FreemiusModel::isLicensed()) {
        $actions['copy'] = esc_html__('Duplicate', 'ninjadraw');
      }
      if (AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_DELETE)) {
        $actions['trash'] = esc_html__('Move to Trash', 'ninjadraw');
      }
    }
    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;
          }
        }
      }
      
      $request_uri = wp_unslash( $_SERVER['REQUEST_URI'] ?? '' );
      if (!empty($request_uri)) {
        wp_safe_redirect( remove_query_arg( ['action', 'id', '_wpnonce'], $request_uri ), 303 );
        exit;
      }

      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
    ]);
  }
}
