<?php
/**
 * Content Builder — Public API.
 *
 * Other plugins call ContentBuilderAPI::* and NEVER read/write
 * contentbuilder_* tables directly. This class is the contract.
 *
 * Usage from another plugin:
 *
 *   if (PluginLoader::isActive('content-builder') && class_exists('ContentBuilderAPI')) {
 *       $page = ContentBuilderAPI::getPostBySlug('page', 'home');
 *   }
 */

class ContentBuilderAPI {

    protected static string $pluginDir = '';
    protected static bool $schemaChecked = false;

    public static function setPluginDir(string $dir): void {
        self::$pluginDir = rtrim($dir, '/');
    }
    public static function pluginDir(): string {
        return self::$pluginDir;
    }

    /**
     * Create any missing tables. Runs once per request (cheap, guarded).
     * This makes upgrades self-healing: dropping a newer build over an
     * existing install adds new tables (e.g. menus) without needing the
     * admin to deactivate/reactivate so install.sql re-runs.
     */
    public static function ensureSchema(): void {
        if (self::$schemaChecked) return;
        self::$schemaChecked = true;
        try {
            $pdo = Database::get();
            $pdo->exec(
                "CREATE TABLE IF NOT EXISTS `contentbuilder_menus` (
                    `id`         INT UNSIGNED NOT NULL AUTO_INCREMENT,
                    `tenant_id`  INT UNSIGNED NOT NULL DEFAULT 1,
                    `name`       VARCHAR(128) NOT NULL,
                    `location`   VARCHAR(32)  NOT NULL DEFAULT '',
                    `items`      JSON         NULL,
                    `created_at` DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
                    `updated_at` DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                    PRIMARY KEY (`id`),
                    KEY `tenant_loc` (`tenant_id`,`location`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
            );
            $pdo->exec(
                "CREATE TABLE IF NOT EXISTS `contentbuilder_post_meta` (
                    `post_id`  INT UNSIGNED NOT NULL,
                    `meta_key` VARCHAR(128) NOT NULL,
                    `meta_val` TEXT NULL,
                    PRIMARY KEY (`post_id`, `meta_key`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
            );
        } catch (\Throwable $ex) {
            // Don't fatal the whole request if the DB user lacks CREATE;
            // the admin can deactivate/reactivate to run install.sql instead.
            if (function_exists('slate_log')) {
                slate_log('ContentBuilder ensureSchema failed: ' . $ex->getMessage(), 'warning');
            }
        }

        self::seedDemoPage();
    }

    /** Demo seed version — bump when demo-landing.json changes to re-apply. */
    const DEMO_SEED_VERSION = '1.5.0';

    /** Create/refresh a polished demo landing page so users see a finished example. */
    protected static function seedDemoPage(): void {
        try {
            $tenantId = current_tenant_id();
            $existing = Database::row(
                "SELECT id FROM contentbuilder_posts WHERE tenant_id = ? AND type = 'page' AND slug = ?",
                [$tenantId, 'demo']);

            $seededVer = (string)self::getSiteSetting('demo_seed_version', '');

            // Already current — nothing to do.
            if ($existing && $seededVer === self::DEMO_SEED_VERSION) return;

            $file = self::$pluginDir . '/lib/demo-landing.json';
            $layout = is_file($file) ? (string)file_get_contents($file) : '[]';
            json_decode($layout); // validate
            if (json_last_error() !== JSON_ERROR_NONE) return;

            if ($existing) {
                // Refresh the auto-seeded demo content to the new design.
                Database::update('contentbuilder_posts',
                    ['layout' => $layout, 'status' => 'published'],
                    'id = ? AND tenant_id = ?', [$existing['id'], $tenantId]);
            } else {
                Database::insert('contentbuilder_posts', [
                    'tenant_id'    => $tenantId,
                    'type'         => 'page',
                    'title'        => 'Demo landing',
                    'slug'         => 'demo',
                    'status'       => 'published',
                    'layout'       => $layout,
                    'published_at' => date('Y-m-d H:i:s'),
                ]);
            }
            self::setSiteSetting('demo_seed_version', self::DEMO_SEED_VERSION);
        } catch (\Throwable $ex) {
            // best-effort seed; ignore failures
        }
    }

    /* ──────────────────────────── Post types ─────────────────────────── */

    public static function getPostTypes(?int $tenantId = null): array {
        return PostType::all($tenantId);
    }

    public static function getPostType(string $slug, ?int $tenantId = null): ?array {
        return PostType::get($slug, $tenantId);
    }

    public static function registerPostType(array $def, ?int $tenantId = null): int {
        $tenantId = $tenantId ?? current_tenant_id();
        $slug = self::slugify($def['slug'] ?? '');
        if ($slug === '') throw new InvalidArgumentException('Post type slug required.');

        $existing = PostType::get($slug, $tenantId);
        $row = [
            'tenant_id'    => $tenantId,
            'slug'         => $slug,
            'label'        => trim($def['label'] ?? ucfirst($slug)),
            'singular'     => trim($def['singular'] ?? ucfirst($slug)),
            'hierarchical' => !empty($def['hierarchical']) ? 1 : 0,
            'is_builtin'   => !empty($def['is_builtin']) ? 1 : 0,
            'supports'     => json_encode($def['supports'] ?? ['title', 'editor']),
        ];
        if ($existing) {
            Database::update('contentbuilder_post_types', $row,
                'id = ?', [$existing['id']]);
            return (int)$existing['id'];
        }
        return Database::insert('contentbuilder_post_types', $row);
    }

    public static function deletePostType(int $id, ?int $tenantId = null): void {
        $tenantId = $tenantId ?? current_tenant_id();
        $pt = Database::row(
            "SELECT * FROM contentbuilder_post_types WHERE id = ? AND tenant_id = ?",
            [$id, $tenantId]);
        if (!$pt || (int)$pt['is_builtin'] === 1) return; // never delete built-ins
        Database::query("DELETE FROM contentbuilder_post_types WHERE id = ?", [$id]);
    }

    /* ──────────────────────────────── Posts ──────────────────────────── */

    public static function getPost(int $id, ?int $tenantId = null): ?array {
        $tenantId = $tenantId ?? current_tenant_id();
        $row = Database::row(
            "SELECT * FROM contentbuilder_posts WHERE id = ? AND tenant_id = ?",
            [$id, $tenantId]);
        return $row ? self::hydrate($row) : null;
    }

    public static function getPostBySlug(string $type, string $slug, ?int $tenantId = null): ?array {
        $tenantId = $tenantId ?? current_tenant_id();
        $row = Database::row(
            "SELECT * FROM contentbuilder_posts
             WHERE tenant_id = ? AND type = ? AND slug = ?",
            [$tenantId, $type, $slug]);
        return $row ? self::hydrate($row) : null;
    }

    public static function listPosts(string $type, array $args = [], ?int $tenantId = null): array {
        $tenantId = $tenantId ?? current_tenant_id();
        $where  = ['tenant_id = ?', 'type = ?'];
        $params = [$tenantId, $type];

        $status = $args['status'] ?? 'published';
        if ($status !== 'any') { $where[] = 'status = ?'; $params[] = $status; }

        $sql = "SELECT * FROM contentbuilder_posts WHERE " . implode(' AND ', $where);

        // Optional term filter (join through relations).
        if (!empty($args['term_id'])) {
            $sql = "SELECT p.* FROM contentbuilder_posts p
                    JOIN contentbuilder_term_relations r ON r.post_id = p.id
                    WHERE " . str_replace('tenant_id', 'p.tenant_id',
                                str_replace('type', 'p.type',
                                str_replace('status', 'p.status', implode(' AND ', $where))))
                  . " AND r.term_id = ?";
            $params[] = (int)$args['term_id'];
        }

        $sql .= " ORDER BY " . (($args['orderby'] ?? 'created_at') === 'title' ? 'title ASC' : 'created_at DESC');
        $limit  = (int)($args['limit'] ?? 20);
        $offset = (int)($args['offset'] ?? 0);
        $sql .= " LIMIT $offset, $limit";

        $rows = Database::rows($sql, $params);
        return array_map([self::class, 'hydrate'], $rows);
    }

    public static function savePost(array $data, ?int $tenantId = null): int {
        $tenantId = $tenantId ?? current_tenant_id();
        $id   = (int)($data['id'] ?? 0) ?: null;
        $type = $data['type'] ?? 'page';
        $slug = self::slugify($data['slug'] ?? ($data['title'] ?? ''));
        if ($slug === '') $slug = 'untitled-' . substr(md5(uniqid('', true)), 0, 6);
        $slug = self::uniqueSlug($type, $slug, $id, $tenantId);

        $row = [
            'tenant_id' => $tenantId,
            'type'      => $type,
            'parent_id' => !empty($data['parent_id']) ? (int)$data['parent_id'] : null,
            'title'     => mb_substr(trim($data['title'] ?? ''), 0, 255),
            'slug'      => $slug,
            'status'    => in_array($data['status'] ?? 'draft', ['draft','published','trash'], true)
                           ? $data['status'] : 'draft',
            'layout'    => json_encode($data['layout'] ?? []),
            'excerpt'   => $data['excerpt'] ?? null,
            'author_id' => $data['author_id'] ?? Auth::userId(),
        ];
        if (($row['status']) === 'published') {
            $row['published_at'] = date('Y-m-d H:i:s');
        }

        if ($id) {
            Database::update('contentbuilder_posts', $row, 'id = ? AND tenant_id = ?', [$id, $tenantId]);
            return $id;
        }
        return Database::insert('contentbuilder_posts', $row);
    }

    public static function publish(int $id, ?int $tenantId = null): void {
        $tenantId = $tenantId ?? current_tenant_id();
        Database::update('contentbuilder_posts',
            ['status' => 'published', 'published_at' => date('Y-m-d H:i:s')],
            'id = ? AND tenant_id = ?', [$id, $tenantId]);
    }

    public static function trash(int $id, ?int $tenantId = null): void {
        $tenantId = $tenantId ?? current_tenant_id();
        Database::update('contentbuilder_posts', ['status' => 'trash'],
            'id = ? AND tenant_id = ?', [$id, $tenantId]);
    }

    public static function deletePost(int $id, ?int $tenantId = null): void {
        $tenantId = $tenantId ?? current_tenant_id();
        Database::query("DELETE FROM contentbuilder_posts WHERE id = ? AND tenant_id = ?", [$id, $tenantId]);
        Database::query("DELETE FROM contentbuilder_post_meta WHERE post_id = ?", [$id]);
        Database::query("DELETE FROM contentbuilder_term_relations WHERE post_id = ?", [$id]);
    }

    public static function countsByType(?int $tenantId = null): array {
        $tenantId = $tenantId ?? current_tenant_id();
        $rows = Database::rows(
            "SELECT type, COUNT(*) AS n FROM contentbuilder_posts
             WHERE tenant_id = ? AND status <> 'trash' GROUP BY type",
            [$tenantId]);
        $out = [];
        foreach ($rows as $r) $out[$r['type']] = (int)$r['n'];
        return $out;
    }

    /* ─────────────────────────────── Post meta ───────────────────────── */
    /* Generic per-post key/value store. Any plugin (SEO, etc.) uses this   */
    /* instead of creating its own join table.                              */

    public static function getMeta(int $postId, string $key, $default = null) {
        $val = Database::value(
            "SELECT meta_val FROM contentbuilder_post_meta WHERE post_id = ? AND meta_key = ?",
            [$postId, $key]);
        return $val === null ? $default : $val;
    }

    public static function getAllMeta(int $postId): array {
        $rows = Database::rows(
            "SELECT meta_key, meta_val FROM contentbuilder_post_meta WHERE post_id = ?",
            [$postId]);
        $out = [];
        foreach ($rows as $r) $out[$r['meta_key']] = $r['meta_val'];
        return $out;
    }

    public static function setMeta(int $postId, string $key, ?string $val): void {
        // upsert
        Database::query(
            "INSERT INTO contentbuilder_post_meta (post_id, meta_key, meta_val)
             VALUES (?, ?, ?)
             ON DUPLICATE KEY UPDATE meta_val = VALUES(meta_val)",
            [$postId, mb_substr($key, 0, 128), $val]);
    }

    public static function deleteMeta(int $postId, string $key): void {
        Database::query(
            "DELETE FROM contentbuilder_post_meta WHERE post_id = ? AND meta_key = ?",
            [$postId, $key]);
    }

    /* ───────────────────────── Taxonomies & terms ────────────────────── */

    public static function getTaxonomies(?string $postType = null, ?int $tenantId = null): array {
        return Taxonomy::all($postType, $tenantId);
    }

    public static function registerTaxonomy(array $def, ?int $tenantId = null): int {
        $tenantId = $tenantId ?? current_tenant_id();
        $slug = self::slugify($def['slug'] ?? '');
        if ($slug === '') throw new InvalidArgumentException('Taxonomy slug required.');
        $existing = Database::row(
            "SELECT * FROM contentbuilder_taxonomies WHERE tenant_id = ? AND slug = ?",
            [$tenantId, $slug]);
        $row = [
            'tenant_id'    => $tenantId,
            'slug'         => $slug,
            'label'        => trim($def['label'] ?? ucfirst($slug)),
            'hierarchical' => !empty($def['hierarchical']) ? 1 : 0,
            'post_types'   => json_encode($def['post_types'] ?? ['post']),
        ];
        if ($existing) {
            Database::update('contentbuilder_taxonomies', $row, 'id = ?', [$existing['id']]);
            return (int)$existing['id'];
        }
        return Database::insert('contentbuilder_taxonomies', $row);
    }

    public static function getTerms(string $taxonomy, ?int $tenantId = null): array {
        $tenantId = $tenantId ?? current_tenant_id();
        return Database::rows(
            "SELECT * FROM contentbuilder_terms
             WHERE tenant_id = ? AND taxonomy = ? ORDER BY name ASC",
            [$tenantId, $taxonomy]);
    }

    public static function getTermBySlug(string $taxonomy, string $slug, ?int $tenantId = null): ?array {
        $tenantId = $tenantId ?? current_tenant_id();
        return Database::row(
            "SELECT * FROM contentbuilder_terms
             WHERE tenant_id = ? AND taxonomy = ? AND slug = ?",
            [$tenantId, $taxonomy, $slug]);
    }

    public static function addTerm(string $taxonomy, string $name, ?int $parent = null, ?int $tenantId = null): int {
        $tenantId = $tenantId ?? current_tenant_id();
        $slug = self::slugify($name);
        $existing = self::getTermBySlug($taxonomy, $slug, $tenantId);
        if ($existing) return (int)$existing['id'];
        return Database::insert('contentbuilder_terms', [
            'tenant_id' => $tenantId,
            'taxonomy'  => $taxonomy,
            'parent_id' => $parent ?: null,
            'name'      => mb_substr(trim($name), 0, 128),
            'slug'      => $slug,
        ]);
    }

    public static function deleteTerm(int $id, ?int $tenantId = null): void {
        $tenantId = $tenantId ?? current_tenant_id();
        Database::query("DELETE FROM contentbuilder_terms WHERE id = ? AND tenant_id = ?", [$id, $tenantId]);
        Database::query("DELETE FROM contentbuilder_term_relations WHERE term_id = ?", [$id]);
    }

    public static function setPostTerms(int $postId, array $termIds): void {
        Database::query("DELETE FROM contentbuilder_term_relations WHERE post_id = ?", [$postId]);
        foreach (array_unique(array_map('intval', $termIds)) as $tid) {
            if ($tid <= 0) continue;
            Database::query(
                "INSERT IGNORE INTO contentbuilder_term_relations (post_id, term_id) VALUES (?, ?)",
                [$postId, $tid]);
        }
    }

    public static function getPostTerms(int $postId, ?string $taxonomy = null): array {
        $sql = "SELECT t.* FROM contentbuilder_terms t
                JOIN contentbuilder_term_relations r ON r.term_id = t.id
                WHERE r.post_id = ?";
        $params = [$postId];
        if ($taxonomy !== null) { $sql .= " AND t.taxonomy = ?"; $params[] = $taxonomy; }
        return Database::rows($sql, $params);
    }

    /* ─────────────────────────────── Rendering ───────────────────────── */

    public static function renderLayout($layout): string {
        if (is_string($layout)) $layout = json_decode($layout, true);
        return Renderer::render(is_array($layout) ? $layout : []);
    }

    /**
     * Clean public URL for a post: pages → /p/<slug>, others → /<type>/<slug>.
     * Pass $preview=true to append the draft-preview flag.
     */
    public static function publicUrl(string $type, string $slug, bool $preview = false): string {
        $base = defined('SLATE_URL') ? SLATE_URL : '';
        $prefix = ($type === 'page') ? 'p' : $type;
        $url = $base . '/' . rawurlencode($prefix) . '/' . rawurlencode($slug);
        return $preview ? $url . '?preview=1' : $url;
    }

    /* ─────────────────────────────── Helpers ─────────────────────────── */

    protected static function hydrate(array $row): array {
        $row['layout'] = $row['layout'] ? (json_decode($row['layout'], true) ?: []) : [];
        return $row;
    }

    public static function slugify(string $s): string {
        $s = strtolower(trim($s));
        $s = preg_replace('/[^a-z0-9]+/', '-', $s);
        return trim($s, '-');
    }

    protected static function uniqueSlug(string $type, string $slug, ?int $id, int $tenantId): string {
        $base = $slug; $i = 2;
        while (true) {
            $clash = Database::row(
                "SELECT id FROM contentbuilder_posts
                 WHERE tenant_id = ? AND type = ? AND slug = ? AND id <> ?",
                [$tenantId, $type, $slug, $id ?? 0]);
            if (!$clash) return $slug;
            $slug = $base . '-' . $i++;
        }
    }

    /* ─────────────────────────────── Permalinks ──────────────────────── */

    /**
     * Public URL for a post. Pages → /p/<slug>, other types → /<type>/<slug>.
     * Returns an absolute URL rooted at SLATE_URL.
     */
    public static function permalink(array $post): string {
        $type = $post['type'] ?? 'page';
        $slug = $post['slug'] ?? '';
        $prefix = ($type === 'page') ? 'p' : rawurlencode($type);
        return rtrim(SLATE_URL, '/') . '/' . $prefix . '/' . rawurlencode($slug);
    }

    /* ───────────────────────── Site settings (header/footer) ─────────── */
    /* Stored in the core settings table, prefixed 'content-builder.' so they */
    /* never collide. Used by the public theme for global chrome.            */

    public static function getSiteSetting(string $key, $default = null) {
        $val = Database::setting('content-builder.' . $key);
        return $val !== null ? $val : $default;
    }

    public static function setSiteSetting(string $key, $value): void {
        Database::setSetting('content-builder.' . $key, $value);
    }

    /* ──────────────────────────── Navigation menus ───────────────────── */
    /*                                                                       */
    /* A menu's `items` is an ordered array of:                              */
    /*   { "label": "...", "url": "/p/about", "type": "custom|page|post" }   */

    public static function getMenus(?int $tenantId = null): array {
        $tenantId = $tenantId ?? current_tenant_id();
        $rows = Database::rows(
            "SELECT * FROM contentbuilder_menus WHERE tenant_id = ? ORDER BY name ASC",
            [$tenantId]);
        return array_map([self::class, 'hydrateMenu'], $rows);
    }

    public static function getMenu(int $id, ?int $tenantId = null): ?array {
        $tenantId = $tenantId ?? current_tenant_id();
        $row = Database::row(
            "SELECT * FROM contentbuilder_menus WHERE id = ? AND tenant_id = ?",
            [$id, $tenantId]);
        return $row ? self::hydrateMenu($row) : null;
    }

    /** Menu assigned to a location ('header'|'footer'), or null. */
    public static function getMenuByLocation(string $location, ?int $tenantId = null): ?array {
        $tenantId = $tenantId ?? current_tenant_id();
        $row = Database::row(
            "SELECT * FROM contentbuilder_menus
             WHERE tenant_id = ? AND location = ? ORDER BY id ASC LIMIT 1",
            [$tenantId, $location]);
        return $row ? self::hydrateMenu($row) : null;
    }

    public static function saveMenu(array $data, ?int $tenantId = null): int {
        $tenantId = $tenantId ?? current_tenant_id();
        $id = (int)($data['id'] ?? 0) ?: null;
        $location = in_array($data['location'] ?? '', ['', 'header', 'footer'], true)
                    ? ($data['location'] ?? '') : '';

        // Enforce one menu per location: clear the location off any other menu.
        if ($location !== '') {
            Database::query(
                "UPDATE contentbuilder_menus SET location = '' WHERE tenant_id = ? AND location = ? AND id <> ?",
                [$tenantId, $location, $id ?? 0]);
        }

        $row = [
            'tenant_id' => $tenantId,
            'name'      => mb_substr(trim($data['name'] ?? 'Menu'), 0, 128),
            'location'  => $location,
            'items'     => json_encode(array_values($data['items'] ?? [])),
        ];
        if ($id) {
            Database::update('contentbuilder_menus', $row, 'id = ? AND tenant_id = ?', [$id, $tenantId]);
            return $id;
        }
        return Database::insert('contentbuilder_menus', $row);
    }

    public static function deleteMenu(int $id, ?int $tenantId = null): void {
        $tenantId = $tenantId ?? current_tenant_id();
        Database::query("DELETE FROM contentbuilder_menus WHERE id = ? AND tenant_id = ?", [$id, $tenantId]);
    }

    protected static function hydrateMenu(array $row): array {
        $row['items'] = $row['items'] ? (json_decode($row['items'], true) ?: []) : [];
        return $row;
    }

    /* ──────────────────────────── Page templates ─────────────────────── */
    /*                                                                       */
    /* Premade block layouts a user can start a page from. Pure data — the   */
    /* editor copies the blocks into a new post.                             */

    public static function templates(): array {
        return [
            'blank' => [
                'label'  => 'Blank',
                'blocks' => [],
            ],
            'landing' => [
                'label'  => 'Landing page',
                'blocks' => [
                    ['type'=>'hero','props'=>['layout'=>'split','mediaSide'=>'left','eyebrow'=>'Welcome',
                        'heading'=>'Your big headline','subheading'=>'A short supporting sentence that sells the idea.',
                        'btnText'=>'Get started','btnHref'=>'#','btn2Text'=>'Learn more','btn2Href'=>'#',
                        'image'=>'','overlay'=>'medium','height'=>'normal']],
                    ['type'=>'icon-grid','props'=>['eyebrow'=>'Why us','heading'=>'Why choose us','bg'=>'white','cols'=>'3','items'=>[
                        ['icon'=>'bolt','title'=>'Fast','text'=>'Describe benefit one.','linkText'=>'','linkHref'=>''],
                        ['icon'=>'shield','title'=>'Reliable','text'=>'Describe benefit two.','linkText'=>'','linkHref'=>''],
                        ['icon'=>'heart','title'=>'Loved','text'=>'Describe benefit three.','linkText'=>'','linkHref'=>''],
                    ]]],
                    ['type'=>'testimonial','props'=>['quote'=>'This product changed how we work.','author'=>'Jane Doe','role'=>'CEO, Example Co','avatar'=>'']],
                    ['type'=>'cta','props'=>['eyebrow'=>'','heading'=>'Ready to start?','text'=>'Join us today.','btnText'=>'Sign up','btnHref'=>'#']],
                ],
            ],
            'about' => [
                'label'  => 'About',
                'blocks' => [
                    ['type'=>'hero','props'=>['layout'=>'split','mediaSide'=>'right','eyebrow'=>'About us',
                        'heading'=>'Who we are','subheading'=>'A short line about what drives you.',
                        'btnText'=>'','btnHref'=>'','btn2Text'=>'','btn2Href'=>'','image'=>'','height'=>'normal']],
                    ['type'=>'icon-grid','props'=>['eyebrow'=>'Our values','heading'=>'What we stand for','bg'=>'tint','cols'=>'3','items'=>[
                        ['icon'=>'check','title'=>'Integrity','text'=>'Describe this value.','linkText'=>'','linkHref'=>''],
                        ['icon'=>'star','title'=>'Quality','text'=>'Describe this value.','linkText'=>'','linkHref'=>''],
                        ['icon'=>'clock','title'=>'Commitment','text'=>'Describe this value.','linkText'=>'','linkHref'=>''],
                    ]]],
                ],
            ],
            'services' => [
                'label'  => 'Services',
                'blocks' => [
                    ['type'=>'hero','props'=>['layout'=>'banner','eyebrow'=>'Services',
                        'heading'=>'What we offer','subheading'=>'Everything we can do for you.',
                        'btnText'=>'Get a quote','btnHref'=>'/p/contact','btn2Text'=>'','btn2Href'=>'',
                        'image'=>'','overlay'=>'medium','height'=>'normal']],
                    ['type'=>'image-grid','props'=>['eyebrow'=>'','heading'=>'Our services','bg'=>'tint','cols'=>'3','items'=>[
                        ['image'=>'','title'=>'Service one','text'=>'Short description.','href'=>''],
                        ['image'=>'','title'=>'Service two','text'=>'Short description.','href'=>''],
                        ['image'=>'','title'=>'Service three','text'=>'Short description.','href'=>''],
                    ]]],
                    ['type'=>'cta','props'=>['eyebrow'=>'','heading'=>'Want to know more?','text'=>'Get in touch and we will help.','btnText'=>'Contact us','btnHref'=>'/p/contact']],
                ],
            ],
            'contact' => [
                'label'  => 'Contact',
                'blocks' => [
                    ['type'=>'hero','props'=>['layout'=>'banner','eyebrow'=>'Contact',
                        'heading'=>'Get in touch','subheading'=>'We would love to hear from you.',
                        'btnText'=>'','btnHref'=>'','btn2Text'=>'','btn2Href'=>'','image'=>'','overlay'=>'medium','height'=>'short']],
                    ['type'=>'icon-grid','props'=>['eyebrow'=>'','heading'=>'How to reach us','bg'=>'white','cols'=>'3','items'=>[
                        ['icon'=>'heart','title'=>'Email','text'=>'hello@example.com','linkText'=>'','linkHref'=>''],
                        ['icon'=>'clock','title'=>'Hours','text'=>'Mon–Fri, 9am–6pm','linkText'=>'','linkHref'=>''],
                        ['icon'=>'shield','title'=>'Phone','text'=>'(555) 123-4567','linkText'=>'','linkHref'=>''],
                    ]]],
                ],
            ],
        ];
    }

    public static function template(string $key): ?array {
        return self::templates()[$key] ?? null;
    }
}
