<?php
/**
 * Rank Writer Main Class
 * 
 * Handles API communication with Morningscore for articles
 * and WordPress post creation.
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Rank_Writer {
    
    /**
     * Initialize Rank Writer functionality
     */
    public static function init() {
        // Include sub-classes
        require_once RANK_PLUGIN_DIR . 'includes/rank-writer/class-rank-writer-db.php';
        require_once RANK_PLUGIN_DIR . 'includes/rank-writer/class-rank-writer-ajax.php';
        
        // Initialize AJAX handlers
        Rank_Writer_Ajax::init();
    }
    
    /**
     * Get articles list from Morningscore API
     * 
     * @param int $page Page number (1-based)
     * @param int $per_page Items per page
     * @return array|WP_Error Articles data or error
     */
    public static function get_articles( $page = 1, $per_page = 10 ) {
        $domain_identifier = rank_get_domain_identifier();
        if ( is_wp_error( $domain_identifier ) ) {
            return $domain_identifier;
        }
        
        $url = "https://api.morningscore.io/v1/{$domain_identifier}/articles";
        $query_args = array(
            'page' => $page,
            'per_page' => $per_page
        );
        
        $response = wp_remote_get(
            add_query_arg( $query_args, $url ),
            array(
                'headers' => array(
                    'Authorization' => 'Bearer ' . rank_get_api_key(),
                    'Accept' => 'application/json',
                ),
                'timeout' => 30,
                'user-agent' => 'Mozilla/5.0 (compatible; RANK AI/1.0; +https://morningscore.io)',
            )
        );
        
        if ( is_wp_error( $response ) ) {
            return $response;
        }
        
        $response_code = wp_remote_retrieve_response_code( $response );
        if ( $response_code !== 200 ) {
            return new WP_Error(
                'api_error',
                'Failed to retrieve articles. Status code: ' . $response_code
            );
        }
        
        $body = json_decode( wp_remote_retrieve_body( $response ), true );
        
        if ( ! is_array( $body ) ) {
            return new WP_Error( 'api_error', 'Invalid response format when fetching articles' );
        }
        
        return $body;
    }
    
    /**
     * Get single article with full content from Morningscore API
     * 
     * @param string $article_id Article ID
     * @return array|WP_Error Article data with content or error
     */
    public static function get_article( $article_id ) {
        $domain_identifier = rank_get_domain_identifier();
        if ( is_wp_error( $domain_identifier ) ) {
            return $domain_identifier;
        }
        
        $url = "https://api.morningscore.io/v1/{$domain_identifier}/articles/{$article_id}";
        
        $response = wp_remote_get(
            $url,
            array(
                'headers' => array(
                    'Authorization' => 'Bearer ' . rank_get_api_key(),
                    'Accept' => 'application/json',
                ),
                'timeout' => 30,
                'user-agent' => 'Mozilla/5.0 (compatible; RANK AI/1.0; +https://morningscore.io)',
            )
        );
        
        if ( is_wp_error( $response ) ) {
            return $response;
        }
        
        $response_code = wp_remote_retrieve_response_code( $response );
        if ( $response_code !== 200 ) {
            return new WP_Error(
                'api_error',
                'Failed to retrieve article. Status code: ' . $response_code
            );
        }
        
        $body = json_decode( wp_remote_retrieve_body( $response ), true );
        
        if ( ! is_array( $body ) || ! isset( $body['_id'] ) ) {
            return new WP_Error( 'api_error', 'Invalid response format when fetching article' );
        }
        
        return $body;
    }
    
    /**
     * Create WordPress draft post from Morningscore article
     * 
     * @param array $article_data Article data from API (must include _id, title, content)
     * @return int|WP_Error Post ID on success, WP_Error on failure
     */
    public static function create_wp_draft( $article_data ) {
        // Validate required fields
        if ( empty( $article_data['_id'] ) || empty( $article_data['title'] ) ) {
            return new WP_Error( 'invalid_data', 'Article ID and title are required' );
        }
        
        // Check if already uploaded
        if ( Rank_Writer_DB::is_article_uploaded( $article_data['_id'] ) ) {
            return new WP_Error( 'already_uploaded', 'This article has already been uploaded' );
        }
        
        // Process content - strip leading H tag if present (title is already used for post_title)
        $content = isset( $article_data['content'] ) ? $article_data['content'] : '';
        $content = self::strip_leading_heading( $content );
        
        // Generate slug from title, truncated to max 70 characters
        $slug = self::generate_truncated_slug( $article_data['title'], 70 );
        
        // Prepare post data
        $post_data = array(
            'post_title'   => sanitize_text_field( $article_data['title'] ),
            'post_name'    => $slug,
            'post_content' => wp_kses_post( $content ),
            'post_status'  => 'draft',
            'post_type'    => 'post',
            'post_author'  => get_current_user_id(),
        );
        
        // Insert the post
        $post_id = wp_insert_post( $post_data, true );
        
        if ( is_wp_error( $post_id ) ) {
            return $post_id;
        }
        
        // Record the upload in tracking table
        $recorded = Rank_Writer_DB::record_upload(
            $article_data['_id'],
            $post_id,
            $article_data['title']
        );
        
        if ( ! $recorded ) {
            // Post was created but tracking failed - log but don't fail
            error_log( 'Rank Writer: Failed to record upload for article ' . $article_data['_id'] );
        }
        
        // Save meta title + description to the active supported SEO plugin
        // (Yoast / Rank Math / SEOPress / SureRank / The SEO Framework / Slim SEO).
        $meta_title = ! empty( $article_data['metaTitle'] ) ? sanitize_text_field( $article_data['metaTitle'] ) : '';
        $meta_desc  = ! empty( $article_data['metaDescription'] ) ? sanitize_text_field( $article_data['metaDescription'] ) : '';
        if ( $meta_title !== '' || $meta_desc !== '' ) {
            Rank_Booster::write_seo_meta( $post_id, $meta_title, $meta_desc );
        }
        
        return $post_id;
    }
    
    /**
     * Get articles with upload status merged
     * 
     * @param int $page Page number
     * @param int $per_page Items per page
     * @return array|WP_Error Articles with is_uploaded flag or error
     */
    public static function get_articles_with_status( $page = 1, $per_page = 10 ) {
        // Get articles from API
        $result = self::get_articles( $page, $per_page );
        
        if ( is_wp_error( $result ) ) {
            return $result;
        }
        
        // Get list of already uploaded article IDs
        $uploaded_ids = Rank_Writer_DB::get_uploaded_article_ids();
        
        // Merge upload status into articles
        if ( isset( $result['data'] ) && is_array( $result['data'] ) ) {
            foreach ( $result['data'] as &$article ) {
                $article['is_uploaded'] = in_array( $article['_id'], $uploaded_ids, true );
            }
        }
        
        return $result;
    }
    
    /**
     * Strip leading H tag from content to avoid duplicate title
     *
     * Removes the first H1-H6 tag if it appears at the beginning of the content,
     * since WordPress uses the title field for the post title.
     *
     * @param string $content HTML content
     * @return string Content with leading heading removed
     */
    private static function strip_leading_heading( $content ) {
        if ( empty( $content ) ) {
            return $content;
        }
        
        // Trim whitespace from the beginning
        $content = ltrim( $content );
        
        // Pattern to match opening H1-H6 tag at the start of content
        // Matches: <h1>...</h1>, <h2>...</h2>, etc. including attributes
        $pattern = '/^<h[1-6][^>]*>.*?<\/h[1-6]>\s*/is';
        
        // Remove the leading heading if found
        $content = preg_replace( $pattern, '', $content, 1 );
        
        return $content;
    }
    
    /**
     * Generate a truncated slug from title
     *
     * Creates a URL-friendly slug from the title, truncated to max length
     * without cutting words in the middle.
     *
     * @param string $title The post title
     * @param int $max_length Maximum slug length (default 70)
     * @return string Sanitized and truncated slug
     */
    private static function generate_truncated_slug( $title, $max_length = 70 ) {
        if ( empty( $title ) ) {
            return '';
        }
        
        // Generate slug using WordPress sanitize_title
        $slug = sanitize_title( $title );
        
        // If already short enough, return as-is
        if ( strlen( $slug ) <= $max_length ) {
            return $slug;
        }
        
        // Truncate to max length
        $truncated = substr( $slug, 0, $max_length );
        
        // Try to cut at a word boundary (hyphen in slugs)
        $last_hyphen = strrpos( $truncated, '-' );
        if ( $last_hyphen !== false && $last_hyphen > $max_length / 2 ) {
            // Cut at the last hyphen if it's in the second half
            $truncated = substr( $truncated, 0, $last_hyphen );
        }
        
        // Remove trailing hyphens
        $truncated = rtrim( $truncated, '-' );
        
        return $truncated;
    }
}