<?php
/**
 * Yoast SEO migration adapter.
 *
 * Yoast stores per-post meta in `_yoast_wpseo_*` postmeta keys and redirects
 * either in the dedicated `wpseo_redirect` storage or the option
 * `wpseo-premium-redirects-export-plain` (Premium).
 *
 * @package Brainwerk SEO Suite
 */

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

class Seoforge_Migrate_Yoast {

    public static function source_label() {
        return 'Yoast SEO';
    }

    public static function is_available() {
        return defined( 'WPSEO_VERSION' ) || self::has_postmeta_table_marker();
    }

    private static function has_postmeta_table_marker() {
        global $wpdb;
        return (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_yoast_wpseo_title' LIMIT 1" ) > 0;
    }

    public static function count_posts() {
        global $wpdb;
        return (int) $wpdb->get_var( "SELECT COUNT(DISTINCT post_id) FROM {$wpdb->postmeta} WHERE meta_key LIKE '_yoast_wpseo_%'" );
    }

    public static function count_redirects() {
        return count( self::list_redirects() );
    }

    public static function map_post_meta( $post_id ) {
        $get = function ( $k ) use ( $post_id ) {
            return get_post_meta( (int) $post_id, '_yoast_wpseo_' . $k, true );
        };
        $title    = $get( 'title' );
        $desc     = $get( 'metadesc' );
        $focus    = $get( 'focuskw' );
        $og_t     = $get( 'opengraph-title' );
        $og_d     = $get( 'opengraph-description' );
        $og_img   = $get( 'opengraph-image' );
        // twitter-title/twitter-description have no matching Seoforge_Meta field
        // (Twitter card output always falls back to the OG title/description —
        // see class-seoforge-meta.php) so they're not fetched here; twitter-image
        // still feeds the og_image fallback below.
        $tw_img   = $get( 'twitter-image' );
        $canonical = $get( 'canonical' );
        $noindex  = $get( 'meta-robots-noindex' );
        $nofollow = $get( 'meta-robots-nofollow' );

        $row = array();
        if ( $title )    { $row['seo_title']        = self::expand_yoast_vars( $title ); }
        if ( $desc )     { $row['seo_description']  = self::expand_yoast_vars( $desc ); }
        if ( $focus )    { $row['focus_keyword']    = $focus; }
        if ( $og_t )     { $row['og_title']         = self::expand_yoast_vars( $og_t ); }
        if ( $og_d )     { $row['og_description']   = self::expand_yoast_vars( $og_d ); }
        if ( $og_img )   { $row['og_image']         = $og_img; }
        if ( ! $og_img && $tw_img ) { $row['og_image'] = $tw_img; }
        if ( $canonical ){ $row['canonical']        = $canonical; }
        // Yoast stores 1 = noindex, 2 = index. We only act on 1.
        if ( '1' === (string) $noindex )  { $row['robots_noindex']  = 1; }
        if ( '1' === (string) $nofollow ) { $row['robots_nofollow'] = 1; }
        return $row;
    }

    /**
     * Expand the most common Yoast template tags. Anything we don't know is
     * left as-is — better than silently dropping the tag.
     */
    public static function expand_yoast_vars( $tpl ) {
        $tpl = (string) $tpl;
        $repl = array(
            '%%sitename%%'    => wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ),
            '%%sitedesc%%'    => wp_specialchars_decode( get_bloginfo( 'description' ), ENT_QUOTES ),
            '%%sep%%'         => '–',
            '%%page%%'        => '',
            '%%pagetotal%%'   => '',
            '%%pagenumber%%'  => '',
            '%%currentdate%%' => date_i18n( get_option( 'date_format' ) ),
            '%%currentyear%%' => date_i18n( 'Y' ),
        );
        return strtr( $tpl, $repl );
    }

    public static function list_redirects() {
        $out = array();
        // Yoast Premium plain export
        $plain = get_option( 'wpseo-premium-redirects-export-plain', array() );
        if ( is_array( $plain ) ) {
            foreach ( $plain as $row ) {
                if ( empty( $row['origin'] ) || empty( $row['url'] ) ) { continue; }
                $type = isset( $row['type'] ) ? (int) $row['type'] : 301;
                $out[] = array(
                    'source_path' => '/' . ltrim( (string) $row['origin'], '/' ),
                    'target_url'  => (string) $row['url'],
                    'status_code' => in_array( $type, array( 301, 302, 307, 308 ), true ) ? $type : 301,
                    'match_type'  => 'exact',
                    'note'        => 'imported from Yoast',
                );
            }
        }
        return $out;
    }
}
