<?php

declare(strict_types=1);

namespace CliqThemes\StoreLocator\Integrations;

defined('ABSPATH') || exit;

use CliqThemes\StoreLocator\Frontend\FrontendModule;
use CliqThemes\StoreLocator\Models\Store;

/**
 * Source of SEO values for the store-detail page, shared by every SEO-plugin
 * integration so they all expose identical title/description/canonical/image
 * data. The "current store" is resolved through a callback (FrontendModule's
 * cached resolver) so we never re-query — and never double-log a view.
 */
final class StoreDetailSeo
{
    /** @var callable():(array<string,mixed>|null) */
    private $resolver;

    /** @param callable():(array<string,mixed>|null) $resolver */
    public function __construct(callable $resolver)
    {
        $this->resolver = $resolver;
    }

    /** The current request's store-detail payload, or null when not a detail page. */
    public function store(): ?array
    {
        return ($this->resolver)();
    }

    public function isStoreDetail(): bool
    {
        return $this->store() !== null;
    }

    public function name(): string
    {
        $store = $this->store();
        return $store ? (string) ($store['name'] ?? '') : '';
    }

    /** Document/OG title: "{store} {separator} {site}". */
    public function title(string $separator = '-'): string
    {
        $name = $this->name();
        if ($name === '') {
            return '';
        }

        return $name . ' ' . $separator . ' ' . get_bloginfo('name');
    }

    /** Trimmed plain-text meta description from the store description. */
    public function description(): string
    {
        $store = $this->store();
        if (! $store) {
            return '';
        }
        $desc = wp_strip_all_tags((string) ($store['description'] ?? ''));

        return $desc !== '' ? wp_trim_words($desc, 30) : '';
    }

    /** Canonical / OG url for the current store. */
    public function canonical(): string
    {
        $store = $this->store();
        if (! $store) {
            return '';
        }

        return (string) ($store['detail_url'] ?? FrontendModule::storePermalink((string) ($store['slug'] ?? '')));
    }

    /** OG image (the store hero), or empty when none. */
    public function image(): string
    {
        $store = $this->store();
        if (! $store) {
            return '';
        }
        if (is_array($store['hero_media'] ?? null)) {
            return (string) ($store['hero_media']['url'] ?? '');
        }

        return (string) ($store['hero_media'] ?? '');
    }

    /**
     * Every published store's detail URL for an XML sitemap.
     *
     * @return array<int, array{loc: string, lastmod: string}>
     */
    public function storeUrls(): array
    {
        $rows = Store::query()
            ->where('status', '=', 'active')
            ->orderBy('id', 'ASC')
            ->raw();

        $urls = [];
        foreach ($rows as $row) {
            $slug = (string) ($row['slug'] ?? '');
            if ($slug === '') {
                continue;
            }
            $urls[] = [
                'loc' => FrontendModule::storePermalink($slug),
                'lastmod' => (string) ($row['updated_at'] ?? $row['created_at'] ?? ''),
            ];
        }

        return $urls;
    }
}
