<?php
declare(strict_types=1);

namespace KbMarkdownImporter\Repository;

use KbMarkdownImporter\Import\ImportLogger;

final class PageRepository
{
    public function findBySource(string $projectId, string $branch, string $sourcePath): int
    {
        $query = new \WP_Query([
            'post_type' => 'kb_doc_page',
            'post_status' => ['publish', 'draft', 'private'],
            'posts_per_page' => 1,
            'fields' => 'ids',
            'no_found_rows' => true,
            'meta_query' => [
                'relation' => 'AND',
                [
                    'key' => '_kb_gitlab_project_id',
                    'value' => $projectId,
                ],
                [
                    'key' => '_kb_gitlab_branch',
                    'value' => $branch,
                ],
                [
                    'key' => '_kb_markdown_source_path',
                    'value' => $sourcePath,
                ],
            ],
        ]);

        return (int) ($query->posts[0] ?? 0);
    }

    public function save(array $data, bool $dryRun = false): int
    {
        $existingId = $this->findBySource($data['project_id'], $data['branch'], $data['source_path']);

        if ($existingId) {
            $oldChecksum = (string) get_post_meta($existingId, '_kb_page_checksum', true);
            $oldRendererVersion = (string) get_post_meta($existingId, '_kb_renderer_version', true);
            if ($oldChecksum === $data['checksum'] && $oldRendererVersion === $data['renderer_version']) {
                ImportLogger::info('Page unchanged: ' . $data['source_path']);
                return $existingId;
            }
        }

        if ($dryRun) {
            ImportLogger::info(($existingId ? 'Would update page: ' : 'Would import page: ') . $data['source_path']);
            return $existingId;
        }

        $postData = [
            'post_type' => 'kb_doc_page',
            'post_status' => 'publish',
            'post_title' => $data['title'],
            'post_name' => $data['page_slug'] ?: 'index',
            'post_content' => $data['html'],
            'post_excerpt' => wp_trim_words(wp_strip_all_tags($data['html']), 35),
        ];

        if ($existingId) {
            $postData['ID'] = $existingId;
            $postId = wp_update_post(wp_slash($postData), true);
        } else {
            $postId = wp_insert_post(wp_slash($postData), true);
        }

        if (is_wp_error($postId)) {
            ImportLogger::error('Failed to save page ' . $data['source_path'] . ': ' . $postId->get_error_message());
            return 0;
        }

        $meta = [
            '_kb_gitlab_project_id' => $data['project_id'],
            '_kb_gitlab_project_path' => $data['project_path'],
            '_kb_gitlab_branch' => $data['branch'],
            '_kb_gitlab_commit_sha' => $data['commit_sha'],
            '_kb_markdown_component' => $data['component'],
            '_kb_markdown_component_title' => $data['component_title'],
            '_kb_markdown_version' => $data['version'],
            '_kb_markdown_module' => $data['module'],
            '_kb_markdown_page_path' => $data['page_path'],
            '_kb_markdown_source_path' => $data['source_path'],
            '_kb_page_checksum' => $data['checksum'],
            '_kb_last_imported_at' => current_time('mysql'),
            '_kb_nav_order' => (string) $data['nav_order'],
            '_kb_parent_page_path' => $data['parent_page_path'],
            '_kb_product_slug' => $data['product_slug'],
            '_kb_version_slug' => sanitize_title($data['version']),
            '_kb_page_slug' => $data['page_slug'],
            '_kb_nav_tree' => wp_json_encode($data['nav_tree']),
            '_kb_renderer_version' => $data['renderer_version'],
        ];

        foreach ($meta as $key => $value) {
            update_post_meta((int) $postId, $key, $value);
        }

        wp_set_object_terms((int) $postId, [$data['product_term_id']], 'kb_product');
        wp_set_object_terms((int) $postId, [$data['version_term_id']], 'kb_version');
        wp_set_object_terms((int) $postId, [$data['component']], 'kb_component');

        ImportLogger::info(($existingId ? 'Page updated: ' : 'Page imported: ') . $data['source_path']);

        return (int) $postId;
    }

    public function findFrontendPage(string $productSlug, string $versionSlug, string $pageSlug): ?\WP_Post
    {
        $pageSlug = $pageSlug ?: '';
        $query = new \WP_Query([
            'post_type' => 'kb_doc_page',
            'post_status' => 'publish',
            'posts_per_page' => 1,
            'no_found_rows' => true,
            'meta_query' => [
                'relation' => 'AND',
                ['key' => '_kb_product_slug', 'value' => $productSlug],
                ['key' => '_kb_version_slug', 'value' => $versionSlug],
                ['key' => '_kb_page_slug', 'value' => $pageSlug],
            ],
        ]);

        return $query->have_posts() ? $query->posts[0] : null;
    }
}
