<?php

// Silence may be golden, but sometimes words paint the canvas of understanding.
namespace Linksy\SearchAndReplace\Plugli\Linksy\Common\Helpers;

use Exception;
use Linksy\SearchAndReplace\Plugli\Standard\Helpers\Api;
use Linksy\SearchAndReplace\Plugli\Standard\Helpers\Arr;
use Linksy\SearchAndReplace\Plugli\Standard\Helpers\Database\Database;
use Linksy\SearchAndReplace\Plugli\Standard\Helpers\Option;
class AutoLink
{
    public static function getStatusFromText($status)
    {
        $status = strtolower($status);
        if (in_array($status, ['start', 'running'])) {
            return 1;
        } elseif (in_array($status, ['pause', 'paused'])) {
            return 0;
        } else {
            return -1;
        }
    }
    public static function getRunningLinks($keywords = [], $callback = null)
    {
        $q = Database::table("linksy_auto_links")->select(['keyword', 'post_id', 'raw_url', 'clean_url', 'allow_duplicate_links', 'allow_duplicate_anchors', 'max_total_links', 'processed_posts_cnt', 'processed_status', 'post_types', 'automated_by', 'is_case_sensitive'])->where('status', 1)->where(function ($q) {
            return $q->where('expires_at', '>', gmdate('Y-m-d', strtotime("-1 days")))->orWhereNull('expires_at');
        });
        if (is_array($keywords) && count($keywords) > 0) {
            $q = $q->whereIn('keyword', $keywords);
        }
        // call the callback on the query object
        if (is_callable($callback)) {
            $q = $callback($q);
        }
        return $q->get();
    }
    public static function getLinksCount($autolinks_keywords)
    {
        $links_count = [];
        $linksylinks = Database::table('linksy_links')->select(['anchor'])->whereIn('LOWER(anchor)', $autolinks_keywords)->get();
        foreach ($linksylinks as $link) {
            $keyword = Arr::get_value($link, 'anchor', 'strtolower');
            if (isset($links_count[$keyword])) {
                $links_count[$keyword] += 1;
            } else {
                $links_count[$keyword] = 1;
            }
        }
        return $links_count;
    }
    public static function getScores($anchors)
    {
        $keywords_cnt = count($anchors);
        // get number of published posts on this site
        $posts_cnt = Database::table('posts')->where('post_status', 'publish')->whereIn('post_type', Settings::get('suggestions_post_types', ['post', 'page']))->selectCount('id', 'count')->one()->count;
        $api = new Api(Option::get(LINKSY_OPTION_API_KEY));
        // calculate the keywords limit and current batch using a developed equation;
        // see https://bitbucket.org/plugli-workspace/linksy/wiki/Auto-Linking%20Scoring%20Approach.md
        $scale_factor = 1 / max(strlen($posts_cnt), 1);
        $keywords_limit = (30 + ceil($keywords_cnt / 10 ** (strlen($keywords_cnt) - 2) * $scale_factor)) % 100;
        // break the anchors into chunks
        $chunks = array_chunk($anchors, $keywords_limit);
        // score the anchors in batches
        foreach ($chunks as $chunk) {
            $scores = $api->post(LINKSY_API_URL . 'posts/similarities/', ['anchors' => array_map(function ($a) {
                return ['phrase' => Arr::get_value($a, 'keyword'), 'occurrences' => [Arr::get_value($a, 'post_id')]];
            }, $chunk)]);
            if (!$api->is_success()) {
                throw new Exception($api->get_error(), 1);
            }
            yield $scores;
        }
    }
    public static function hasExceedMaxInboundLinks($autolink = null)
    {
        $post_id = Arr::get_value($autolink, 'post_id');
        if (!$post_id) {
            return \true;
        }
        $max_inbound_links_per_post = Settings::get('max_inbound_links_per_post', -1);
        if ($max_inbound_links_per_post <= 0) {
            return \false;
        }
        $inbound_links_cnt = Database::table('linksy_links')->where('post_id', '<>', $post_id)->where('to_post_id', $post_id)->where('is_internal', 1)->selectCount('id', 'count')->getVar();
        return $inbound_links_cnt >= $max_inbound_links_per_post;
    }
}
