<?php
/**
 * Prohibit direct script loading
 */
defined('ABSPATH') || die('No direct script access allowed!');

/**
 * Class WpmsGscCount
 */
class WpmsGscCount
{
    /**
     * Google search console service
     *
     * @var WpmsGscService
     */
    private $service;
    /**
     * Holder for the fetched issues from GSC
     *
     * @var array
     */
    private $issues = array();

    /**
     * WpmsGscCount constructor.
     * Fetching the counts
     *
     * @param WpmsGscService $service Google search console service
     */
    public function __construct(WpmsGscService $service)
    {
        $this->service = $service;
    }

    /**
     * Getting the counts for given platform and return them as an array
     *
     * @param string $platform Platform (desktop, mobile, feature phone).
     *
     * @return array
     */
    public function countsPlat($platform)
    {
        $counts = $this->getCounts();
        if (isset($counts[$platform])) {
            return $counts[$platform];
        }

        return array();
    }

    /**
     * Listing the issues an gives them back as fetched issues
     *
     * @param string $platform Platform (desktop, mobile, feature phone).
     * @param string $category Issue category.
     *
     * @return void
     */
    public function listIssues($platform, $category)
    {
        $counts = $this->getCounts();
        if (isset($counts[$platform])) {
            // create new counts value
            $counts[$platform] = $this->listCatIssues($counts[$platform], $platform, $category);
            $this->setCounts($counts);
        }
    }

    /**
     * Return the fetched issues
     *
     * @return array
     */
    public function getIssues()
    {
        return $this->issues;
    }

    /**
     * Update the count of the issues
     *
     * @param string  $platform  Platform (desktop, mobile, feature phone).
     * @param string  $category  Issue type.
     * @param integer $new_count Updated count.
     *
     * @return void
     */
    public function updateCountIssue($platform, $category, $new_count)
    {
        $counts = $this->getCounts();

        if (!empty($counts[$platform][$category]) && is_array($counts[$platform][$category])) {
            $counts[$platform][$category]['count'] = $new_count;
        }

        $this->setCounts($counts);
    }

    /**
     * Getting the counts for given platform and category.
     *
     * @param string $platform Platform (desktop, mobile, feature phone).
     * @param string $category Issue type.
     *
     * @return integer
     */
    public function countIssue($platform, $category)
    {
        $counts = $this->getCounts();

        if (!empty($counts[$platform][$category]['count'])) {
            return $counts[$platform][$category]['count'];
        }

        return 0;
    }

    /**
     * Fetching the counts from the GSC API
     *
     * @return void
     */
    public function fetchCounts()
    {
        $last_fetch = get_option(WPMS_GSC_LAST_FETCH, 0);
        if (WpmsGsc::getProfile() && $last_fetch <= strtotime('-12 hours')) {
            // Remove timestamp
            delete_option(WPMS_GSC_LAST_FETCH);
            // Get counts
            $counts = $this->gscCounts($this->service->getCountCrawlIssue());
            // Fetch counts
            $this->setCounts($counts);
            // Save timestamp.
            add_option(WPMS_GSC_LAST_FETCH, time(), '', 'no');
        }
    }

    /**
     * Parsing the received counts from the API and map the keys to plugin friendly values
     *
     * @param array $fetched_counts Set of retrieved counts.
     *
     * @return array
     */
    private function gscCounts(array $fetched_counts)
    {
        $counts = array();
        foreach ($fetched_counts as $platform_name => $categories) {
            $plat_new = WpmsGscMapper::platFromApi($platform_name);

            foreach ($categories as $cat_name => $cat) {
                $new_cat                     = WpmsGscMapper::catFromApi($cat_name);
                $counts[$plat_new][$new_cat] = $cat;
            }
        }

        return $counts;
    }

    /**
     * Getting the counts from the options
     *
     * @return array
     */
    private function getCounts()
    {
        return get_option(WPMS_GSC_COUNTS, array());
    }

    /**
     * Fetching the counts from the service and store them in an option
     *
     * @param array $counts Set of counts.
     *
     * @return void
     */
    private function setCounts(array $counts)
    {
        update_option(WPMS_GSC_COUNTS, $counts);
    }

    /**
     * Listing the issues for current category.
     *
     * @param array  $counts Set of counts.
     * @param string $plat   Platform (desktop, mobile, feature phone).
     * @param string $cat    Issue type.
     *
     * @return array
     */
    private function listCatIssues(array $counts, $plat, $cat)
    {
        if (isset($counts[$cat]) && $counts[$cat]['count'] > 0
            && $counts[$cat]['last_fetch'] <= strtotime('-12 hours')) {
            $plat_to_api = WpmsGscMapper::platToApi($plat);
            $cat_to_api  = WpmsGscMapper::catToApi($cat);
            $issues      = $this->service->fetchCatIssues($plat_to_api, $cat_to_api);
            if ($issues) {
                $this->issues = $issues;
            }

            $counts[$cat]['count'] = count($this->issues);
            // create last fetch
            $counts[$cat]['last_fetch'] = time();
        }

        return $counts;
    }
}
