<?php
namespace WooNooW\Api;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use WooNooW\Frontend\PlaceholderRenderer;
use WooNooW\Frontend\PageSSR;

/**
 * Pages Controller
 * REST API for page structures and CPT templates
 */
class PagesController
{
    /**
     * Register API routes
     */
    public static function register_routes()
    {
        $namespace = 'woonoow/v1';
        
        // List all pages and templates
        register_rest_route($namespace, '/pages', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'get_pages'],
            'permission_callback' => '__return_true',
        ]);
        
        // Get/Save page structure (structural pages)
        register_rest_route($namespace, '/pages/(?P<slug>[a-zA-Z0-9_-]+)', [
            [
                'methods' => 'GET',
                'callback' => [__CLASS__, 'get_page'],
                'permission_callback' => '__return_true',
            ],
            [
                'methods' => 'POST',
                'callback' => [__CLASS__, 'save_page'],
                'permission_callback' => [__CLASS__, 'check_admin_permission'],
            ],
        ]);
        
        // Get/Save CPT templates
        register_rest_route($namespace, '/templates/(?P<cpt>[a-zA-Z0-9_-]+)', [
            [
                'methods' => 'GET',
                'callback' => [__CLASS__, 'get_template'],
                'permission_callback' => '__return_true',
            ],
            [
                'methods' => 'POST',
                'callback' => [__CLASS__, 'save_template'],
                'permission_callback' => [__CLASS__, 'check_admin_permission'],
            ],
        ]);
        
        // Get post with template applied (for SPA rendering)
        register_rest_route($namespace, '/content/(?P<type>[a-zA-Z0-9_-]+)/(?P<slug>[a-zA-Z0-9_-]+)', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'get_content_with_template'],
            'permission_callback' => '__return_true',
        ]);
        
        // Create new page
        register_rest_route($namespace, '/pages', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'create_page'],
            'permission_callback' => [__CLASS__, 'check_admin_permission'],
        ]);
    }
    
    /**
     * Check admin permission
     */
    public static function check_admin_permission()
    {
        return current_user_can('manage_woocommerce');
    }
    
    /**
     * Get all pages and templates
     */
    public static function get_pages(WP_REST_Request $request)
    {
        $result = [];
        
        // Get structural pages (pages with WooNooW structure)
        $pages = get_posts([
            'post_type' => 'page',
            'posts_per_page' => -1,
            'meta_query' => [
                [
                    'key' => '_wn_page_structure',
                    'compare' => 'EXISTS',
                ],
            ],
        ]);
        
        foreach ($pages as $page) {
            $result[] = [
                'id' => $page->ID,
                'type' => 'page',
                'slug' => $page->post_name,
                'title' => $page->post_title,
                'url' => get_permalink($page),
                'icon' => 'page',
            ];
        }
        
        // Get CPT templates
        $cpts = self::get_editable_post_types();
        foreach ($cpts as $cpt => $label) {
            $template = get_option("wn_template_{$cpt}", null);
            
            $result[] = [
                'type' => 'template',
                'cpt' => $cpt,
                'title' => "{$label} Template",
                'icon' => 'template',
                'permalink_base' => self::get_cpt_permalink_base($cpt),
                'has_template' => !empty($template),
            ];
        }
        
        return new WP_REST_Response($result, 200);
    }
    
    /**
     * Get page structure by slug
     */
    public static function get_page(WP_REST_Request $request)
    {
        $slug = $request->get_param('slug');
        
        // Find page by slug
        $page = get_page_by_path($slug);
        if (!$page) {
            return new WP_Error('not_found', 'Page not found', ['status' => 404]);
        }
        
        $structure = get_post_meta($page->ID, '_wn_page_structure', true);
        
        // Get SEO data (Yoast/Rank Math)
        $seo = self::get_seo_data($page->ID);
        
        return new WP_REST_Response([
            'id' => $page->ID,
            'type' => 'page',
            'slug' => $page->post_name,
            'title' => $page->post_title,
            'url' => get_permalink($page),
            'seo' => $seo,
            'structure' => $structure ?: ['sections' => []],
        ], 200);
    }
    
    /**
     * Save page structure
     */
    public static function save_page(WP_REST_Request $request)
    {
        $slug = $request->get_param('slug');
        $body = $request->get_json_params();
        
        // Find page by slug
        $page = get_page_by_path($slug);
        if (!$page) {
            return new WP_Error('not_found', 'Page not found', ['status' => 404]);
        }
        
        // Validate structure
        $structure = $body['sections'] ?? null;
        if ($structure === null) {
            return new WP_Error('invalid_data', 'Missing sections data', ['status' => 400]);
        }
        
        // Save structure
        $save_data = [
            'type' => 'page',
            'sections' => $structure,
            'updated_at' => current_time('mysql'),
        ];
        
        update_post_meta($page->ID, '_wn_page_structure', $save_data);
        
        return new WP_REST_Response([
            'success' => true,
            'page' => [
                'id' => $page->ID,
                'slug' => $page->post_name,
            ],
        ], 200);
    }
    
    /**
     * Get CPT template
     */
    public static function get_template(WP_REST_Request $request)
    {
        $cpt = $request->get_param('cpt');
        
        // Validate CPT exists
        if (!post_type_exists($cpt) && $cpt !== 'post') {
            return new WP_Error('invalid_cpt', 'Invalid post type', ['status' => 400]);
        }
        
        $template = get_option("wn_template_{$cpt}", null);
        $cpt_obj = get_post_type_object($cpt);
        
        return new WP_REST_Response([
            'type' => 'template',
            'cpt' => $cpt,
            'title' => $cpt_obj ? $cpt_obj->labels->singular_name . ' Template' : ucfirst($cpt) . ' Template',
            'permalink_base' => self::get_cpt_permalink_base($cpt),
            'available_sources' => self::get_available_sources($cpt),
            'structure' => $template ?: ['sections' => []],
        ], 200);
    }
    
    /**
     * Save CPT template
     */
    public static function save_template(WP_REST_Request $request)
    {
        $cpt = $request->get_param('cpt');
        $body = $request->get_json_params();
        
        // Validate CPT exists
        if (!post_type_exists($cpt) && $cpt !== 'post') {
            return new WP_Error('invalid_cpt', 'Invalid post type', ['status' => 400]);
        }
        
        // Validate structure
        $structure = $body['sections'] ?? null;
        if ($structure === null) {
            return new WP_Error('invalid_data', 'Missing sections data', ['status' => 400]);
        }
        
        // Save template
        $save_data = [
            'type' => 'template',
            'cpt' => $cpt,
            'sections' => $structure,
            'updated_at' => current_time('mysql'),
        ];
        
        update_option("wn_template_{$cpt}", $save_data);
        
        return new WP_REST_Response([
            'success' => true,
            'template' => [
                'cpt' => $cpt,
            ],
        ], 200);
    }
    
    /**
     * Get content with template applied (for SPA rendering)
     */
    public static function get_content_with_template(WP_REST_Request $request)
    {
        $type = $request->get_param('type');
        $slug = $request->get_param('slug');
        
        // Handle structural pages
        if ($type === 'page') {
            return self::get_page($request);
        }
        
        // For CPT items, get post and apply template
        $post = get_page_by_path($slug, OBJECT, $type);
        if (!$post) {
            // Try with post type 'post' if type is 'blog'
            if ($type === 'blog') {
                $post = get_page_by_path($slug, OBJECT, 'post');
                $type = 'post';
            }
        }
        
        if (!$post) {
            return new WP_Error('not_found', 'Content not found', ['status' => 404]);
        }
        
        // Get template for this CPT
        $template = get_option("wn_template_{$type}", null);
        
        // Build post data
        $post_data = PlaceholderRenderer::build_post_data($post);
        
        // Get SEO data
        $seo = self::get_seo_data($post->ID);
        
        // If template exists, resolve placeholders
        $rendered_sections = [];
        if ($template && !empty($template['sections'])) {
            foreach ($template['sections'] as $section) {
                $resolved_section = $section;
                $resolved_section['props'] = PageSSR::resolve_props($section['props'] ?? [], $post_data);
                $rendered_sections[] = $resolved_section;
            }
        }
        
        return new WP_REST_Response([
            'type' => 'content',
            'cpt' => $type,
            'post' => $post_data,
            'seo' => $seo,
            'template' => $template ?: ['sections' => []],
            'rendered' => [
                'sections' => $rendered_sections,
            ],
        ], 200);
    }
    
    /**
     * Create new page
     */
    public static function create_page(WP_REST_Request $request)
    {
        $body = $request->get_json_params();
        
        $title = sanitize_text_field($body['title'] ?? '');
        $slug = sanitize_title($body['slug'] ?? $title);
        
        if (empty($title)) {
            return new WP_Error('invalid_data', 'Title is required', ['status' => 400]);
        }
        
        // Check if page already exists
        if (get_page_by_path($slug)) {
            return new WP_Error('exists', 'Page with this slug already exists', ['status' => 400]);
        }
        
        // Create page
        $page_id = wp_insert_post([
            'post_type' => 'page',
            'post_title' => $title,
            'post_name' => $slug,
            'post_status' => 'publish',
        ]);
        
        if (is_wp_error($page_id)) {
            return $page_id;
        }
        
        // Initialize empty structure
        $structure = [
            'type' => 'page',
            'sections' => [],
            'created_at' => current_time('mysql'),
        ];
        
        update_post_meta($page_id, '_wn_page_structure', $structure);
        
        return new WP_REST_Response([
            'success' => true,
            'page' => [
                'id' => $page_id,
                'slug' => $slug,
                'title' => $title,
                'url' => get_permalink($page_id),
            ],
        ], 201);
    }
    
    // ========================================
    // Helper Methods
    // ========================================
    
    /**
     * Get editable post types for templates
     */
    private static function get_editable_post_types()
    {
        $types = [
            'post' => 'Blog Post',
        ];
        
        // Get public custom post types
        $custom_types = get_post_types([
            'public' => true,
            '_builtin' => false,
        ], 'objects');
        
        foreach ($custom_types as $type) {
            // Skip WooCommerce types (handled separately)
            if (in_array($type->name, ['product', 'shop_order', 'shop_coupon'])) {
                continue;
            }
            $types[$type->name] = $type->labels->singular_name;
        }
        
        return $types;
    }
    
    /**
     * Get permalink base for a CPT
     */
    private static function get_cpt_permalink_base($cpt)
    {
        if ($cpt === 'post') {
            // Get blog permalink structure
            $struct = get_option('permalink_structure');
            if (strpos($struct, '%postname%') !== false) {
                return '/blog/';
            }
            return '/';
        }
        
        $obj = get_post_type_object($cpt);
        if ($obj && isset($obj->rewrite['slug'])) {
            return '/' . $obj->rewrite['slug'] . '/';
        }
        
        return '/' . $cpt . '/';
    }
    
    /**
     * Get available dynamic sources for a CPT
     */
    private static function get_available_sources($cpt)
    {
        $sources = [
            ['value' => 'post_title', 'label' => 'Title'],
            ['value' => 'post_content', 'label' => 'Content'],
            ['value' => 'post_excerpt', 'label' => 'Excerpt'],
            ['value' => 'post_featured_image', 'label' => 'Featured Image'],
            ['value' => 'post_author', 'label' => 'Author'],
            ['value' => 'post_date', 'label' => 'Date'],
            ['value' => 'post_url', 'label' => 'Permalink'],
        ];
        
        // Add taxonomy sources
        $taxonomies = get_object_taxonomies($cpt, 'objects');
        foreach ($taxonomies as $tax) {
            if ($tax->public) {
                $sources[] = [
                    'value' => $tax->name,
                    'label' => $tax->labels->name,
                ];
            }
        }
        
        // Add related posts source
        $sources[] = ['value' => 'related_posts', 'label' => 'Related Posts'];
        
        return $sources;
    }
    
    /**
     * Get SEO data for a post (Yoast/Rank Math compatible)
     */
    private static function get_seo_data($post_id)
    {
        $seo = [];
        
        // Try Yoast
        $seo['meta_title'] = get_post_meta($post_id, '_yoast_wpseo_title', true) ?: get_the_title($post_id);
        $seo['meta_description'] = get_post_meta($post_id, '_yoast_wpseo_metadesc', true);
        $seo['canonical'] = get_post_meta($post_id, '_yoast_wpseo_canonical', true) ?: get_permalink($post_id);
        $seo['og_title'] = get_post_meta($post_id, '_yoast_wpseo_opengraph-title', true);
        $seo['og_description'] = get_post_meta($post_id, '_yoast_wpseo_opengraph-description', true);
        $seo['og_image'] = get_post_meta($post_id, '_yoast_wpseo_opengraph-image', true);
        
        // Try Rank Math if Yoast not available
        if (empty($seo['meta_description'])) {
            $seo['meta_description'] = get_post_meta($post_id, 'rank_math_description', true);
        }
        
        return $seo;
    }
}
