<?php

namespace Tricks\LaravelSitemapForDynamicPages\Http\Controllers;

use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\File;
use ReflectionClass;
use Spatie\Sitemap\Sitemap;
use Spatie\Sitemap\Tags\Url;
use Symfony\Component\HttpFoundation\Response;

class Controller
{
    use ValidatesRequests;
    public function __invoke(Request $request, $extension): array|Response
    {
        $sitemap = Sitemap::create();

        $methodName = 'getSitemapEntries';

        $urls = collect(File::allFiles(app_path()))
            ->map(fn($item) => $item->getRelativePathName())
            ->map(fn($path) => sprintf('\%s%s',
                Container::getInstance()->getNamespace(),
                strtr(substr($path, 0, strrpos($path, '.')), '/', '\\'))
            )
            ->filter(fn($className) => class_exists($className))
            ->map(fn($className) => new ReflectionClass($className))
            ->filter(fn($reflection) => $reflection->isSubclassOf(Model::class) && !$reflection->isAbstract())
            ->filter(fn($reflection) => $reflection->hasMethod($methodName))
            ->map(fn($reflection) => $reflection->newInstance())
            ->flatMap(fn($modelInstance) => $modelInstance->all())
            ->flatMap(fn($instance) => $instance->$methodName());

        if ($extension === 'json') {
            return response()->json($urls);
        }

        $urls->map(fn($url) => Url::create($url)->setLastModificationDate(Carbon::yesterday())
            ->setChangeFrequency(Url::CHANGE_FREQUENCY_YEARLY)
            ->setPriority(0.1))
            ->each(fn($url) => $sitemap->add($url));

        return $sitemap->toResponse($request);

    }
}
