<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class GuidePage extends Model
{
    protected $fillable = [
        'guide_id',
        'title',
        'content',
        'options',
    ];

    protected $casts = [
        'options' => 'array',
    ];

    protected static function booted(): void
    {
        static::deleting(function (GuidePage $page) {
            // CASCADE on from_page_id is handled by FK, but incoming edges need cleanup
            GuidePageEdge::where('to_page_id', $page->id)->delete();
        });
    }

    public function getUriAttribute(): string
    {
        return route('guides.pages.show', $this->id);
    }

    public function getNormalizedContentAttribute(): string
    {
        return static::normalizeRichTextContent($this->content);
    }

    public static function normalizeRichTextContent(?string $content): string
    {
        if (blank($content)) {
            return '';
        }

        $content = preg_replace_callback(
            '~(?:https?:)?//[^"\'\s<>()]+(?<path>/storage/guide-pages/[^"\'\s<>()]*)~i',
            static fn (array $matches): string => $matches['path'],
            $content,
        ) ?? $content;

        return preg_replace(
            '~(?<=["\'])storage/guide-pages/~i',
            '/storage/guide-pages/',
            $content,
        ) ?? $content;
    }

    public static function uploadedAttachmentUrl(string $path): string
    {
        return '/storage/'.ltrim($path, '/');
    }

    public function guide()
    {
        return $this->belongsTo(Guide::class);
    }

    public function outgoingEdges()
    {
        return $this->hasMany(GuidePageEdge::class, 'from_page_id')->orderBy('sort');
    }

    public function incomingEdges()
    {
        return $this->hasMany(GuidePageEdge::class, 'to_page_id');
    }

    public function nextPages()
    {
        return $this->belongsToMany(self::class, 'guide_page_edges', 'from_page_id', 'to_page_id')
            ->withPivot('label', 'sort')
            ->orderByPivot('sort');
    }

    public function previousPages()
    {
        return $this->belongsToMany(self::class, 'guide_page_edges', 'to_page_id', 'from_page_id')
            ->withPivot('label', 'sort');
    }

    public function isEntry(): bool
    {
        return ! $this->incomingEdges()->exists();
    }
}
