<?php

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

/**
 * Get the supported product types
 */
function mdspbe_get_supported_product_types( $with_labels = false, $with_variation = true ) {

    $supported_types = ['simple', 'variable', 'external', 'grouped'];
    if ( $with_variation === true ) {
        $supported_types[] = 'variation';
    }

    if ( $with_labels === true ) {
        $product_types = wc_get_product_types();
    
        $assoc_supp_types = [];
        foreach ( $product_types as $key => $label ) {
            if ( in_array( $key, $supported_types, true ) ) {
                $assoc_supp_types[$key] = $label;
            }
        }

        return $assoc_supp_types;
    } 

    return $supported_types;
    
}

/**
 * Sanitize edit option data
 */
function mdspbe_sanitize_option_data( $data ) {
    $edit_opts = mdspbe_get_attr_edit_options();
    $sanitized_data = [];

    foreach ( $data as $key => $value ) {
        if ( $key === 'id' ) {
            continue;
        }
        $sanitize_func = $edit_opts[$data['id']]['add']['fields'][$key]['sanitize'];

        if ( $sanitize_func && function_exists( $sanitize_func ) ) {
            $sanitized_data[$key] = $sanitize_func( $value );
        } else {
            $sanitized_data[$key] = sanitize_text_field( $value );
        }
    }

    return $sanitized_data;
}


/**
 * Sanitize fields
 */
function mdspbe_sanitize_fields( $array ) {
    $attributes = mdspbe_get_products_attributes();

    foreach ( $array as $key_1 => $values ) {
        foreach ( $values as $key_2 => $value) {
            $sanitize_func = $attributes[$key_2]['sanitize'];
            if ( function_exists( $sanitize_func ) ) {
                $array[$key_1][$key_2] = $sanitize_func( $value );
            } else {
                $array[$key_1][$key_2] = sanitize_text_field( $value );
            }
        }
    }
    return $array;
}


/**
 * Floatval or empty ''
 */
function mdspbe_floatval( $value ) {
    if ( ! $value ) {
        return '';
    }

    return floatval( $value );
}


/**
 * Intval or empty ''
 */
function mdspbe_intval( $value ) {
    if ( ! $value ) {
        return '';
    }

    return intval( $value );
}


/**
 * Custom boolval function
 */
function mdspbe_boolval( $value ) {
    $bool = in_array( strtolower( $value ), ['1', 'true', 'yes', 1, true], true );
    return $bool;
}


/**
 * Get all active attributes
 */
function mdspbe_get_active_attribute_keys() {
    $active_attributes = get_user_meta( get_current_user_id(), '_mdspbe_active_attributes', true ) ?: 
        ['name', 'regular_price', 'stock_status', 'visibility', 'categories', 'status'];

    // Add the attributes that comes together
    // Ie. stock quantity with manage stock
    $attributes = mdspbe_get_products_attributes();
    foreach ( $active_attributes as $active_attribute ) {
        if ( isset( $attributes[$active_attribute] ) && isset( $attributes[$active_attribute]['attrs_needed'] ) ) {
            $active_attributes = array_merge( $active_attributes, $attributes[$active_attribute]['attrs_needed'] );
        }
    }

    return array_unique( $active_attributes );
}


/**
 * Get all categories
 */
function mdspbe_get_categories() {

    static $results;
    if ( $results ) {
        return $results;
    }

    $categories = get_terms( [
        'taxonomy'   => 'product_cat',
        'hide_empty' => false,
    ] );

    // Sort categories by name (case-insensitive)
    usort( $categories, function( $a, $b ) {
        return strcasecmp( $a->name, $b->name );
    } );

    $results = [];

    foreach ( $categories as $cat ) {
        $results[$cat->term_id] = $cat->name;
    }

    return $results;
}


/**
 * Add a category
 */
function mdspbe_add_category( $data ) {

    $data = mdspbe_sanitize_option_data( $data );

    $name = isset( $data['name'] ) ? $data['name'] : '';
    
    $args = [
            'description' => isset( $data['description'] ) ? $data['description'] : '',
            'parent'      => isset( $data['parent'] ) ? $data['parent'] : 0
        ];
    $args = apply_filters( 'mdspbe_add_category_args', $args );

    $result = wp_insert_term(
        $name,
        'product_cat',
        $args
    );

    if ( ! is_wp_error( $result ) ) {
        $response = [
            'id' => $result['term_id'],
            'name' => $name,
        ];
        return $response;
    } else {
        return null;
    }  
}


/**
 * Remove a category
 */
function mdspbe_remove_categories( $data ) {
    
    $response = true;
    $ids = $data['value_1'];
    foreach ( $ids as $id ) {
        $result = wp_delete_term( absint( $id ), 'product_cat' );
        if ( ! $result ) {
            $response = false;
        }
    }
    
    return $response;
}


/**
 * Get all tags
 */
function mdspbe_get_tags() {

    static $results;
    if ( $results ) {
        return $results;
    }

    $tags = get_terms( [
        'taxonomy'   => 'product_tag',
        'hide_empty' => false,
    ] );

    // Sort tags by name (case-insensitive)
    usort( $tags, function( $a, $b ) {
        return strcasecmp( $a->name, $b->name );
    } );

    $results = [];

    foreach ( $tags as $tag ) {
        $results[$tag->term_id] = $tag->name;
    }

    return $results;
}



/**
 * Add a tag
 */
function mdspbe_add_tag( $data ) {

    $data = mdspbe_sanitize_option_data( $data );

    $name = isset( $data['name'] ) ? $data['name'] : '';
    
    $args = [
            'description' => isset( $data['description'] ) ? $data['description'] : '',
        ];
    $args = apply_filters( 'mdspbe_add_tag_args', $args );

    $result = wp_insert_term(
        $name,
        'product_tag',
        $args
    );

    if ( ! is_wp_error( $result ) ) {
        $response = [
            'id' => $result['term_id'],
            'name' => $name,
        ];
        return $response;
    } else {
        return null;
    }  
}


/**
 * Remove tags
 */
function mdspbe_remove_tags( $data ) {
    
    $response = true;
    $ids = $data['value_1'];
    foreach ( $ids as $id ) {
        $result = wp_delete_term( absint( $id ), 'product_tag' );
        if ( ! $result ) {
            $response = false;
        }
    }
    
    return $response;
}


/**
 * Get all attribute options
 */
function mdspbe_get_attr_options( $attr_name ) {

    static $results = [];
    if ( isset( $results[$attr_name] ) ) {
        return $results[$attr_name];
    }

    $opts = get_terms( [
        'taxonomy'   => 'pa_' . $attr_name,
        'hide_empty' => false,
    ] );

    // Sort options by name (case-insensitive)
    usort( $opts, function( $a, $b ) {
        return strcasecmp( $a->name, $b->name );
    } );

    $results[$attr_name] = [];

    foreach ( $opts as $opt ) {
        $results[$attr_name][$opt->term_id] = $opt->name;
    }

    return $results[$attr_name];
}



/**
 * Add an attribute option
 */
function mdspbe_add_attr_option( $data, $attr_name ) {

    $data = mdspbe_sanitize_option_data( $data );

    $name = isset( $data['name'] ) ? $data['name'] : '';
    
    $args = [
            'description' => isset( $data['description'] ) ? $data['description'] : '',
        ];
    $args = apply_filters( 'mdspbe_add_attr_option_args', $args );

    $result = wp_insert_term(
        $name,
        'pa_' . $attr_name,
        $args
    );

    if ( ! is_wp_error( $result ) ) {
        $response = [
            'id' => $result['term_id'],
            'name' => $name,
        ];
        return $response;
    } else {
        return null;
    }  
}


/**
 * Remove attr options
 */
function mdspbe_remove_attr_options( $data, $attr_name ) {
    
    $response = true;
    $ids = $data['value_1'];
    foreach ( $ids as $id ) {
        $result = wp_delete_term( absint( $id ), 'pa_' . $attr_name );
        if ( ! $result ) {
            $response = false;
        }
    }
    
    return $response;
}


/**
 * Get all attr options of an specific product
 */
function mdspbe_get_attribute_ids( $product, $attr_name ) {
    $attributes = $product->get_attributes();

    if ( isset( $attributes['pa_' . $attr_name] ) ) {
        return $attributes['pa_' . $attr_name]['data']['options'];
    }

    return [];
}


/**
 * Set attr options to a product
 */
function mdspbe_set_attribute_ids( $product, $term_ids, $attr_name ) {
    
    // Set terms in WP taxonomy
    wp_set_object_terms( $product->get_id(), $term_ids, 'pa_' . $attr_name );

    // Build the attribute object
    $attribute = new WC_Product_Attribute();
    $attribute->set_id( wc_attribute_taxonomy_id_by_name( 'pa_' . $attr_name ) );
    $attribute->set_name( 'pa_' . $attr_name );
    $attribute->set_options( $term_ids );
    $attribute->set_visible(true);
    $attribute->set_variation(true); // if used for variations

    // Merge with existing attributes
    $attributes = $product->get_attributes();
    $attributes['pa_' . $attr_name] = $attribute;

    $product->set_attributes( $attributes );

}


/**
 * Get all product statuses
 */
function mdspbe_get_product_statuses() {
    
    $statuses = [
        'publish' => esc_html__( 'Published', 'mds-product-bulk-editor-for-woocommerce' ),
        'pending' => esc_html__( 'Pending Review', 'mds-product-bulk-editor-for-woocommerce' ),
        'draft'   => esc_html__( 'Draft', 'mds-product-bulk-editor-for-woocommerce' ),
        'trash'   => esc_html__( 'Trashed', 'mds-product-bulk-editor-for-woocommerce' )
    ];

    return $statuses;

}


/**
 * Get tax classes
 */
function mdspbe_get_product_tax_classes() {

    static $tax_classes;
    if ( $tax_classes ) {
        return $tax_classes;
    }
    
    // This is mainly for backward compatiblity across WC versions
    try {
        $method = new ReflectionMethod( 'WC_Tax', 'get_tax_rate_classes' );
        if ( $method->isPublic() ) {
            // Safe to call directly
            $tax_class_objects = WC_Tax::get_tax_rate_classes();

            $tax_classes = [
                '' => esc_html__( 'Standard', 'mds-product-bulk-editor-for-woocommerce' )
            ];
            foreach ( $tax_class_objects as $object ) {
                $tax_classes[$object->slug] = $object->name;
            }
        
            return $tax_classes;
        } else {
            return [];
        }
    } catch ( ReflectionException $e ) {
        // Method doesn't exist at all in this version
    }

}


/**
 * Get shipping classes
 */
function mdspbe_get_shipping_classes() {

    static $shipping_classes;
    if ( $shipping_classes ) {
        return $shipping_classes;
    }

    $shipping_classes = WC()->shipping()->get_shipping_classes();
    return $shipping_classes;
}


/**
 * Get bool options
 */
function mdspbe_get_bool_options() {
    
    $options = [
        'yes' => esc_html__( 'Yes', 'mds-product-bulk-editor-for-woocommerce' ),
        'no' => esc_html__( 'No', 'mds-product-bulk-editor-for-woocommerce' )
    ];

    return $options;

}


/**
 * Format bools to string
 */
function mdspbe_format_bool( $value ) {
    
    if ( $value === false || $value == '0' || $value === '' ) {
        $value = 'no';
    } elseif ( $value === true || $value == '1' ) {
        $value = 'yes';
    }

    return $value;
    
}


/**
 * Get the product type label
 */
function mdspbe_get_product_type_label( $product_type ) {

    $product_types = wc_get_product_types();
    if ( $product_type === 'variation' ) {
        $label = esc_html__( 'Variation',  'mds-product-bulk-editor-for-woocommerce' );
    } else {
        $label = isset( $product_types[ $product_type ] ) ? $product_types[ $product_type ] : ucfirst( $product_type );
    }

    $label = apply_filters( 'mdspbe_product_type_label', $label );
    
    return $label;
}


/**
 * Get product value
 */
function mdspbe_get_value( $product, $input_data ) {
    if ( ! $product ) {
        $raw_value = isset( $input_data['default'] ) ? $input_data['default'] : '';
    } elseif ( ! empty( $input_data['is_meta'] ) ) {
        if ( is_array( $input_data['meta_key'] ) ) {
            // Support for different meta keys by product type
            $product_type = $product->get_type();
            if ( ! empty( $input_data['meta_key'][$product_type] ) ) {
                $meta_key = $input_data['meta_key'][$product_type];
                $raw_value = $product->get_meta( $meta_key );
            }
        } else {
            $raw_value = $product->get_meta( $input_data['meta_key'] );
        }

        if ( ! empty( $input_data['format_get'] ) ) {
            $format_get_callback = $input_data['format_get'];
            if ( function_exists( $format_get_callback ) ) {
                $raw_value = $format_get_callback( $raw_value );
            }
        }
    } else {
        $get = $input_data['get'];

        if ( isset( $input_data['are_get_set_functs'] ) && $input_data['are_get_set_functs'] === true && function_exists( $get ) ) {

            if ( isset( $input_data['callbacks_param'] ) ) {
                $raw_value = $get( $product, $input_data['callbacks_param'] );
            } else {
                $raw_value = $get( $product );
            }
            
        } elseif ( method_exists( $product, $get ) ) {
            $raw_value = $product->$get( 'edit' );

        } else {
            return new WP_Error( 'invalid_field', esc_html__( 'Invalid field for the current Woocommerce version',  'mds-product-bulk-editor-for-woocommerce' ), ["status" => 400] );
        }

        if ( ! empty( $input_data['format_get'] ) ) {
            $format_get_callback = $input_data['format_get'];
            if ( function_exists( $format_get_callback ) ) {
                $raw_value = $format_get_callback( $raw_value );
            }
        }
    }
    
    if ( ! empty( $input_data['multiple'] ) ) {

        if ( $product ) {

            // Safety check to avoid errors when we get '' as raw value
            if ( ! is_array( $raw_value ) ) {
                $raw_value = [];
            }
            return $raw_value;

        } else {
            return [];
        }

        return $product ? $raw_value : []; // This is for when creating a new product (empty row)
    } else {
        return $raw_value;
    }
}


/**
 * Map absint function
 */
function mdspbe_map_absint( $array ) {
    $array = array_map( 'absint', $array );
    return $array;
}


/**
 * Duplicate product
 */
function mdspbe_duplicate_product( $product_id ) {
    $get_product_func = mdspbe_get_product_function_name();
    $product = $get_product_func( $product_id );
    
    ( new WC_Admin_Duplicate_Product() )->product_duplicate( $product );
}


/**
 * Trash product
 */
function mdspbe_trash_product( $product_id ) {
    wp_trash_post( $product_id );
}


/**
 * Untrash product
 */
function mdspbe_untrash_product( $product_id ) {
    wp_untrash_post( $product_id );
}


/**
 * Delete product
 */
function mdspbe_delete_product( $product_id ) {
    wp_delete_post( $product_id, true );
}


/**
 * Convert local date into UTC timestamp
 */
function mdspbe_date_to_utc_timestamp( $date_str ) {

    if ( ! $date_str ) {
        return null;
    } 

    // Create DateTime object with local time
    $datetime = new DateTime( $date_str, wp_timezone() );

    // Convert to UTC
    $datetime->setTimezone( new DateTimeZone('UTC') );

    // Get Unix timestamp
    $timestamp = $datetime->getTimestamp();

    return $timestamp;
}


/**
 * Format UTC date into local date
 */
function mdspbe_utc_date_to_local_date( $utc_date_object ) {
    
    if ( ! $utc_date_object ) {
        return '';
    } 

    $local_date_str = $utc_date_object->date_i18n();

    return $local_date_str;
}


/**
 * Format date time string into local date time
 */
function mdspbe_date_string_to_local_date( $date_raw ) {
    
    if ( ! $date_raw ) {
        return '';
    } 

    if ( is_string( $date_raw ) ) {
        return $date_raw;
    }

    try {
        // Convert to string with local timezone + formatting
        $formatted_date = wp_date(
            get_option('date_format') . ' ' . get_option('time_format'),
            $date_raw->getTimestamp()
        );
        return $formatted_date;
    }
    catch (Exception $e) {
		return '';
	}
    

    
}
