<?php

namespace WPSN\Modules\Analysis\Admin;

defined('ABSPATH') || exit;

// WP_List_Table is not automatically loaded on all admin pages.
if (!class_exists('WP_List_Table')) {
    require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}

/**
 * WP_List_Table for Tools → Low score pages report.
 */
final class LowScoreListTable extends \WP_List_Table
{
    /** @var array{pt:string,status:string,max:int,include_na:bool,s:string} */
    private array $filters;

    private LowScoreQuery $query;

    public function __construct(array $filters)
    {
        $this->filters = $filters;
        $this->query = new LowScoreQuery();

        parent::__construct([
            'singular' => 'wpsn_low_score_row',
            'plural'   => 'wpsn_low_score_rows',
            'ajax'     => false,
        ]);
    }

    public function get_columns(): array
    {
        return [
            'score' => __('Score', 'wp-seo-next'),
            'title' => __('Title', 'wp-seo-next'),
            'type' => __('Type', 'wp-seo-next'),
            'status' => __('Status', 'wp-seo-next'),
            'modified' => __('Modified', 'wp-seo-next'),
        ];
    }

    protected function get_default_primary_column_name(): string
    {
        return 'title';
    }

    public function get_sortable_columns(): array
    {
        return [
            'score' => ['score', true],
            'title' => ['title', false],
            'modified' => ['modified', false],
        ];
    }

    public function no_items(): void
    {
        echo esc_html__('No matching pages found.', 'wp-seo-next');
    }

    public function prepare_items(): void
    {
        $perPage = $this->get_items_per_page('wpsn_analysis_report_per_page', 20);
        $paged = $this->get_pagenum();
        $offset = ($paged - 1) * $perPage;

        $orderby = isset($_REQUEST['orderby']) ? sanitize_key((string) wp_unslash($_REQUEST['orderby'])) : 'score';
        $order = isset($_REQUEST['order']) ? strtoupper((string) wp_unslash($_REQUEST['order'])) : 'ASC';
        $order = in_array($order, ['ASC', 'DESC'], true) ? $order : 'ASC';

        $filters = $this->filters;
        $filters['orderby'] = $orderby;
        $filters['order'] = $order;

        [$items, $total] = $this->query->fetch($filters, $perPage, $offset);

        $this->items = $items;

        $this->set_pagination_args([
            'total_items' => $total,
            'per_page'    => $perPage,
            'total_pages' => (int) ceil($total / $perPage),
        ]);
    }

    /**
     * @param array<string,mixed> $item
     */
    protected function column_score(array $item): string
    {
        $raw = $item['score'] ?? null;
        $score = is_numeric($raw) ? (int) $raw : null;
        if ($score === null) {
            return '<span style="opacity:.65">—</span>';
        }

        $score = max(0, min(100, $score));

        $badgeStyle = 'display:inline-block;min-width:36px;text-align:center;padding:2px 8px;border-radius:999px;font-weight:600;font-size:12px;border:1px solid rgba(0,0,0,.12);';
        if ($score >= 80) {
            $badgeStyle .= 'border-color:rgba(0,128,0,.25);';
        } elseif ($score >= 55) {
            $badgeStyle .= 'border-color:rgba(230,150,0,.35);';
        } else {
            $badgeStyle .= 'border-color:rgba(200,0,0,.35);';
        }
        return '<span style="' . esc_attr($badgeStyle) . '">' . esc_html((string) $score) . '</span>';
    }

    /**
     * @param array<string,mixed> $item
     */
    protected function column_title(array $item): string
    {
        $id = (int) ($item['ID'] ?? 0);
        if ($id <= 0) {
            return '';
        }

        $title = (string) ($item['post_title'] ?? '');
        $title = $title !== '' ? $title : __('(no title)', 'wp-seo-next');

        $editLink = get_edit_post_link($id, '');
        $viewLink = get_permalink($id);

        $out = '';
        if (is_string($editLink) && $editLink !== '') {
            $out .= '<a href="' . esc_url($editLink) . '"><strong>' . esc_html($title) . '</strong></a>';
        } else {
            $out .= '<strong>' . esc_html($title) . '</strong>';
        }

        $actions = [];
        if (is_string($editLink) && $editLink !== '') {
            $actions['edit'] = '<a href="' . esc_url($editLink) . '">' . esc_html__('Edit', 'wp-seo-next') . '</a>';
        }
        if (is_string($viewLink) && $viewLink !== '') {
            $actions['view'] = '<a href="' . esc_url($viewLink) . '" target="_blank" rel="noopener noreferrer">' . esc_html__('View', 'wp-seo-next') . '</a>';
        }

        if (!empty($actions)) {
            $out .= $this->row_actions($actions);
        }

        return $out;
    }

    /**
     * @param array<string,mixed> $item
     */
    protected function column_type(array $item): string
    {
        $pt = (string) ($item['post_type'] ?? '');
        $obj = $pt !== '' ? get_post_type_object($pt) : null;
        if ($obj && !empty($obj->labels->singular_name)) {
            return esc_html((string) $obj->labels->singular_name);
        }
        return esc_html($pt);
    }

    /**
     * @param array<string,mixed> $item
     */
    protected function column_status(array $item): string
    {
        $st = (string) ($item['post_status'] ?? '');
        $obj = $st !== '' ? get_post_status_object($st) : null;
        if ($obj && !empty($obj->label)) {
            return esc_html((string) $obj->label);
        }
        return esc_html($st);
    }

    /**
     * @param array<string,mixed> $item
     */
    protected function column_modified(array $item): string
    {
        $gmt = (string) ($item['post_modified_gmt'] ?? '');
        if ($gmt === '' || $gmt === '0000-00-00 00:00:00') {
            return '<span style="opacity:.7">—</span>';
        }
        $local = get_date_from_gmt($gmt, get_option('date_format') . ' ' . get_option('time_format'));
        return esc_html($local);
    }

    /**
     * @param array<string,mixed> $item
     * @param string $column_name
     */
    public function column_default($item, $column_name)
    {
        return '';
    }
}
