<?php
/**
 * LinkCentral Pretty Links Import Handler
 *
 * This trait handles Pretty Links database import functionality for LinkCentral links.
 * It can be used by any class that needs to import links from Pretty Links database.
 */

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

/**
 * Utility class for Pretty Links plugin detection and configuration
 */
class LinkCentral_PrettyLinks_Utils {

    /**
     * Import configuration constants
     */
    const DEFAULT_BATCH_SIZE = 50;
    const STATS_BATCH_SIZE = 1000;
    const MAX_LINKS_PER_IMPORT = 1000;
    const MAX_CLICKS_PER_LINK = 50000;

    /**
     * Check if Pretty Links plugin is active
     *
     * @return bool True if Pretty Links is active
     */
    private static function is_plugin_active() {
        return function_exists('is_plugin_active') && (
            is_plugin_active('pretty-link/pretty-link.php') || 
            is_plugin_active('pretty-links/pretty-links.php')
        );
    }
    
    /**
     * Check if Pretty Links is available (active and has data)
     *
     * @return bool True if Pretty Links is active and has data
     */
    public static function is_available() {
        // Check if Pretty Links plugin is active first (cheapest check)
        if (!self::is_plugin_active()) {
            return false;
        }
        
        // Quick check if any Pretty Links exist
        global $wpdb;
        $table_name = $wpdb->prefix . 'prli_links';
        
        // Check if table exists
        if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name)) !== $table_name) {
            return false;
        }
        
        $count = $wpdb->get_var("SELECT COUNT(*) FROM {$table_name} WHERE link_status = 'enabled'");
        return $count > 0;
    }

    /**
     * Get Pretty Links statistics
     *
     * @return array Statistics about Pretty Links data
     */
    public static function get_stats() {
        // Check if Pretty Links plugin is active first
        if (!self::is_plugin_active()) {
            return array('links' => 0, 'categories' => 0, 'stats' => 0);
        }

        global $wpdb;
        $links_table = $wpdb->prefix . 'prli_links';
        $clicks_table = $wpdb->prefix . 'prli_clicks';

        // Check if tables exist
        if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $links_table)) !== $links_table) {
            return array('links' => 0, 'categories' => 0, 'stats' => 0);
        }

        // Get link count (only enabled links)
        $links_count = $wpdb->get_var("SELECT COUNT(*) FROM {$links_table} WHERE link_status = 'enabled'");

        // If no Pretty Links data exists, return zeros
        if ($links_count === 0) {
            return array('links' => 0, 'categories' => 0, 'stats' => 0);
        }

        // Count categories (Pretty Links uses custom taxonomy)
        $categories_count = $wpdb->get_var("
            SELECT COUNT(DISTINCT t.term_id)
            FROM {$wpdb->prefix}terms t
            INNER JOIN {$wpdb->prefix}term_taxonomy tt ON t.term_id = tt.term_id
            WHERE tt.taxonomy = 'pretty-link-category'
        ");

        // Count stats (check if Pretty Links Pro clicks table exists)
        $stats_count = 0;
        if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $clicks_table)) === $clicks_table) {
            $stats_count = $wpdb->get_var("SELECT COUNT(*) FROM {$clicks_table}");
        }

        return array(
            'links' => (int) $links_count,
            'categories' => (int) $categories_count,
            'stats' => (int) $stats_count
        );
    }
}

class LinkCentral_PrettyLinks_Importer {

    /**
     * Check if Pretty Links plugin is installed
     *
     * @return bool True if Pretty Links is installed
     */
    public function is_available() {
        return LinkCentral_PrettyLinks_Utils::is_available();
    }

    /**
     * Get Pretty Links statistics
     *
     * @return array Statistics about Pretty Links data
     */
    public function get_stats() {
        return LinkCentral_PrettyLinks_Utils::get_stats();
    }

    /**
     * Process Pretty Links import
     *
     * @param array $import_options Import options
     * @return array|WP_Error Import results or error
     */
    public function process_import($import_options = array()) {
        global $wpdb;

        if (!$this->is_available()) {
            return new WP_Error('no_data', __('No Pretty Links data found.', 'linkcentral'));
        }

        $defaults = array(
            'import_categories' => false,
            'import_stats' => false,
            'duplicate_handling' => 'skip',
            'batch_size' => LinkCentral_PrettyLinks_Utils::DEFAULT_BATCH_SIZE,
            'offset' => 0
        );

        $import_options = wp_parse_args($import_options, $defaults);

        // Map Pretty Links-specific options to generic import options
        $import_options['create_categories'] = $import_options['import_categories'];

        $results = array(
            'success' => 0,
            'skipped' => 0,
            'errors' => 0,
            'categories_imported' => 0,
            'stats_imported' => 0,
            'error_details' => array()
        );

        // Import categories first if requested
        if ($import_options['import_categories']) {
            $category_result = $this->import_categories();
            $results['categories_imported'] = $category_result;
        }

        // Import links in batches
        $batch_size = $import_options['batch_size'];
        $offset = $import_options['offset'];
        $processed = 0;

        while (true) {
            $links = $this->get_links($batch_size, $offset);

            if (empty($links)) {
                break; // No more links to process
            }

            foreach ($links as $pl_link) {
                $link_result = $this->import_single_link($pl_link, $import_options);

                if (is_wp_error($link_result)) {
                    $results['errors']++;
                    $results['error_details'][] = array(
                        'link' => $pl_link['name'],
                        'error' => $link_result->get_error_message()
                    );
                } elseif ($link_result['action'] === 'skipped') {
                    $results['skipped']++;
                } else {
                    $results['success']++;

                    // Import stats if requested
                    if ($import_options['import_stats'] && isset($link_result['link_id'])) {
                        $stats_imported = $this->import_stats($pl_link['id'], $link_result['link_id']);
                        $results['stats_imported'] += $stats_imported;
                    }
                }

                $processed++;
            }

            $offset += count($links);

            // Optional: Add progress tracking
            $results['processed'] = $processed;
            $results['current_offset'] = $offset;

            // Prevent infinite loops and timeouts
            if ($processed >= LinkCentral_PrettyLinks_Utils::MAX_LINKS_PER_IMPORT) {
                $results['batch_complete'] = false;
                $results['resume_offset'] = $offset;
                break;
            }
        }

        $results['batch_complete'] = true;
        return $results;
    }

    /**
     * Get Pretty Links from database
     *
     * @param int $batch_size Number of links to retrieve
     * @param int $offset Offset for pagination
     * @return array Array of Pretty Links
     */
    private function get_links($batch_size = null, $offset = 0) {
        global $wpdb;
        $links_table = $wpdb->prefix . 'prli_links';

        $limit_clause = $batch_size ? $wpdb->prepare(" LIMIT %d OFFSET %d", $batch_size, $offset) : '';

        $links = $wpdb->get_results("
            SELECT
                id,
                name,
                url as destination_url,
                slug,
                description,
                redirect_type,
                param_forwarding,
                param_struct,
                track_me,
                nofollow,
                sponsored,
                link_cpt_id,
                created_at
            FROM {$links_table}
            WHERE link_status = 'enabled'
            ORDER BY created_at ASC
            {$limit_clause}
        ", ARRAY_A);

        // Get categories for each link
        foreach ($links as &$link) {
            $categories = array();

            // Get categories from WordPress taxonomy system (modern Pretty Links)
            if (!empty($link['link_cpt_id'])) {
                $taxonomy_categories = wp_get_post_terms($link['link_cpt_id'], 'pretty-link-category', array('fields' => 'all'));
                if (!is_wp_error($taxonomy_categories) && is_array($taxonomy_categories)) {
                    $categories = $taxonomy_categories;
                }
            }

            // Build hierarchical paths
            $hierarchical_paths = is_array($categories) ? $this->build_category_hierarchy($categories) : array();
            
            $link['categories'] = $hierarchical_paths;
        }

        return $links;
    }

    /**
     * Build hierarchical category paths from Pretty Links categories
     *
     * @param array $categories Array of WP_Term objects
     * @return array Array of hierarchical category paths like "Parent > Child"
     */
    private function build_category_hierarchy($categories) {
        $hierarchical_paths = array();

        foreach ($categories as $category) {
            $hierarchical_paths[] = $this->build_category_path($category);
        }

        return $hierarchical_paths;
    }

    /**
     * Build a hierarchical path from a category term
     *
     * @param WP_Term $category The category term
     * @return string Hierarchical path like "Parent > Child"
     */
    private function build_category_path($category) {
        $path_parts = array();
        $current_term = $category;

        // Walk up the hierarchy to build the full path
        while ($current_term) {
            array_unshift($path_parts, $current_term->name);
            if ($current_term->parent > 0) {
                $current_term = get_term($current_term->parent, 'pretty-link-category');
                if (is_wp_error($current_term) || !$current_term) {
                    break;
                }
            } else {
                break;
            }
        }

        return implode(' > ', $path_parts);
    }

    /**
     * Import Pretty Links categories
     *
     * @return int Number of categories imported
     */
    private function import_categories() {
        $pl_categories = get_terms(array(
            'taxonomy' => 'pretty-link-category',
            'hide_empty' => false,
        ));

        if (is_wp_error($pl_categories)) {
            return 0;
        }

        $imported_count = 0;

        // Sort categories by hierarchy (parents first)
        usort($pl_categories, function($a, $b) {
            return $a->parent - $b->parent;
        });

        foreach ($pl_categories as $pl_category) {
            // Build hierarchical path for this category
            $category_path = $this->get_category_hierarchical_path($pl_category);

            // Use the import utilities to handle hierarchical category creation
            $term_id = LinkCentral_Import_Shared::get_or_create_category($category_path, true);

            if ($term_id) {
                $imported_count++;
            }
        }

        return $imported_count;
    }

    /**
     * Get the hierarchical path for a Pretty Links category
     *
     * @param WP_Term $category The category term
     * @return string Hierarchical path like "Parent > Child"
     */
    private function get_category_hierarchical_path($category) {
        return $this->build_category_path($category);
    }

    /**
     * Import a single Pretty Links link
     *
     * @param array $pl_link Pretty Links link data
     * @param array $import_options Import options
     * @return array|WP_Error Import result or error
     */
    private function import_single_link($pl_link, $import_options) {
        // Process slug and prefix first to determine the final slug
        // This fixes duplicate detection when Pretty Links slug matches LinkCentral prefix
        // e.g., Pretty Links "go/abcd" with LinkCentral prefix "go" should find existing "abcd"
        $current_prefix = get_option('linkcentral_url_prefix', 'go');
        $force_prefix = $import_options['force_prefix'] ?? false;
        $slug_info = LinkCentral_Import_Shared::process_slug($pl_link['slug'], $current_prefix, false);
        
        // Check for existing link by the processed slug (what the final slug will be)
        $existing_link = LinkCentral_Import_Shared::find_existing_link($slug_info['slug']);
        
        if ($existing_link && $import_options['duplicate_handling'] === 'skip') {
            return array('action' => 'skipped');
        }
        
        // Prepare link data
        $category_data = $import_options['import_categories'] ? $pl_link['categories'] : array();

        $link_data = array(
            'title' => $pl_link['name'],
            'destination_url' => $pl_link['destination_url'],
            'slug' => $slug_info['slug'],
            'disable_slug_prefix' => $slug_info['disable_slug_prefix'],
            'category' => $category_data,
            'nofollow' => $this->convert_pl_nofollow($pl_link['nofollow']),
            'sponsored' => $this->convert_pl_sponsored($pl_link['sponsored']),
            'parameter_forwarding' => $this->convert_pl_parameter_forwarding($pl_link['param_forwarding']),
            'redirect_type' => $this->convert_pl_redirect_type($pl_link['redirect_type']),
            'note' => $pl_link['description'],
            'keywords' => ''
        );

        
        // Validate required fields
        $validation_result = LinkCentral_Import_Shared::validate_link_data($link_data);
        if (is_wp_error($validation_result)) {
            return $validation_result;
        }
        
        // Create or update the link
        $link_result = LinkCentral_Import_Shared::create_or_update_link($link_data, $existing_link, $import_options);
        
        if (is_wp_error($link_result)) {
            return $link_result;
        }
        
        return array(
            'action' => $existing_link ? 'updated' : 'created',
            'link_id' => $link_result
        );
    }

    /**
     * Import Pretty Links stats for a link
     *
     * @param int $pl_link_id Pretty Links link ID
     * @param int $lc_link_id LinkCentral link ID
     * @return int Number of stats imported
     */
    private function import_stats($pl_link_id, $lc_link_id) {
        global $wpdb;

        $clicks_table = $wpdb->prefix . 'prli_clicks';

        // Check if stats table exists
        if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $clicks_table)) != $clicks_table) {
            return 0;
        }

        // Get stats for this link (batched for performance)
        $batch_size = LinkCentral_PrettyLinks_Utils::STATS_BATCH_SIZE;
        $offset = 0;
        $total_imported = 0;

        while (true) {
            $clicks = $wpdb->get_results($wpdb->prepare("
                SELECT
                    id,
                    link_id,
                    created_at as click_date,
                    referer as referring_url,
                    browser,
                    host,
                    uri,
                    vuid as visitor_id,
                    first_click
                FROM {$clicks_table}
                WHERE link_id = %d
                ORDER BY created_at ASC
                LIMIT %d OFFSET %d
            ", $pl_link_id, $batch_size, $offset), ARRAY_A);

            if (empty($clicks)) {
                break; // No more stats for this link
            }

            // Convert clicks to LinkCentral format
            $stats = array();
            foreach ($clicks as $click) {
                $stats[] = array(
                    'click_date' => $click['click_date'],
                    'referring_url' => $click['referring_url'] ?? '',
                    'user_agent' => $click['browser'] ?? '',
                    'destination_url' => '', // Pretty Links doesn't store destination URL in clicks
                    'visitor_id' => $click['visitor_id'] ?? '', // Map Pretty Links vuid to visitor_id
                    'first_click' => (int)($click['first_click'] ?? 0), // Copy first_click directly
                );
            }

            $batch_imported = $this->import_stats_batch($stats, $lc_link_id);
            $total_imported += $batch_imported;
            $offset += $batch_size;

            // Safety check to prevent infinite loops
            if ($offset > LinkCentral_PrettyLinks_Utils::MAX_CLICKS_PER_LINK) {
                break;
            }
        }

        return $total_imported;
    }

    /**
     * Import a batch of stats for a link
     *
     * @param array $stats Array of stat data
     * @param int $lc_link_id LinkCentral link ID
     * @return int Number of stats imported in this batch
     */
    private function import_stats_batch($stats, $lc_link_id) {
        global $wpdb;

        if (empty($stats)) {
            return 0;
        }

        $linkcentral_stats_table = $wpdb->prefix . 'linkcentral_stats';
        $imported_count = 0;

        // Prepare data for batch insert
        $values = array();
        $placeholders = array();

        foreach ($stats as $stat) {
            $values = array_merge($values, array(
                $lc_link_id,
                $stat['click_date'],
                $stat['referring_url'] ?: '',
                $stat['user_agent'] ?: '',
                $stat['destination_url'] ?: '',
                '' , // country - Pretty Links doesn't store this
                $stat['visitor_id'] ?: '', // visitor_id from Pretty Links vuid
                $stat['first_click'] ?: 0 // first_click flag
            ));

            $placeholders[] = '(%d, %s, %s, %s, %s, %s, %s, %d)';
        }

        // Perform batch insert
        if (!empty($values)) {
            $query = $wpdb->prepare("
                INSERT INTO {$linkcentral_stats_table}
                (link_id, click_date, referring_url, user_agent, destination_url, country, visitor_id, first_click)
                VALUES " . implode(', ', $placeholders),
                $values
            );

            $result = $wpdb->query($query);
            if ($result !== false) {
                $imported_count = count($stats);
            }
        }

        return $imported_count;
    }

    /**
     * Convert Pretty Links nofollow setting to LinkCentral format
     *
     * @param string $nofollow Pretty Links nofollow setting
     * @return string LinkCentral nofollow setting
     */
    private function convert_pl_nofollow($nofollow) {
        if ($nofollow === '1' || $nofollow === 1) {
            return 'yes';
        } elseif ($nofollow === '0' || $nofollow === 0) {
            return 'no';
        }
        return 'default';
    }

    /**
     * Convert Pretty Links sponsored setting to LinkCentral format
     *
     * @param string $sponsored Pretty Links sponsored setting
     * @return string LinkCentral sponsored setting
     */
    private function convert_pl_sponsored($sponsored) {
        if ($sponsored === '1' || $sponsored === 1) {
            return 'yes';
        } elseif ($sponsored === '0' || $sponsored === 0) {
            return 'no';
        }
        return 'default';
    }

    /**
     * Convert Pretty Links parameter forwarding to LinkCentral format
     *
     * @param string $param_forwarding Pretty Links parameter forwarding setting
     * @return string LinkCentral parameter forwarding setting
     */
    private function convert_pl_parameter_forwarding($param_forwarding) {
        if ($param_forwarding === '1' || $param_forwarding === 1) {
            return 'yes';
        } elseif ($param_forwarding === '0' || $param_forwarding === 0) {
            return 'no';
        }
        return 'default';
    }

    /**
     * Convert Pretty Links redirect type to LinkCentral format
     *
     * @param string $redirect_type Pretty Links redirect type
     * @return string LinkCentral redirect type
     */
    private function convert_pl_redirect_type($redirect_type) {
        switch ($redirect_type) {
            case '301':
                return '301';
            case '302':
                return '302';
            case '307':
                return '307';
            default:
                return 'default';
        }
    }
}
