<?php
namespace PrimeLink\Modules\Coupons;

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

class CouponImportService {
    /**
     * Find an existing coupon by a given field (code, coupon_id)
     * 
     * @param array $coupon_data Coupon data
     * @param string $match_by Match by field
     * @param array $batch_lookups Optional batch lookup results (for optimization)
     * @return int Coupon ID or 0 if not found
     */
    public static function find_existing_coupon_id( $coupon_data, $match_by, $batch_lookups = null ) {
        if ( $match_by === 'code' && !empty($coupon_data['code']) ) {
            $code = sanitize_text_field( $coupon_data['code'] );
            
            // Use batch lookup if available
            if ( $batch_lookups && isset( $batch_lookups['coupons_by_code'][ $code ] ) ) {
                return absint( $batch_lookups['coupons_by_code'][ $code ] );
            }
            
            // Fallback to individual lookup
            $coupon = new \WC_Coupon( $code );
            return $coupon->get_id() > 0 ? $coupon->get_id() : 0;
        }
        if ( $match_by === 'coupon_id' && !empty($coupon_data['coupon_id']) ) {
            $coupon_id = absint($coupon_data['coupon_id']);
            $coupon = new \WC_Coupon( $coupon_id );
            return $coupon->get_id() > 0 ? $coupon->get_id() : 0;
        }
        return 0;
    }

    /**
     * Create a new WooCommerce coupon from mapped data
     */
    public static function create_coupon( $coupon_data, $import_id = 0 ) {
        // Code is required
        if ( empty($coupon_data['code']) ) {
            return 0;
        }

        $code = sanitize_text_field($coupon_data['code']);
        
        // Check if coupon already exists
        $existing_coupon = new \WC_Coupon( $code );
        if ( $existing_coupon->get_id() > 0 ) {
            // Update existing coupon
            $coupon_id = $existing_coupon->get_id();
        } else {
            // Create new coupon
            $coupon = new \WC_Coupon();
            $coupon->set_code( $code );
            $coupon_id = $coupon->save();
            
            if ( !$coupon_id || is_wp_error($coupon_id) ) {
                return 0;
            }
        }
        
        // Get the coupon object
        $coupon = new \WC_Coupon( $coupon_id );
        
        // Discount type
        if ( !empty($coupon_data['discount_type']) ) {
            $discount_type = sanitize_text_field($coupon_data['discount_type']);
            $valid_types = array( 'fixed_cart', 'fixed_product', 'percent', 'percent_product' );
            if ( in_array($discount_type, $valid_types, true) ) {
                $coupon->set_discount_type( $discount_type );
            }
        } else {
            // Default to fixed_cart if not set
            $coupon->set_discount_type( 'fixed_cart' );
        }
        
        // Discount amount
        if ( !empty($coupon_data['amount']) ) {
            $coupon->set_amount( floatval($coupon_data['amount']) );
        }
        
        // Description
        if ( !empty($coupon_data['description']) ) {
            $coupon->set_description( sanitize_textarea_field($coupon_data['description']) );
        }
        
        // Expiry date
        if ( !empty($coupon_data['date_expires']) ) {
            $expires = self::parse_date($coupon_data['date_expires']);
            if ( $expires ) {
                $coupon->set_date_expires( $expires );
            }
        }
        
        // Usage limits
        if ( isset($coupon_data['usage_limit']) && $coupon_data['usage_limit'] !== '' ) {
            $coupon->set_usage_limit( absint($coupon_data['usage_limit']) );
        }
        if ( isset($coupon_data['usage_limit_per_user']) && $coupon_data['usage_limit_per_user'] !== '' ) {
            $coupon->set_usage_limit_per_user( absint($coupon_data['usage_limit_per_user']) );
        }
        
        // Minimum and maximum amounts
        if ( !empty($coupon_data['minimum_amount']) ) {
            $coupon->set_minimum_amount( floatval($coupon_data['minimum_amount']) );
        }
        if ( !empty($coupon_data['maximum_amount']) ) {
            $coupon->set_maximum_amount( floatval($coupon_data['maximum_amount']) );
        }
        
        // Boolean flags
        if ( isset($coupon_data['individual_use']) ) {
            $coupon->set_individual_use( (bool) $coupon_data['individual_use'] );
        }
        if ( isset($coupon_data['exclude_sale_items']) ) {
            $coupon->set_exclude_sale_items( (bool) $coupon_data['exclude_sale_items'] );
        }
        if ( isset($coupon_data['free_shipping']) ) {
            $coupon->set_free_shipping( (bool) $coupon_data['free_shipping'] );
        }
        
        // Product restrictions
        if ( !empty($coupon_data['product_ids']) ) {
            $product_ids = self::parse_ids($coupon_data['product_ids']);
            $coupon->set_product_ids( $product_ids );
        }
        if ( !empty($coupon_data['excluded_product_ids']) ) {
            $excluded_ids = self::parse_ids($coupon_data['excluded_product_ids']);
            $coupon->set_excluded_product_ids( $excluded_ids );
        }
        
        // Category restrictions
        if ( !empty($coupon_data['product_categories']) ) {
            $categories = self::parse_ids($coupon_data['product_categories']);
            $coupon->set_product_categories( $categories );
        }
        if ( !empty($coupon_data['excluded_product_categories']) ) {
            $excluded_cats = self::parse_ids($coupon_data['excluded_product_categories']);
            $coupon->set_excluded_product_categories( $excluded_cats );
        }
        
        // Customer email restrictions
        if ( !empty($coupon_data['customer_emails']) ) {
            $emails = self::parse_emails($coupon_data['customer_emails']);
            $coupon->set_email_restrictions( $emails );
        }
        
        // Limit usage to X items
        if ( isset($coupon_data['limit_usage_to_x_items']) && $coupon_data['limit_usage_to_x_items'] !== '' ) {
            $coupon->set_limit_usage_to_x_items( absint($coupon_data['limit_usage_to_x_items']) );
        }
        
        // Custom meta fields
        if ( !empty($coupon_data['meta']) && is_array($coupon_data['meta']) ) {
            foreach ( $coupon_data['meta'] as $key => $value ) {
                update_post_meta( $coupon_id, sanitize_key($key), $value );
            }
        }
        
        // Save the coupon
        $coupon->save();
        
        if ( $import_id > 0 ) {
            update_post_meta( $coupon_id, '_mt_primelink_import_id', absint($import_id) );
        }
        
        return $coupon_id;
    }

    /**
     * Update an existing coupon
     */
    public static function update_coupon( $coupon_id, $coupon_data, $update_fields = array() ) {
        $coupon = new \WC_Coupon( $coupon_id );
        if ( $coupon->get_id() === 0 ) {
            return;
        }
        
        if ( empty($update_fields) || in_array('discount', $update_fields) ) {
            if ( !empty($coupon_data['discount_type']) ) {
                $discount_type = sanitize_text_field($coupon_data['discount_type']);
                $valid_types = array( 'fixed_cart', 'fixed_product', 'percent', 'percent_product' );
                if ( in_array($discount_type, $valid_types, true) ) {
                    $coupon->set_discount_type( $discount_type );
                }
            }
            if ( !empty($coupon_data['amount']) ) {
                $coupon->set_amount( floatval($coupon_data['amount']) );
            }
            if ( !empty($coupon_data['description']) ) {
                $coupon->set_description( sanitize_textarea_field($coupon_data['description']) );
            }
        }
        
        if ( empty($update_fields) || in_array('restrictions', $update_fields) ) {
            if ( !empty($coupon_data['product_ids']) ) {
                $coupon->set_product_ids( self::parse_ids($coupon_data['product_ids']) );
            }
            if ( !empty($coupon_data['excluded_product_ids']) ) {
                $coupon->set_excluded_product_ids( self::parse_ids($coupon_data['excluded_product_ids']) );
            }
            if ( !empty($coupon_data['product_categories']) ) {
                $coupon->set_product_categories( self::parse_ids($coupon_data['product_categories']) );
            }
            if ( !empty($coupon_data['excluded_product_categories']) ) {
                $coupon->set_excluded_product_categories( self::parse_ids($coupon_data['excluded_product_categories']) );
            }
            if ( !empty($coupon_data['customer_emails']) ) {
                $coupon->set_email_restrictions( self::parse_emails($coupon_data['customer_emails']) );
            }
            if ( isset($coupon_data['minimum_amount']) ) {
                $coupon->set_minimum_amount( floatval($coupon_data['minimum_amount']) );
            }
            if ( isset($coupon_data['maximum_amount']) ) {
                $coupon->set_maximum_amount( floatval($coupon_data['maximum_amount']) );
            }
            if ( isset($coupon_data['individual_use']) ) {
                $coupon->set_individual_use( (bool) $coupon_data['individual_use'] );
            }
            if ( isset($coupon_data['exclude_sale_items']) ) {
                $coupon->set_exclude_sale_items( (bool) $coupon_data['exclude_sale_items'] );
            }
            if ( isset($coupon_data['free_shipping']) ) {
                $coupon->set_free_shipping( (bool) $coupon_data['free_shipping'] );
            }
        }
        
        if ( empty($update_fields) || in_array('usage', $update_fields) ) {
            if ( isset($coupon_data['usage_limit']) && $coupon_data['usage_limit'] !== '' ) {
                $coupon->set_usage_limit( absint($coupon_data['usage_limit']) );
            }
            if ( isset($coupon_data['usage_limit_per_user']) && $coupon_data['usage_limit_per_user'] !== '' ) {
                $coupon->set_usage_limit_per_user( absint($coupon_data['usage_limit_per_user']) );
            }
            if ( isset($coupon_data['limit_usage_to_x_items']) && $coupon_data['limit_usage_to_x_items'] !== '' ) {
                $coupon->set_limit_usage_to_x_items( absint($coupon_data['limit_usage_to_x_items']) );
            }
            if ( !empty($coupon_data['date_expires']) ) {
                $expires = self::parse_date($coupon_data['date_expires']);
                if ( $expires ) {
                    $coupon->set_date_expires( $expires );
                }
            }
        }
        
        if ( (empty($update_fields) || in_array('custom_fields', $update_fields)) && !empty($coupon_data['meta']) && is_array($coupon_data['meta']) ) {
            foreach ( $coupon_data['meta'] as $key => $value ) {
                update_post_meta( $coupon_id, sanitize_key($key), $value );
            }
        }
        
        $coupon->save();
    }

    /**
     * Parse comma-separated IDs.
     * Uses ImportMapper::normalize_list() for consistency with product imports.
     *
     * @param mixed $value Value to parse (string or array).
     * @return array Array of integer IDs.
     */
    private static function parse_ids( $value ) {
        // Use normalize_list from ImportMapper for consistent parsing
        $list = \PrimeLink\Modules\Imports\Service\ImportMapper::normalize_list( $value );
        // Convert to integers and filter out invalid values
        return array_filter( array_map( 'absint', $list ) );
    }

    /**
     * Parse comma-separated emails.
     * Uses ImportMapper::normalize_list() for consistency with product imports.
     *
     * @param mixed $value Value to parse (string or array).
     * @return array Array of sanitized email addresses.
     */
    private static function parse_emails( $value ) {
        // Use normalize_list from ImportMapper for consistent parsing
        $list = \PrimeLink\Modules\Imports\Service\ImportMapper::normalize_list( $value );
        // Sanitize emails and filter out invalid values
        $emails = array_map( 'sanitize_email', $list );
        return array_filter( $emails, 'is_email' );
    }

    /**
     * Parse date string to timestamp.
     *
     * @param string $date_string Date string.
     * @return int|false Timestamp or false on failure.
     */
    private static function parse_date( $date_string ) {
        return \PrimeLink\Helpers\DateHelper::parse_to_timestamp( $date_string );
    }
}

