<?php

namespace SEOAIC\content_improvement_suggestions;

use Exception;
use SEOAIC\helpers\HTMLBuilers;
use SEOAIC\repositories\ContentImprovementSuggestionsRepository;
use SEOAIC\repositories\PostRepository;
use WP_Post;

abstract class AbstractContentImprovementSuggestion
{
    protected $contentImprovementSuggestionsRepository;
    protected $postRepository;
    protected $id;
    protected $label;
    protected $description;
    protected $placeholderWordsCount = 8;
    protected $placeholderMinWordWidth = 1;
    protected $placeholderMaxWordWidth = 5;
    public $canGenerateSuggestion = true;

    abstract public function currentValue(WP_Post $post);
    abstract public function issueShouldBeFixed($value): bool;
    abstract protected function applyNewValue(WP_Post $post, $newValue): bool;

    public function __construct()
    {
        global $SEOAIC;

        $this->contentImprovementSuggestionsRepository = new ContentImprovementSuggestionsRepository($SEOAIC);
        $this->postRepository = new PostRepository($SEOAIC);
    }

    public function getId(): string
    {
        return $this->id;
    }

    public function getLabel(): string
    {
        return $this->label;
    }

    public function getDescription(): string
    {
        return $this->description;
    }

    public function apply(int $postId)
    {
        $save = false;
        $post = get_post($postId);

        if (empty($post)) {
            throw new Exception(esc_html__("Post not found.", "seoaic"));
        }

        $issuesData = $this->contentImprovementSuggestionsRepository->getSavedPostIssues($post);

        if (
            empty($issuesData)
            || empty($issuesData['issues'])
        ) {
            throw new Exception(esc_html__("No issues found for the post.", "seoaic"));
        }

        foreach ($issuesData['issues'] as &$issueData) {
            if (
                $issueData['issue'] == $this->getId()
                && $this->applyNewValue($post, $issueData['new_value'])
            ) {
                $issueData['status'] = ContentImprovementSuggestionsRepository::CI_POST_ISSUE_STATUS_ACCEPTED;

                $save = true;
                break;
            }
        }

        if (
            $save
            && $this->contentImprovementSuggestionsRepository->savePostIssues($post, $issuesData)
        ) {
            return true;
        }

        return false;
    }

    public function reject(int $postId)
    {
        $post = get_post($postId);
        $save = false;

        if (empty($post)) {
            throw new Exception(esc_html__("Post not found.", "seoaic"));
        }

        $issuesData = $this->contentImprovementSuggestionsRepository->getSavedPostIssues($post);
        // error_log('issuesData '.print_r($issuesData, true));
        if (
            empty($issuesData)
            || empty($issuesData['issues'])
        ) {
            throw new Exception(esc_html__("No issues found for the post.", "seoaic"));
        }

        foreach ($issuesData['issues'] as &$issue) {
            if ($issue['issue'] == $this->getId()) {
                $issue['status'] = ContentImprovementSuggestionsRepository::CI_POST_ISSUE_STATUS_REJECTED;

                $save = true;
                break;
            }
        }

        if (
            $save
            && $this->contentImprovementSuggestionsRepository->savePostIssues($post, $issuesData)
        ) {
            return true;
        }

        return false;
    }

    public function makePlaceholder()
    {
        if ($this->canGenerateSuggestion) {
            return HTMLBuilers::textPlaceholder($this->placeholderWordsCount, $this->placeholderMinWordWidth, $this->placeholderMaxWordWidth);
        }

        return '';
    }
}
