<?php

namespace OtomaticAi\Models;

use OtomaticAi\Casts\Language;
use OtomaticAi\Models\Contracts\Publishable;
use OtomaticAi\Models\WP\Post;
use OtomaticAi\Traits\HasLogs;
use OtomaticAi\Utils\Support;
use OtomaticAi\Vendors\Carbon\Carbon;
use OtomaticAi\Vendors\Illuminate\Database\Eloquent\Builder;
use OtomaticAi\Vendors\Illuminate\Database\Eloquent\Model;
use OtomaticAi\Vendors\Illuminate\Support\Arr;

class Netlinking extends Model implements Publishable
{
    use HasLogs;

    protected $fillable = [
        "uuid",
        "title",
        'language',
        'target_url',
        'anchor_text',
        'modules',
        'persona_id',
        'post_id',
        'status',
        'generation_state',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = ['edit_link', 'display_link'];

    protected $casts = [
        'language' => Language::class,
        'modules' => 'array',
        'logs' => 'array',
        'generation_state' => 'array',
    ];

    protected $extras = [];

    /**
     * Create a new Eloquent model instance.
     *
     * @param  array  $attributes
     * @return void
     */
    public function __construct(array $attributes = [])
    {
        global $wpdb;

        $this->table = $wpdb->prefix . 'otomatic_ai_netlinking';
        parent::__construct($attributes);
    }

    /**
     * Get the persona that owns the netlinking.
     */
    public function persona()
    {
        return $this->belongsTo(Persona::class);
    }

    /**
     * Get the wp post that owns the netlinking.
     */
    public function post()
    {
        return $this->belongsTo(Post::class, "post_id");
    }

    /**
     * Scope a query to only include published publications.
     */
    public function scopePublished(Builder $query): void
    {
        $query->where('status', 'success');
    }

    /**
     * Scope a query to only include idle publications.
     */
    public function scopeIdle(Builder $query): void
    {
        $query->where('status', 'idle');
    }

    /**
     * Scope a query to only include pending publications.
     */
    public function scopePending(Builder $query): void
    {
        $query->where('status', 'pending');
    }

    /**
     * Scope a query to only include failed publications.
     */
    public function scopeFailed(Builder $query): void
    {
        $query->where('status', 'failed');
    }

    /**
     * Get the modules of the netlinking.
     */
    public function getModulesAttribute()
    {
        $modules = json_decode($this->attributes["modules"], true);

        // add custom link
        if (!empty($this->attributes["target_url"])) {
            Arr::set($modules, "content.automatic.custom_links.enabled", true);
            Arr::set($modules, "content.automatic.custom_links.links", [
                [
                    "url" => $this->attributes["target_url"],
                    "anchor" => Arr::get($this->attributes, "anchor_text", Support::getHostname($this->attributes["target_url"], $this->attributes["target_url"])),
                    "blank" => false,
                    "nofollow" => false,
                ]
            ]);
        }

        return Project::makeModules('bulk', $modules);
    }

    /**
     * Get the wordpress edit link of the post publication.
     */
    public function getEditLinkAttribute()
    {
        if ($this->post_id !== null) {
            return get_edit_post_link($this->post_id, 'json');
        }

        return null;
    }

    /**
     * Get the wordpress display link of the post publication.
     */
    public function getDisplayLinkAttribute()
    {
        if ($this->post_id !== null) {
            return get_permalink($this->post_id);
        }

        return null;
    }

    public function getGenerationTitleAttribute()
    {
        return $this->title;
    }

    public function getExtrasAttribute()
    {
        return $this->extras;
    }

    public function setExtrasAttribute($value)
    {
        $this->extras = $value;
    }
}
