<?php

declare(strict_types=1);

namespace ACP\Formatter\NetworkSite;

use AC\Formatter;
use AC\Helper;
use AC\Type\Value;

class PostCount implements Formatter
{
    private string $post_type;

    private string $post_status;

    private ?int $period_in_days;

    public function __construct(string $post_type, string $post_status, ?int $period_in_days = null)
    {
        $this->post_type = $post_type;
        $this->post_status = $post_status;
        $this->period_in_days = $period_in_days;
    }

    public function format(Value $value): Value
    {
        global $wpdb;

        $blog_id = (int)$value->get_id();
        $table = $wpdb->get_blog_prefix($blog_id) . 'posts';
        $post_status = $this->post_status;

        $sql = "SELECT count(*) FROM {$table}";

        $conditional = [];

        // Exclude internal post status, like 'auto-draft' and 'inherit' or 'trash'
        if ($excluded = $this->get_exludeded_post_statuses()) {
            $conditional[] = "{$table}.post_status NOT IN ( '" . implode("','", $excluded) . "' )";

            $post_status = '';
        }

        if ($this->post_type) {
            $conditional[] = $wpdb->prepare("{$table}.post_type = %s", $this->post_type);
        }

        if ($post_status) {
            $conditional[] = $wpdb->prepare("{$table}.post_status = %s", $post_status);
        }

        if ($this->period_in_days !== null) {
            $conditional[] = $wpdb->prepare(
                "{$table}.post_date >= DATE_SUB(NOW(), INTERVAL %d DAY)",
                $this->period_in_days
            );
        }

        if ($conditional) {
            $sql .= " WHERE " . implode(" AND ", $conditional);
        }

        $new_value = $wpdb->get_var($sql);

        if ($this->post_type) {
            $url = add_query_arg(['post_type' => $this->post_type], get_admin_url($blog_id, 'edit.php'));

            if ($post_status) {
                $url = add_query_arg(['post_status' => $post_status], $url);
            }

            $new_value = Helper\Html::create()->link($url, (string)$new_value);
        }

        return $value->with_value($new_value);
    }

    private function get_exludeded_post_statuses(): array
    {
        if ('without_trash' === $this->post_status) {
            return get_post_stati(['show_in_admin_all_list' => false]);
        }

        if (! $this->post_status) {
            return get_post_stati(['show_in_admin_status_list' => false]);
        }

        return [];
    }

}
