<?php
/**
 * AJAX handler class
 *
 * @package ReplicateWP_Virtual_TryOn
 */

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

/**
 * AJAX handler class
 */
class RWPVTO_Ajax_Handler {
    
    /**
     * Single instance
     *
     * @var RWPVTO_Ajax_Handler
     */
    private static $instance = null;
    
    /**
     * Get instance
     *
     * @return RWPVTO_Ajax_Handler
     */
    public static function instance() {
        if ( is_null( self::$instance ) ) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Constructor
     */
    private function __construct() {
        // Generate try-on image
        add_action( 'wp_ajax_rwpvto_generate_tryon', array( $this, 'generate_tryon' ) );
        
        // Delete generated image
        add_action( 'wp_ajax_rwpvto_delete_image', array( $this, 'delete_image' ) );
        
        // Get generated images for product
        add_action( 'wp_ajax_rwpvto_get_product_images', array( $this, 'get_product_images' ) );
        
        // Add generated image to product gallery
        add_action( 'wp_ajax_rwpvto_add_to_gallery', array( $this, 'add_to_gallery' ) );
        
        // Test API connection
        add_action( 'wp_ajax_rwpvto_test_api', array( $this, 'test_api' ) );
    }
    
    /**
     * Generate try-on image
     */
    public function generate_tryon() {
        // Verify nonce
        check_ajax_referer( 'rwpvto_nonce', 'nonce' );
        
        // Check user capabilities
        if ( ! current_user_can( 'edit_products' ) ) {
            wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        // Get parameters
        $product_id = isset( $_POST['product_id'] ) ? absint( $_POST['product_id'] ) : 0;
        $garment_image = isset( $_POST['garment_image'] ) ? esc_url_raw( wp_unslash( $_POST['garment_image'] ) ) : '';
        $model_image = isset( $_POST['model_image'] ) ? esc_url_raw( wp_unslash( $_POST['model_image'] ) ) : '';
        $category = isset( $_POST['category'] ) ? sanitize_text_field( wp_unslash( $_POST['category'] ) ) : 'upper_body';
        $garment_description = isset( $_POST['garment_description'] ) ? sanitize_text_field( wp_unslash( $_POST['garment_description'] ) ) : '';
        $custom_filename = isset( $_POST['custom_filename'] ) ? sanitize_file_name( wp_unslash( $_POST['custom_filename'] ) ) : '';
        $model_gender = isset( $_POST['model_gender'] ) ? sanitize_text_field( wp_unslash( $_POST['model_gender'] ) ) : '';
        $auto_crop = isset( $_POST['auto_crop'] ) ? (bool) absint( $_POST['auto_crop'] ) : false;
        
        // Validate
        if ( empty( $product_id ) ) {
            wp_send_json_error( array( 'message' => __( 'Product ID is required.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        if ( empty( $garment_image ) ) {
            wp_send_json_error( array( 'message' => __( 'Garment image is required.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        if ( empty( $model_image ) ) {
            wp_send_json_error( array( 'message' => __( 'Model image is required.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        // Generate image using Replicate API
        $api = new RWPVTO_Replicate_API();
        $result = $api->generate_tryon( array(
            'garm_img' => $garment_image,
            'human_img' => $model_image,
            'garment_des' => $garment_description,
            'category' => $category,
            'crop' => $auto_crop,
        ) );
        
        // Check for errors
        if ( is_wp_error( $result ) ) {
            wp_send_json_error( array( 'message' => $result->get_error_message() ) );
        }
        
        // Automatically download image to WordPress uploads
        $local_image_url = null;
        $attachment_id = $this->download_and_attach_image( $result['output_url'], $product_id, null, array(
            'garm_img' => $garment_image,
            'human_img' => $model_image,
            'category' => $category,
            'garment_des' => $garment_description,
            'custom_filename' => $custom_filename,
            'model_gender' => $model_gender,
        ) );
        
        if ( ! is_wp_error( $attachment_id ) ) {
            $local_image_url = wp_get_attachment_url( $attachment_id );
        }
        
        // Save to database
        $db = RWPVTO_Database::instance();
        $image_id = $db->insert_image( array(
            'product_id' => $product_id,
            'garment_image_url' => $garment_image,
            'model_image_url' => $model_image,
            'generated_image_url' => $result['output_url'],
            'local_image_url' => $local_image_url,
            'replicate_prediction_id' => $result['prediction_id'],
            'model_gender' => $model_gender,
            'model_ethnicity' => null,
            'category' => $category,
            'garment_description' => $garment_description,
            'parameters' => array(
                'garm_img' => $garment_image,
                'human_img' => $model_image,
                'category' => $category,
                'garment_des' => $garment_description,
                'custom_filename' => $custom_filename,
            ),
            'status' => 'completed',
        ) );
        
        if ( ! $image_id ) {
            wp_send_json_error( array( 'message' => __( 'Failed to save generated image.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        // Use local URL if available, otherwise use replicate URL
        $display_url = $local_image_url ? $local_image_url : $result['output_url'];
        
        wp_send_json_success( array(
            'message' => __( 'Image generated successfully!', 'ai-virtual-try-on-for-woocommerce' ),
            'image_id' => $image_id,
            'image_url' => $display_url,
            'local_image_url' => $local_image_url,
            'prediction_id' => $result['prediction_id'],
        ) );
    }
    
    /**
     * Delete generated image
     */
    public function delete_image() {
        // Verify nonce
        check_ajax_referer( 'rwpvto_nonce', 'nonce' );
        
        // Check user capabilities
        if ( ! current_user_can( 'edit_products' ) ) {
            wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        $image_id = isset( $_POST['image_id'] ) ? absint( $_POST['image_id'] ) : 0;
        
        if ( empty( $image_id ) ) {
            wp_send_json_error( array( 'message' => __( 'Image ID is required.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        $db = RWPVTO_Database::instance();
        $result = $db->delete_image( $image_id );
        
        if ( $result ) {
            wp_send_json_success( array( 'message' => __( 'Image deleted successfully.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        } else {
            wp_send_json_error( array( 'message' => __( 'Failed to delete image.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
    }
    
    /**
     * Get generated images for product
     */
    public function get_product_images() {
        // Verify nonce
        check_ajax_referer( 'rwpvto_nonce', 'nonce' );
        
        // Check user capabilities
        if ( ! current_user_can( 'edit_products' ) ) {
            wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        $product_id = isset( $_POST['product_id'] ) ? absint( $_POST['product_id'] ) : 0;
        
        if ( empty( $product_id ) ) {
            wp_send_json_error( array( 'message' => __( 'Product ID is required.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        $db = RWPVTO_Database::instance();
        $images = $db->get_images_by_product( $product_id );
        
        wp_send_json_success( array( 'images' => $images ) );
    }
    
    /**
     * Add generated image to product gallery
     */
    public function add_to_gallery() {
        // Verify nonce
        check_ajax_referer( 'rwpvto_nonce', 'nonce' );
        
        // Check user capabilities
        if ( ! current_user_can( 'edit_products' ) ) {
            wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        $image_id = isset( $_POST['image_id'] ) ? absint( $_POST['image_id'] ) : 0;
        $product_id = isset( $_POST['product_id'] ) ? absint( $_POST['product_id'] ) : 0;
        
        if ( empty( $image_id ) || empty( $product_id ) ) {
            wp_send_json_error( array( 'message' => __( 'Image ID and Product ID are required.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        // Get image from database
        $db = RWPVTO_Database::instance();
        $image = $db->get_image( $image_id );
        
        if ( ! $image ) {
            wp_send_json_error( array( 'message' => __( 'Image not found.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        // Download image and add to media library (if not already downloaded)
        $attachment_id = null;
        $local_image_url = null;
        
        if ( ! empty( $image->local_image_url ) ) {
            // Image already downloaded, get attachment ID from URL
            $attachment_id = attachment_url_to_postid( $image->local_image_url );
            $local_image_url = $image->local_image_url;
        } else {
            // Download image and add to media library
            $attachment_id = $this->download_and_attach_image( $image->generated_image_url, $product_id, $image );
            
            if ( is_wp_error( $attachment_id ) ) {
                wp_send_json_error( array( 'message' => $attachment_id->get_error_message() ) );
            }
            
            // Get local URL and update database
            $local_image_url = wp_get_attachment_url( $attachment_id );
            if ( $local_image_url ) {
                $db->update_image( $image->id, array( 'local_image_url' => $local_image_url ) );
            }
        }
        
        // Add to product gallery
        $product = wc_get_product( $product_id );
        if ( ! $product ) {
            wp_send_json_error( array( 'message' => __( 'Product not found.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        $gallery_ids = $product->get_gallery_image_ids();
        
        // Check if image already exists in gallery
        if ( in_array( $attachment_id, $gallery_ids, true ) ) {
            wp_send_json_error( array( 'message' => __( 'This image is already in the product gallery.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        // Add to gallery
        $gallery_ids[] = $attachment_id;
        $product->set_gallery_image_ids( $gallery_ids );
        $product->save();
        
        wp_send_json_success( array(
            'message' => __( 'Image added to product gallery.', 'ai-virtual-try-on-for-woocommerce' ),
            'attachment_id' => $attachment_id,
        ) );
    }
    
    /**
     * Test API connection
     */
    public function test_api() {
        // Verify nonce
        check_ajax_referer( 'rwpvto_nonce', 'nonce' );
        
        // Check user capabilities
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'ai-virtual-try-on-for-woocommerce' ) ) );
        }
        
        $api = new RWPVTO_Replicate_API();
        $result = $api->test_connection();
        
        if ( is_wp_error( $result ) ) {
            wp_send_json_error( array( 'message' => $result->get_error_message() ) );
        }
        
        wp_send_json_success( array( 'message' => __( 'API connection successful!', 'ai-virtual-try-on-for-woocommerce' ) ) );
    }
    
    /**
     * Download image and attach to product
     *
     * @param string $image_url Image URL
     * @param int $product_id Product ID
     * @param object|null $image_data Image data from database (optional)
     * @param array|null $params Additional parameters for filename generation (optional)
     * @return int|WP_Error Attachment ID or error
     */
    private function download_and_attach_image( $image_url, $product_id, $image_data = null, $params = null ) {
        require_once ABSPATH . 'wp-admin/includes/file.php';
        require_once ABSPATH . 'wp-admin/includes/media.php';
        require_once ABSPATH . 'wp-admin/includes/image.php';
        
        // Set timeout for external image download
        add_filter( 'http_request_timeout', array( $this, 'increase_download_timeout' ) );
        
        // Download file with increased timeout
        $tmp = download_url( $image_url, 60 ); // 60 seconds timeout
        
        // Remove filter
        remove_filter( 'http_request_timeout', array( $this, 'increase_download_timeout' ) );
        
        if ( is_wp_error( $tmp ) ) {
            return new WP_Error(
                'download_failed',
                sprintf(
                    /* translators: %s: Error message */
                    __( 'Failed to download image: %s', 'ai-virtual-try-on-for-woocommerce' ),
                    $tmp->get_error_message()
                )
            );
        }
        
        // Detect file extension from URL or default to png
        $file_ext = 'png';
        $parsed_url = wp_parse_url( $image_url );
        if ( isset( $parsed_url['path'] ) ) {
            $path_info = pathinfo( $parsed_url['path'] );
            if ( isset( $path_info['extension'] ) ) {
                $file_ext = strtolower( $path_info['extension'] );
            }
        }
        
        // Validate and sanitize file extension (support common image formats)
        $allowed_extensions = array( 'jpg', 'jpeg', 'png', 'gif', 'webp' );
        if ( ! in_array( $file_ext, $allowed_extensions, true ) ) {
            $file_ext = 'png'; // Default to png if unknown extension
        }
        
        // Check for custom filename first
        $custom_filename = '';
        $model_gender = null;
        
        // Try to get parameters from $params first (for new images), then from $image_data
        if ( $params && isset( $params['custom_filename'] ) ) {
            $custom_filename = $params['custom_filename'];
        } elseif ( $image_data && ! empty( $image_data->parameters ) ) {
            // Parameters are stored as JSON, so decode if needed
            $parameters = $image_data->parameters;
            if ( is_string( $parameters ) ) {
                $parameters = json_decode( $parameters, true );
            }
            if ( is_array( $parameters ) && isset( $parameters['custom_filename'] ) ) {
                $custom_filename = $parameters['custom_filename'];
            }
        }
        
        // Get model_gender from params or image_data
        if ( $params && isset( $params['model_gender'] ) ) {
            $model_gender = $params['model_gender'];
        } elseif ( $image_data && ! empty( $image_data->model_gender ) ) {
            $model_gender = $image_data->model_gender;
        }
        
        // Get category from params or image_data
        $category = null;
        if ( $params && isset( $params['category'] ) ) {
            $category = $params['category'];
        } elseif ( $image_data && ! empty( $image_data->category ) ) {
            $category = $image_data->category;
        }
        
        // Use custom filename if provided, otherwise build SEO-friendly filename
        if ( ! empty( $custom_filename ) ) {
            // Sanitize custom filename
            $filename = sanitize_file_name( $custom_filename );
            // Remove any file extension if user included it
            $filename = preg_replace( '/\.[^.]+$/', '', $filename );
            // Add timestamp for uniqueness
            $filename = $filename . '-' . time();
        } else {
            // Build SEO-friendly filename
            $filename_parts = array();
            
            // Get product name/slug
            $product = wc_get_product( $product_id );
            if ( $product ) {
                $product_slug = sanitize_file_name( $product->get_slug() );
                if ( empty( $product_slug ) ) {
                    $product_slug = sanitize_file_name( $product->get_name() );
                }
                if ( ! empty( $product_slug ) ) {
                    $filename_parts[] = $product_slug;
                }
            }
            
            // Add model info if available
            if ( ! empty( $model_gender ) ) {
                $gender = strtolower( sanitize_file_name( $model_gender ) );
                $filename_parts[] = $gender;
            }
            
            // Add category if available
            if ( ! empty( $category ) ) {
                $category_sanitized = sanitize_file_name( $category );
                // Convert category to readable format
                $category_map = array(
                    'upper_body' => 'upper-body',
                    'lower_body' => 'lower-body',
                    'dresses' => 'dress',
                );
                $category_sanitized = isset( $category_map[ $category_sanitized ] ) ? $category_map[ $category_sanitized ] : $category_sanitized;
                $filename_parts[] = $category_sanitized;
            }
            
            // Add virtual-tryon prefix
            array_unshift( $filename_parts, 'virtual-tryon' );
            
            // Add timestamp for uniqueness
            $filename_parts[] = time();
            
            // Join parts and create filename
            $filename = implode( '-', $filename_parts );
        }
        
        // Limit filename length (max 200 chars for filesystem compatibility)
        if ( strlen( $filename ) > 200 ) {
            $filename = substr( $filename, 0, 200 );
        }
        
        // Get file info
        $file_array = array(
            'name' => $filename . '.' . $file_ext,
            'tmp_name' => $tmp,
        );
        
        // Upload to media library
        $attachment_id = media_handle_sideload( $file_array, $product_id );
        
        // Check for errors
        if ( is_wp_error( $attachment_id ) ) {
            wp_delete_file( $file_array['tmp_name'] );
            return new WP_Error(
                'upload_failed',
                sprintf(
                    /* translators: %s: Error message */
                    __( 'Failed to upload to media library: %s', 'ai-virtual-try-on-for-woocommerce' ),
                    $attachment_id->get_error_message()
                )
            );
        }
        
        return $attachment_id;
    }
    
    /**
     * Increase download timeout for external images
     *
     * @param int $timeout Current timeout
     * @return int New timeout
     */
    public function increase_download_timeout( $timeout ) {
        return 60; // 60 seconds
    }
}

