<?php
/**
 * ==========================
 * 🔐 IGNY8 FILE RULE HEADER
 * ==========================
 * @file         : sync-functions.php
 * @location     : /flows/sync-functions.php
 * @type         : Function Library
 * @scope        : Global
 * @allowed      : Automation logic, workflow functions, sync operations
 * @reusability  : Globally Reusable
 * @notes        : Core automation functions for all workflows
 

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}


/**
 * Update cluster metrics based on related keywords and mappings
 */
function igny8_update_cluster_metrics($cluster_id) {
    global $wpdb;
    
    if (!$cluster_id) {
        return ['success' => false, 'message' => 'Operation failed'];
    }
    
    try {
    
    // Get keyword count and aggregated data
    $keyword_data = $wpdb->get_row($wpdb->prepare("
        SELECT 
            COUNT(*) as keyword_count,
            COALESCE(SUM(search_volume), 0) as total_volume,
            COALESCE(AVG(difficulty), 0) as avg_difficulty
        FROM {$wpdb->prefix}igny8_keywords 
        WHERE cluster_id = %d
    ", $cluster_id));
    
    // Get mapped pages count from taxonomy relationships
    $cluster_term_id = $wpdb->get_var($wpdb->prepare("
        SELECT cluster_term_id FROM {$wpdb->prefix}igny8_clusters WHERE id = %d
    ", $cluster_id));
    
    $mapped_pages_count = 0;
    if ($cluster_term_id) {
        // Count content (posts, pages, products) associated with this cluster term
        $mapped_pages_count = $wpdb->get_var($wpdb->prepare("
            SELECT COUNT(DISTINCT object_id) 
            FROM {$wpdb->prefix}term_relationships tr
            INNER JOIN {$wpdb->prefix}term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
            WHERE tt.term_id = %d AND tt.taxonomy = 'clusters'
        ", $cluster_term_id));
    }
    
    // Update cluster record
    $wpdb->update(
        $wpdb->prefix . 'igny8_clusters',
        [
            'keyword_count' => intval($keyword_data->keyword_count),
            'total_volume' => intval($keyword_data->total_volume),
            'avg_difficulty' => floatval($keyword_data->avg_difficulty),
            'mapped_pages_count' => intval($mapped_pages_count)
        ],
        ['id' => $cluster_id],
        ['%d', '%d', '%f', '%d'],
        ['%d']
    );
    
    return true;
    
    } catch (Exception $e) {
        error_log("ERROR in igny8_update_cluster_metrics: " . $e->getMessage());
        return ['success' => false, 'message' => 'Failed to update cluster metrics: ' . $e->getMessage()];
    }
}

/**
 * Update campaign metrics
 */
function igny8_update_campaign_metrics($campaign_id) {
    global $wpdb;
    
    if (!$campaign_id) {
        return ['success' => false, 'message' => 'Operation failed'];
    }
    
    // Get campaign performance data
    $performance_data = $wpdb->get_row($wpdb->prepare("
        SELECT 
            COUNT(*) as total_tasks,
            COUNT(CASE WHEN status = 'completed' THEN 1 END) as completed_tasks,
            COALESCE(AVG(seo_score), 0) as avg_seo_score
        FROM {$wpdb->prefix}igny8_tasks 
        WHERE campaign_id = %d
    ", $campaign_id));
    
    // Update campaign record
    $wpdb->update(
        $wpdb->prefix . 'igny8_campaigns',
        [
            'total_tasks' => intval($performance_data->total_tasks),
            'completed_tasks' => intval($performance_data->completed_tasks),
            'avg_seo_score' => floatval($performance_data->avg_seo_score)
        ],
        ['id' => $campaign_id],
        ['%d', '%d', '%f'],
        ['%d']
    );
    
    return true;
}

/**
 * Update idea metrics based on related tasks
 */
function igny8_update_idea_metrics($idea_id) {
    global $wpdb;
    
    if (!$idea_id) {
        return ['success' => false, 'message' => 'Operation failed'];
    }
    
    // Get tasks count for this idea
    $tasks_count = $wpdb->get_var($wpdb->prepare("
        SELECT COUNT(*) 
        FROM {$wpdb->prefix}igny8_tasks 
        WHERE idea_id = %d
    ", $idea_id));
    
    // Update idea record
    $wpdb->update(
        $wpdb->prefix . 'igny8_content_ideas',
        [
            'tasks_count' => intval($tasks_count)
        ],
        ['id' => $idea_id],
        ['%d'],
        ['%d']
    );
    
    return true;
}

/**
 * Update task metrics based on related variations
 */
// REMOVED: Task variations functionality - tasks don't need variations

/**
 * Update keyword status when WordPress post is published
 * 
 * @param int $post_id The WordPress post ID that was published
 */
function igny8_update_keywords_on_post_publish($post_id) {
    global $wpdb;
    
    if (!$post_id) {
        return;
    }
    
    // Find tasks that are assigned to this post
    $tasks = $wpdb->get_results($wpdb->prepare("
        SELECT id, cluster_id 
        FROM {$wpdb->prefix}igny8_tasks 
        WHERE assigned_post_id = %d AND cluster_id IS NOT NULL
    ", $post_id));
    
    if (empty($tasks)) {
        return;
    }
    
    // Update keyword status to 'mapped' for all keywords in the clusters of published tasks
    foreach ($tasks as $task) {
        if ($task->cluster_id) {
            // Get all keywords in this cluster and update their status to 'mapped'
            $keyword_ids = $wpdb->get_col($wpdb->prepare("
                SELECT id FROM {$wpdb->prefix}igny8_keywords 
                WHERE cluster_id = %d
            ", $task->cluster_id));
            
            if (!empty($keyword_ids)) {
                $placeholders = implode(',', array_fill(0, count($keyword_ids), '%d'));
                $wpdb->query($wpdb->prepare("
                    UPDATE {$wpdb->prefix}igny8_keywords 
                    SET status = 'mapped' 
                    WHERE id IN ({$placeholders})
                ", $keyword_ids));
            }
            
            // Update task status to 'completed'
            $wpdb->update(
                $wpdb->prefix . 'igny8_tasks',
                ['status' => 'completed'],
                ['id' => $task->id],
                ['%s'],
                ['%d']
            );
        }
    }
    
    // Log the event
    if (function_exists('igny8_write_log')) {
        igny8_write_log('post_published', [
            'post_id' => $post_id, 
            'tasks_updated' => count($tasks),
            'message' => 'Keywords updated to mapped status'
        ]);
    }
}

/**
 * Automatically create clusters from keywords using AI clustering
 * 
 * @param array $keyword_ids Optional array of keyword IDs to cluster. If empty, uses all unmapped keywords.
 * @return array Result array with success status and message
 */
function igny8_auto_create_clusters_from_keywords($keyword_ids = []) {
    global $wpdb;
    
    // If no keyword IDs provided, get all unmapped keywords
    if (empty($keyword_ids)) {
        $keyword_ids = $wpdb->get_col("
            SELECT id FROM {$wpdb->prefix}igny8_keywords 
            WHERE cluster_id IS NULL
        ");
    }
    
    if (empty($keyword_ids)) {
        return ['success' => true, 'message' => 'No unmapped keywords found for clustering'];
    }
    
    // Limit to 20 keywords for AI processing
    if (count($keyword_ids) > 20) {
        $keyword_ids = array_slice($keyword_ids, 0, 20);
    }
    
    // Get keywords data
    $placeholders = implode(',', array_fill(0, count($keyword_ids), '%d'));
    $keywords = $wpdb->get_results($wpdb->prepare("
        SELECT * FROM {$wpdb->prefix}igny8_keywords 
        WHERE id IN ({$placeholders})
    ", $keyword_ids));
    
    if (empty($keywords)) {
        return ['success' => false, 'message' => 'No valid keywords found for clustering'];
    }
    
    // Create clusters using AI (this would call the AI clustering function)
    // For now, create a simple cluster with all keywords
    $cluster_name = igny8_generate_cluster_name_from_keywords(array_column($keywords, 'keyword'));
    
    // Create cluster
    $cluster_result = $wpdb->insert(
        $wpdb->prefix . 'igny8_clusters',
        [
            'cluster_name' => $cluster_name,
            'status' => 'active',
            'created_at' => current_time('mysql')
        ],
        ['%s', '%s', '%s']
    );
    
    if ($cluster_result === false) {
        return ['success' => false, 'message' => 'Failed to create cluster'];
    }
    
    $cluster_id = $wpdb->insert_id;
    
    // Trigger cluster_added action to create taxonomy term
    do_action('igny8_cluster_added', $cluster_id);
    
    // Map all keywords to this cluster
    $mapped_count = $wpdb->query($wpdb->prepare("
        UPDATE {$wpdb->prefix}igny8_keywords 
        SET cluster_id = %d, status = 'mapped' 
        WHERE id IN ({$placeholders})
    ", array_merge([$cluster_id], $keyword_ids)));
    
    // Update cluster metrics
    igny8_update_cluster_metrics($cluster_id);
    
    return [
        'success' => true,
        'message' => "Created cluster '{$cluster_name}' with {$mapped_count} keywords",
        'cluster_id' => $cluster_id,
        'mapped_count' => $mapped_count
    ];
}

/**
 * Workflow automation trigger system
 */
function igny8_workflow_triggers($event, $payload = []) {
    switch ($event) {
        case 'keywords_imported':
            if (isset($payload['keyword_ids'])) {
                return igny8_auto_create_clusters_from_keywords($payload['keyword_ids']);
            }
            break;
            
        case 'cluster_created':
            if (isset($payload['cluster_id'])) {
                // Create ideas from cluster
                $ideas_result = igny8_auto_create_ideas_from_clusters($payload['cluster_id']);
                
                return [
                    'success' => true,
                    'message' => 'Cluster workflow completed',
                    'ideas' => $ideas_result
                ];
            }
            break;
            
    }
    
    return ['success' => true, 'message' => 'No workflow automation for this event'];
}



/**
 * Bulk delete keywords with cluster metrics update
 */
function igny8_bulk_delete_keywords($keyword_ids) {
    global $wpdb;
    
    if (empty($keyword_ids) || !is_array($keyword_ids)) {
        return ['success' => false, 'message' => 'Operation failed'];
    }
    
    // Get cluster IDs before deletion for metrics update
    $placeholders = implode(',', array_fill(0, count($keyword_ids), '%d'));
    $cluster_ids = $wpdb->get_col($wpdb->prepare("
        SELECT DISTINCT cluster_id 
        FROM {$wpdb->prefix}igny8_keywords 
        WHERE id IN ({$placeholders}) 
        AND cluster_id IS NOT NULL
    ", $keyword_ids));
    
    // Delete keywords
    $result = $wpdb->query($wpdb->prepare("
        DELETE FROM {$wpdb->prefix}igny8_keywords 
        WHERE id IN ({$placeholders})
    ", $keyword_ids));
    
    if ($result !== false) {
        // Update cluster metrics for affected clusters
        foreach ($cluster_ids as $cluster_id) {
            if ($cluster_id) {
                igny8_update_cluster_metrics($cluster_id);
            }
        }
        
        return $result;
    }
    
    return ['success' => false, 'message' => 'Operation failed'];
}

/**
 * Bulk map keywords to cluster
 *
 * @param array $keyword_ids Array of keyword IDs to map
 * @param int $cluster_id Cluster ID to map keywords to
 * @return array ['success' => bool, 'message' => string, 'mapped_count' => int]
 */
function igny8_bulk_map_keywords($keyword_ids, $cluster_id) {
    global $wpdb;

    if (empty($keyword_ids) || !is_array($keyword_ids)) {
        return ['success' => false, 'message' => 'No keywords selected for mapping', 'mapped_count' => 0];
    }

    if (empty($cluster_id) || !is_numeric($cluster_id)) {
        return ['success' => false, 'message' => 'Invalid cluster ID provided', 'mapped_count' => 0];
    }

    $cluster_id = intval($cluster_id);

    // Verify cluster exists
    $cluster_exists = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->prefix}igny8_clusters WHERE id = %d",
        $cluster_id
    ));

    if (!$cluster_exists) {
        return ['success' => false, 'message' => 'Cluster not found', 'mapped_count' => 0];
    }

    // Sanitize and validate IDs
    $keyword_ids = array_map('intval', $keyword_ids);
    $keyword_ids = array_filter($keyword_ids, function($id) { return $id > 0; });

    if (empty($keyword_ids)) {
        return ['success' => false, 'message' => 'No valid keyword IDs provided', 'mapped_count' => 0];
    }

    // Get old cluster IDs for metrics update
    $placeholders = implode(',', array_fill(0, count($keyword_ids), '%d'));
    $old_cluster_ids = $wpdb->get_col($wpdb->prepare(
        "SELECT DISTINCT cluster_id FROM {$wpdb->prefix}igny8_keywords WHERE id IN ({$placeholders}) AND cluster_id IS NOT NULL",
        $keyword_ids
    ));

    // Update keywords to new cluster
    $mapped_count = $wpdb->query($wpdb->prepare(
        "UPDATE {$wpdb->prefix}igny8_keywords SET cluster_id = %d, status = 'mapped', updated_at = CURRENT_TIMESTAMP WHERE id IN ({$placeholders})",
        array_merge([$cluster_id], $keyword_ids)
    ));

    if ($mapped_count === false) {
        return ['success' => false, 'message' => 'Failed to map keywords to cluster', 'mapped_count' => 0];
    }

    // Update metrics for old clusters (they lost keywords)
    if (!empty($old_cluster_ids)) {
        foreach (array_unique($old_cluster_ids) as $old_cluster_id) {
            if ($old_cluster_id && $old_cluster_id != $cluster_id) {
                igny8_update_cluster_metrics($old_cluster_id);
            }
        }
    }

    // Update metrics for new cluster (gained keywords)
    igny8_update_cluster_metrics($cluster_id);

    return [
        'success' => true,
        'message' => "Successfully mapped {$mapped_count} keyword(s) to cluster",
        'mapped_count' => $mapped_count
    ];
}

/**
 * Bulk unmap keywords from their clusters
 *
 * @param array $keyword_ids Array of keyword IDs to unmap
 * @return array ['success' => bool, 'message' => string, 'unmapped_count' => int]
 */
function igny8_bulk_unmap_keywords($keyword_ids) {
    global $wpdb;

    if (empty($keyword_ids) || !is_array($keyword_ids)) {
        return ['success' => false, 'message' => 'No keywords selected for unmapping', 'unmapped_count' => 0];
    }

    // Sanitize and validate IDs
    $keyword_ids = array_map('intval', $keyword_ids);
    $keyword_ids = array_filter($keyword_ids, function($id) { return $id > 0; });

    if (empty($keyword_ids)) {
        return ['success' => false, 'message' => 'No valid keyword IDs provided', 'unmapped_count' => 0];
    }

    // Get cluster IDs before unmapping for metrics update
    $placeholders = implode(',', array_fill(0, count($keyword_ids), '%d'));
    $cluster_ids = $wpdb->get_col($wpdb->prepare(
        "SELECT DISTINCT cluster_id FROM {$wpdb->prefix}igny8_keywords WHERE id IN ({$placeholders}) AND cluster_id IS NOT NULL",
        $keyword_ids
    ));

    // Update keywords to unmap them
    $unmapped_count = $wpdb->query($wpdb->prepare(
        "UPDATE {$wpdb->prefix}igny8_keywords SET cluster_id = NULL, status = 'unmapped', updated_at = CURRENT_TIMESTAMP WHERE id IN ({$placeholders})",
        $keyword_ids
    ));

    if ($unmapped_count === false) {
        return ['success' => false, 'message' => 'Failed to unmap keywords from clusters', 'unmapped_count' => 0];
    }

    // Update metrics for affected clusters (they lost keywords)
    if (!empty($cluster_ids)) {
        foreach (array_unique($cluster_ids) as $cluster_id) {
            if ($cluster_id) {
                igny8_update_cluster_metrics($cluster_id);
            }
        }
    }

    return [
        'success' => true,
        'message' => "Successfully unmapped {$unmapped_count} keyword(s) from clusters",
        'unmapped_count' => $unmapped_count
    ];
}

/**
 * Automatically create or link a taxonomy term when a new cluster is created.
 *
 * @param int $cluster_id The cluster ID from wp_igny8_clusters.
 */
function igny8_auto_create_cluster_term($cluster_id) {
    global $wpdb;

    // 1. Validate cluster
    $cluster = $wpdb->get_row($wpdb->prepare(
        "SELECT cluster_name, cluster_term_id FROM {$wpdb->prefix}igny8_clusters WHERE id = %d",
        $cluster_id
    ));

    if (!$cluster) {
        error_log("Igny8: Cluster not found for ID $cluster_id.");
        return;
    }

    // 2. Skip if already mapped
    if (!empty($cluster->cluster_term_id)) {
        error_log("Igny8: Cluster $cluster_id already linked to term {$cluster->cluster_term_id}.");
        return;
    }

    // 3. Ensure taxonomy exists
    if (!taxonomy_exists('clusters') && function_exists('igny8_register_taxonomies')) {
        igny8_register_taxonomies();
    }

    // 4. Create or find existing term
    $term_result = wp_insert_term(
        sanitize_text_field($cluster->cluster_name),
        'clusters',
        ['slug' => sanitize_title($cluster->cluster_name)]
    );

    if (is_wp_error($term_result)) {
        // If term exists, fetch it
        $existing = get_term_by('name', $cluster->cluster_name, 'clusters');
        $term_id = $existing ? $existing->term_id : 0;
    } else {
        $term_id = $term_result['term_id'];
    }

    // 5. Save term ID back to cluster table
    if ($term_id > 0) {
        $wpdb->update(
            "{$wpdb->prefix}igny8_clusters",
            ['cluster_term_id' => $term_id],
            ['id' => $cluster_id],
            ['%d'],
            ['%d']
        );
        error_log("Igny8: Created and linked taxonomy term $term_id for cluster $cluster_id.");
    } else {
        error_log("Igny8: Failed to link taxonomy term for cluster $cluster_id.");
    }
}

/**
 * Automatically update taxonomy term when a cluster name is changed/updated.
 *
 * @param int $cluster_id The cluster ID from wp_igny8_clusters.
 */
function igny8_auto_update_cluster_term($cluster_id) {
    global $wpdb;

    // 1. Validate cluster
    $cluster = $wpdb->get_row($wpdb->prepare(
        "SELECT cluster_name, cluster_term_id FROM {$wpdb->prefix}igny8_clusters WHERE id = %d",
        $cluster_id
    ));

    if (!$cluster) {
        error_log("Igny8: Cluster not found for ID $cluster_id.");
        return;
    }

    // 2. Skip if no term linked
    if (empty($cluster->cluster_term_id)) {
        error_log("Igny8: Cluster $cluster_id has no linked taxonomy term.");
        return;
    }

    // 3. Ensure taxonomy exists
    if (!taxonomy_exists('clusters') && function_exists('igny8_register_taxonomies')) {
        igny8_register_taxonomies();
    }

    // 4. Get the existing term
    $term = get_term($cluster->cluster_term_id, 'clusters');
    if (is_wp_error($term) || !$term) {
        error_log("Igny8: Taxonomy term {$cluster->cluster_term_id} not found for cluster $cluster_id.");
        return;
    }

    // 5. Check if name has changed
    if ($term->name === $cluster->cluster_name) {
        error_log("Igny8: Cluster $cluster_id name unchanged, skipping taxonomy update.");
        return;
    }

    // 6. Update the term name and slug
    $update_result = wp_update_term(
        $cluster->cluster_term_id,
        'clusters',
        [
            'name' => sanitize_text_field($cluster->cluster_name),
            'slug' => sanitize_title($cluster->cluster_name)
        ]
    );

    if (is_wp_error($update_result)) {
        error_log("Igny8: Failed to update taxonomy term for cluster $cluster_id: " . $update_result->get_error_message());
    } else {
        error_log("Igny8: Successfully updated taxonomy term {$cluster->cluster_term_id} for cluster $cluster_id.");
    }
}

// Hook registration for automatic cluster term creation
// Hook moved to sync-hooks.php

/**
 * Handle content association/disassociation with cluster taxonomy terms
 */
function igny8_handle_content_cluster_association($object_id, $terms, $tt_ids, $taxonomy) {
    // Only process clusters taxonomy
    if ($taxonomy !== 'clusters') {
        return;
    }
    
    global $wpdb;
    
    // Get all cluster IDs that have terms in this taxonomy update
    $cluster_ids = [];
    
    foreach ($terms as $term) {
        if (is_numeric($term)) {
            $term_id = $term;
        } else {
            $term_obj = get_term_by('slug', $term, 'clusters');
            $term_id = $term_obj ? $term_obj->term_id : null;
        }
        
        if ($term_id) {
            // Find cluster that has this term_id
            $cluster_id = $wpdb->get_var($wpdb->prepare("
                SELECT id FROM {$wpdb->prefix}igny8_clusters 
                WHERE cluster_term_id = %d
            ", $term_id));
            
            if ($cluster_id) {
                $cluster_ids[] = $cluster_id;
            }
        }
    }
    
    // Update metrics for all affected clusters
    foreach (array_unique($cluster_ids) as $cluster_id) {
        igny8_update_cluster_metrics($cluster_id);
    }
}

// Hook registration for automatic cluster metrics updates when content is associated/disassociated with cluster terms
// Hook moved to sync-hooks.php

/**
 * Update task metrics including word count and meta sync
 */
function igny8_update_task_metrics($task_id) {
    global $wpdb;
    $post_id = $wpdb->get_var($wpdb->prepare("SELECT assigned_post_id FROM {$wpdb->prefix}igny8_tasks WHERE id = %d", $task_id));

    if ($post_id) {
        $content = get_post_field('post_content', $post_id);
        $word_count = str_word_count(strip_tags($content));
        update_post_meta($post_id, '_igny8_word_count', $word_count);

        $wpdb->update("{$wpdb->prefix}igny8_tasks", ['word_count' => $word_count], ['id' => $task_id]);
    }
}