<?php
namespace PrimeLink\Modules\Reviews;

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

class ReviewImportService {
    /**
     * Find an existing review by a given field (review_id, product_id + author_email, etc.)
     * 
     * @param array $review_data Review data
     * @param string $match_by Match by field
     * @param array $batch_lookups Optional batch lookup results (for optimization)
     * @return int Review ID or 0 if not found
     */
    public static function find_existing_review_id( $review_data, $match_by, $batch_lookups = null ) {
        $match_by = (string) $match_by;
        
        // Match by review_id
        if ( $match_by === 'review_id' && ! empty( $review_data['review_id'] ) ) {
            $review_id = absint( $review_data['review_id'] );
            $review = get_comment( $review_id );
            return ( $review && $review->comment_type === 'review' ) ? $review_id : 0;
        }
        
        // Match by product_id + author_email (most reliable for reviews)
        if ( $match_by === 'product_author' && ! empty( $review_data['product_id'] ) && ! empty( $review_data['author_email'] ) ) {
            $product_id = absint( $review_data['product_id'] );
            $author_email = sanitize_email( $review_data['author_email'] );
            
            // Use batch lookup if available
            if ( $batch_lookups && isset( $batch_lookups['reviews_by_product_author'][ $product_id ][ $author_email ] ) ) {
                return absint( $batch_lookups['reviews_by_product_author'][ $product_id ][ $author_email ] );
            }
            
            // Fallback to individual lookup
            $reviews = get_comments( array(
                'post_id' => $product_id,
                'author_email' => $author_email,
                'type' => 'review',
                'status' => 'all',
                'number' => 1,
            ) );
            
            if ( ! empty( $reviews ) ) {
                return absint( $reviews[0]->comment_ID );
            }
        }
        
        // Match by product_id + author_name (fallback)
        if ( $match_by === 'product_author_name' && ! empty( $review_data['product_id'] ) && ! empty( $review_data['author_name'] ) ) {
            $product_id = absint( $review_data['product_id'] );
            $author_name = sanitize_text_field( $review_data['author_name'] );
            
            $reviews = get_comments( array(
                'post_id' => $product_id,
                'author' => $author_name,
                'type' => 'review',
                'status' => 'all',
                'number' => 1,
            ) );
            
            if ( ! empty( $reviews ) ) {
                return absint( $reviews[0]->comment_ID );
            }
        }
        
        return 0;
    }

    /**
     * Create a new WooCommerce product review from mapped data
     */
    public static function create_review( $review_data, $import_id = 0 ) {
        // Product ID is required
        if ( empty( $review_data['product_id'] ) ) {
            return 0;
        }
        
        $product_id = absint( $review_data['product_id'] );
        $product = wc_get_product( $product_id );
        
        if ( ! $product ) {
            \PrimeLink\Helpers\LoggerHelper::error(
                'Review Import Error: Product not found',
                array( 'product_id' => $product_id )
            );
            return 0;
        }
        
        // Required fields
        $author_name = ! empty( $review_data['author_name'] ) ? sanitize_text_field( $review_data['author_name'] ) : __( 'Anonymous', 'primelink' );
        $author_email = ! empty( $review_data['author_email'] ) ? sanitize_email( $review_data['author_email'] ) : '';
        $content = ! empty( $review_data['content'] ) ? wp_kses_post( $review_data['content'] ) : '';
        $rating = ! empty( $review_data['rating'] ) ? absint( $review_data['rating'] ) : 0;
        
        // Validate rating (1-5)
        if ( $rating < 1 || $rating > 5 ) {
            $rating = 0;
        }
        
        // Review data
        $comment_data = array(
            'comment_post_ID' => $product_id,
            'comment_author' => $author_name,
            'comment_author_email' => $author_email,
            'comment_author_url' => ! empty( $review_data['author_url'] ) ? esc_url_raw( $review_data['author_url'] ) : '',
            'comment_content' => $content,
            'comment_type' => 'review',
            'comment_parent' => ! empty( $review_data['parent_id'] ) ? absint( $review_data['parent_id'] ) : 0,
            'comment_approved' => ! empty( $review_data['status'] ) ? self::normalize_status( $review_data['status'] ) : 1,
            'comment_date' => ! empty( $review_data['date_created'] ) ? self::normalize_date( $review_data['date_created'] ) : current_time( 'mysql' ),
            'comment_date_gmt' => ! empty( $review_data['date_created'] ) ? get_gmt_from_date( self::normalize_date( $review_data['date_created'] ) ) : current_time( 'mysql', 1 ),
        );
        
        // Insert review
        $review_id = wp_insert_comment( $comment_data );
        
        if ( is_wp_error( $review_id ) ) {
            \PrimeLink\Helpers\LoggerHelper::error(
                'Review Import Error: ' . $review_id->get_error_message(),
                array(
                    'product_id' => $product_id,
                    'data' => $review_data,
                )
            );
            return 0;
        }
        
        // Set rating
        if ( $rating > 0 ) {
            update_comment_meta( $review_id, 'rating', $rating );
        }
        
        // Set verified purchase
        if ( isset( $review_data['verified_purchase'] ) ) {
            $verified = self::normalize_boolean( $review_data['verified_purchase'] );
            update_comment_meta( $review_id, 'verified', $verified ? 'yes' : 'no' );
        }
        
        // Set helpful votes
        if ( isset( $review_data['helpful_votes'] ) ) {
            update_comment_meta( $review_id, 'helpful_votes', absint( $review_data['helpful_votes'] ) );
        }
        
        // Set title if provided
        if ( ! empty( $review_data['title'] ) ) {
            update_comment_meta( $review_id, 'title', sanitize_text_field( $review_data['title'] ) );
        }
        
        // Store import tracking
        if ( $import_id > 0 ) {
            update_comment_meta( $review_id, '_mt_primelink_import_id', absint( $import_id ) );
        }
        
        return absint( $review_id );
    }

    /**
     * Update an existing WooCommerce product review
     */
    public static function update_review( $review_id, $review_data, $update_fields = array() ) {
        $review = get_comment( $review_id );
        if ( ! $review || $review->comment_type !== 'review' ) {
            return false;
        }
        
        $update_all = empty( $update_fields ) || in_array( 'all', $update_fields, true );
        
        $comment_data = array();
        
        // Update author name
        if ( ( $update_all || in_array( 'author', $update_fields, true ) ) && isset( $review_data['author_name'] ) ) {
            $comment_data['comment_author'] = sanitize_text_field( $review_data['author_name'] );
        }
        
        // Update author email
        if ( ( $update_all || in_array( 'author', $update_fields, true ) ) && isset( $review_data['author_email'] ) ) {
            $comment_data['comment_author_email'] = sanitize_email( $review_data['author_email'] );
        }
        
        // Update author URL
        if ( ( $update_all || in_array( 'author', $update_fields, true ) ) && isset( $review_data['author_url'] ) ) {
            $comment_data['comment_author_url'] = esc_url_raw( $review_data['author_url'] );
        }
        
        // Update content
        if ( ( $update_all || in_array( 'content', $update_fields, true ) ) && isset( $review_data['content'] ) ) {
            $comment_data['comment_content'] = wp_kses_post( $review_data['content'] );
        }
        
        // Update status
        if ( ( $update_all || in_array( 'status', $update_fields, true ) ) && isset( $review_data['status'] ) ) {
            $comment_data['comment_approved'] = self::normalize_status( $review_data['status'] );
        }
        
        // Update date
        if ( ( $update_all || in_array( 'date', $update_fields, true ) ) && isset( $review_data['date_created'] ) ) {
            $date = self::normalize_date( $review_data['date_created'] );
            $comment_data['comment_date'] = $date;
            $comment_data['comment_date_gmt'] = get_gmt_from_date( $date );
        }
        
        // Update parent
        if ( ( $update_all || in_array( 'parent', $update_fields, true ) ) && isset( $review_data['parent_id'] ) ) {
            $comment_data['comment_parent'] = absint( $review_data['parent_id'] );
        }
        
        // Update comment if we have data
        if ( ! empty( $comment_data ) ) {
            $comment_data['comment_ID'] = $review_id;
            wp_update_comment( $comment_data );
        }
        
        // Update rating
        if ( ( $update_all || in_array( 'rating', $update_fields, true ) ) && isset( $review_data['rating'] ) ) {
            $rating = absint( $review_data['rating'] );
            if ( $rating >= 1 && $rating <= 5 ) {
                update_comment_meta( $review_id, 'rating', $rating );
            }
        }
        
        // Update verified purchase
        if ( ( $update_all || in_array( 'verified', $update_fields, true ) ) && isset( $review_data['verified_purchase'] ) ) {
            $verified = self::normalize_boolean( $review_data['verified_purchase'] );
            update_comment_meta( $review_id, 'verified', $verified ? 'yes' : 'no' );
        }
        
        // Update helpful votes
        if ( ( $update_all || in_array( 'helpful', $update_fields, true ) ) && isset( $review_data['helpful_votes'] ) ) {
            update_comment_meta( $review_id, 'helpful_votes', absint( $review_data['helpful_votes'] ) );
        }
        
        // Update title
        if ( ( $update_all || in_array( 'title', $update_fields, true ) ) && isset( $review_data['title'] ) ) {
            update_comment_meta( $review_id, 'title', sanitize_text_field( $review_data['title'] ) );
        }
        
        return true;
    }

    /**
     * Normalize status to WooCommerce comment status
     */
    private static function normalize_status( $status ) {
        $status = strtolower( trim( $status ) );
        
        $status_map = array(
            'approved' => 1,
            'approve' => 1,
            '1' => 1,
            'true' => 1,
            'yes' => 1,
            'pending' => 0,
            '0' => 0,
            'false' => 0,
            'no' => 0,
            'spam' => 'spam',
            'trash' => 'trash',
        );
        
        return isset( $status_map[ $status ] ) ? $status_map[ $status ] : 1;
    }

    /**
     * Normalize date to MySQL format
     */
    private static function normalize_date( $date ) {
        if ( empty( $date ) ) {
            return current_time( 'mysql' );
        }
        
        // Try to parse the date
        $timestamp = strtotime( $date );
        if ( $timestamp === false ) {
            return current_time( 'mysql' );
        }
        
        return date( 'Y-m-d H:i:s', $timestamp );
    }

    /**
     * Normalize boolean value
     */
    private static function normalize_boolean( $value ) {
        if ( is_bool( $value ) ) {
            return $value;
        }
        
        $value = strtolower( trim( (string) $value ) );
        
        return in_array( $value, array( '1', 'true', 'yes', 'on' ), true );
    }

    /**
     * Prepare batch lookups for reviews
     */
    public static function prepare_batch_lookups( $rows, $headers, $mapping, $match_by ) {
        $lookups = array(
            'reviews_by_product_author' => array(),
        );
        
        if ( empty( $rows ) || empty( $mapping ) ) {
            return $lookups;
        }
        
        // Extract product IDs and author emails from the batch
        $product_author_pairs = array();
        
        foreach ( $rows as $row ) {
            $item = array();
            foreach ( $headers as $idx => $header ) {
                $item[ $header ] = $row[ $idx ] ?? '';
            }
            
            // Try to get product_id and author_email from mapped data
            $product_id = null;
            $author_email = null;
            
            foreach ( $mapping as $column_config ) {
                if ( is_string( $column_config ) ) {
                    $column_config = array( 'source' => $column_config );
                }
                $source = $column_config['source'] ?? '';
                
                if ( $source === 'product_id' && ! empty( $item[ $source ] ) ) {
                    $product_id = absint( $item[ $source ] );
                }
                if ( $source === 'author_email' && ! empty( $item[ $source ] ) ) {
                    $author_email = sanitize_email( $item[ $source ] );
                }
            }
            
            if ( $product_id && $author_email ) {
                $product_author_pairs[] = array(
                    'product_id' => $product_id,
                    'author_email' => $author_email,
                );
            }
        }
        
        if ( ! empty( $product_author_pairs ) ) {
            // Group by product_id for efficient lookup
            $grouped = array();
            foreach ( $product_author_pairs as $pair ) {
                $pid = $pair['product_id'];
                $email = $pair['author_email'];
                if ( ! isset( $grouped[ $pid ] ) ) {
                    $grouped[ $pid ] = array();
                }
                $grouped[ $pid ][] = $email;
            }
            
            // Batch lookup reviews
            foreach ( $grouped as $product_id => $emails ) {
                $reviews = get_comments( array(
                    'post_id' => $product_id,
                    'author_email__in' => array_unique( $emails ),
                    'type' => 'review',
                    'status' => 'all',
                ) );
                
                foreach ( $reviews as $review ) {
                    $email = strtolower( $review->comment_author_email );
                    if ( ! isset( $lookups['reviews_by_product_author'][ $product_id ] ) ) {
                        $lookups['reviews_by_product_author'][ $product_id ] = array();
                    }
                    $lookups['reviews_by_product_author'][ $product_id ][ $email ] = absint( $review->comment_ID );
                }
            }
        }
        
        return $lookups;
    }
}


