<?php

defined( 'ABSPATH' ) || exit;
if ( !class_exists( 'WPSE_EDD_Downloads_Sheet' ) ) {
    class WPSE_EDD_Downloads_Sheet extends WPSE_Sheet_Factory {
        public $variable_prices_key = 'edd_variable_prices';

        public $files_key = 'edd_download_files';

        public $existing_values_pre_saving = array();

        function __construct() {
            $allowed_columns = array();
            $allowed_columns = array(
                'ID',
                'post_title',
                'post_content',
                'post_status',
                'post_name',
                'view_post',
                '_thumbnail_id',
                'edd_price',
                'edd_download_files_file',
                'edd_download_files_name'
            );
            parent::__construct( array(
                'fs_object'          => wpseedd_fs(),
                'post_type'          => array('download'),
                'post_type_label'    => array('EDD Downloads'),
                'serialized_columns' => array(),
                'columns'            => array($this, 'get_columns'),
                'allowed_columns'    => $allowed_columns,
                'remove_columns'     => array(),
            ) );
            add_action( 'vg_sheet_editor/initialized', array($this, 'after_init') );
            add_filter(
                'vg_sheet_editor/provider/post/update_item_meta',
                array($this, 'filter_cell_data_for_saving'),
                10,
                3
            );
            add_filter(
                'vg_sheet_editor/provider/post/get_item_meta',
                array($this, 'filter_cell_data_for_readings'),
                10,
                5
            );
            add_filter(
                'vg_sheet_editor/serialized_addon/column_settings',
                array($this, 'filter_serialized_column_settings'),
                10,
                5
            );
            add_filter(
                'vg_sheet_editor/columns/blacklisted_columns',
                array($this, 'blacklist_index_column'),
                10,
                2
            );
            add_filter( 'vg_sheet_editor/options_page/options', array($this, 'add_settings_page_options') );
            add_filter(
                'vg_sheet_editor/infinite_serialized_column/column_settings',
                array($this, 'filter_serialized_column_settings_2'),
                10,
                3
            );
            add_filter(
                'vg_sheet_editor/infinite_serialized_column/existing_value',
                array($this, 'modify_existing_value'),
                10,
                3
            );
            add_filter(
                'vg_sheet_editor/infinite_serialized_column/update_value',
                array($this, 'modify_value_for_saving'),
                10,
                3
            );
            add_filter( 'vg_sheet_editor/infinite_serialized_column/settings', array($this, 'modify_infinite_serialized_settings') );
            add_filter( 'vg_sheet_editor/import/save_rows_args', array($this, 'move_edd_files_to_end') );
        }

        /**
         * Moves columns starting with 'edd_download_files' to the end of the import data because they reference prices so the files should be saved last
         *
         * @param array $args The arguments array passed to save_rows.
         * @return array The modified arguments.
         */
        public function move_edd_files_to_end( $args ) {
            // 1. Check if the post type is 'download' (EDD)
            if ( !isset( $args['post_type'] ) || 'download' !== $args['post_type'] ) {
                return $args;
            }
            // 2. Check if there is data to process
            if ( empty( $args['data'] ) || !is_array( $args['data'] ) ) {
                return $args;
            }
            // 3. Iterate through rows to reorder columns
            foreach ( $args['data'] as $row_index => $row ) {
                $standard_columns = array();
                $file_columns = array();
                $found_target = false;
                foreach ( $row as $key => $value ) {
                    // Check if key starts with the target prefix
                    if ( strpos( $key, $this->files_key ) === 0 ) {
                        $file_columns[$key] = $value;
                        $found_target = true;
                    } else {
                        $standard_columns[$key] = $value;
                    }
                }
                // Only reconstruct the row if we actually found target columns
                if ( $found_target ) {
                    // Merge standard columns first, followed by file columns
                    $args['data'][$row_index] = array_merge( $standard_columns, $file_columns );
                }
            }
            return $args;
        }

        function after_init() {
            if ( empty( VGSE()->options['keys_for_infinite_serialized_handler'] ) ) {
                VGSE()->options['keys_for_infinite_serialized_handler'] = '';
            }
            if ( strpos( VGSE()->options['keys_for_infinite_serialized_handler'], $this->variable_prices_key ) === false ) {
                VGSE()->options['keys_for_infinite_serialized_handler'] .= ',' . $this->variable_prices_key;
            }
            if ( strpos( VGSE()->options['keys_for_infinite_serialized_handler'], $this->files_key ) === false ) {
                VGSE()->options['keys_for_infinite_serialized_handler'] .= ',' . $this->files_key;
            }
        }

        function modify_infinite_serialized_settings( $settings ) {
            if ( $settings['sample_field_key'] === $this->variable_prices_key ) {
                foreach ( $settings['sample_values'] as $index => $sample_value ) {
                    $settings['sample_values'][$index] = $this->modify_existing_value( $sample_value, null, $this->variable_prices_key );
                }
                $settings['sample_field'] = current( $settings['sample_values'] );
            }
            if ( $settings['sample_field_key'] === $this->files_key ) {
                foreach ( $settings['sample_values'] as $index => $sample_value ) {
                    $settings['sample_values'][$index] = $this->modify_existing_value( $sample_value, null, $this->files_key );
                }
                $settings['sample_field'] = current( $settings['sample_values'] );
            }
            return $settings;
        }

        function fix_indices_before_saving( $value, $post_id, $key ) {
            $existing_values = VGSE()->helpers->get_with_dot_notation( $this->existing_values_pre_saving, $post_id . '.' . $key );
            if ( !is_array( $existing_values ) ) {
                $existing_value = get_post_meta( $post_id, $key, true );
                if ( !is_array( $existing_value ) ) {
                    $existing_value = array();
                }
                $existing_values = array_values( $existing_value );
                VGSE()->helpers->set_with_dot_notation( $this->existing_values_pre_saving, $post_id . '.' . $key, $existing_values );
            }
            $value = array_values( $value );
            $new_value = array();
            foreach ( $value as $index => $single_value ) {
                $default_index = $index + 1;
                $new_index = ( isset( $existing_values[$index] ) && isset( $existing_values[$index]['index'] ) ? $existing_values[$index]['index'] : $default_index );
                $single_value['index'] = $new_index;
                $new_value[$new_index] = $single_value;
            }
            $value = $new_value;
            return $value;
        }

        function modify_value_for_saving( $value, $post_id, $key ) {
            if ( $key === $this->variable_prices_key ) {
                $value = $this->fix_indices_before_saving( $value, $post_id, $key );
                // Auto enable variable pricing if we're saving variable prices
                if ( !empty( $value ) ) {
                    update_post_meta( $post_id, '_variable_pricing', 1 );
                }
            }
            if ( $key === $this->files_key ) {
                $value = $this->fix_indices_before_saving( $value, $post_id, $key );
                $default_file_values = array(
                    'index'          => '',
                    'attachment_id'  => '',
                    'thumbnail_size' => '',
                    'name'           => '',
                    'file'           => '',
                    'condition'      => 'all',
                );
                $variable_prices = get_post_meta( $post_id, $this->variable_prices_key, true );
                if ( !is_array( $variable_prices ) ) {
                    $variable_prices = array();
                }
                foreach ( $value as $index => $file ) {
                    $value[$index] = array_merge( $default_file_values, $file );
                    if ( empty( $file['condition'] ) ) {
                        $value[$index]['condition'] = 'all';
                        $file['condition'] = 'all';
                    }
                    if ( !is_numeric( $file['condition'] ) && $file['condition'] !== 'all' && !empty( $variable_prices ) && ($price = wp_list_filter( $variable_prices, array(
                        'name' => $file['condition'],
                    ) )) ) {
                        $value[$index]['condition'] = current( $price )['index'];
                    }
                }
            }
            return $value;
        }

        function modify_existing_value( $value, $post_id, $key ) {
            if ( $key === $this->variable_prices_key ) {
                if ( is_array( $value ) ) {
                    $value = array_values( $value );
                    foreach ( $value as $index => $single_value ) {
                        if ( isset( $value[$index]['index'] ) ) {
                            unset($value[$index]['index']);
                        }
                    }
                }
            }
            if ( $key === $this->files_key && is_array( $value ) ) {
                $value = array_values( $value );
                foreach ( $value as $index => $single_value ) {
                    if ( isset( $value[$index]['index'] ) ) {
                        unset($value[$index]['index']);
                    }
                    if ( isset( $single_value['condition'] ) && is_numeric( $single_value['condition'] ) ) {
                        $prices = VGSE()->helpers->get_current_provider()->get_item_meta(
                            $post_id,
                            $this->variable_prices_key,
                            true,
                            'save',
                            true
                        );
                        if ( is_array( $prices ) && isset( $prices[(int) $single_value['condition']] ) ) {
                            $value[$index]['condition'] = $prices[$single_value['condition']]['name'];
                        }
                    }
                }
            }
            return $value;
        }

        function filter_serialized_column_settings_2( $column_settings, $infinite_serializer, $post_type ) {
            if ( !in_array( $post_type, $this->post_type, true ) ) {
                return $column_settings;
            }
            if ( strpos( $column_settings['key'], $this->variable_prices_key ) !== false ) {
                $column_settings['title'] = str_replace( 'Edd Variable Prices', 'Variable Price', $column_settings['title'] );
            }
            if ( strpos( $column_settings['key'], 'edd_download_files' ) !== false ) {
                $column_settings['title'] = preg_replace( '/^Edd Download Files : (\\d+) : Condition$/', 'Files: Required price: $1', $column_settings['title'] );
                $column_settings['title'] = preg_replace( '/^Edd Download Files : (\\d+) : Name$/', 'Files: Name: $1', $column_settings['title'] );
                $column_settings['title'] = preg_replace( '/^Edd Download Files : (\\d+) : File$/', 'Files: File: $1', $column_settings['title'] );
            }
            return $column_settings;
        }

        function blacklist_index_column( $columns, $provider ) {
            if ( in_array( $provider, $this->post_type ) ) {
                $columns = array_merge( $columns, array(
                    // Blacklist the columns for the file index 0, because EDD saves the files starting with index 1
                    'edd_download_files_\\d+=index',
                    'edd_download_files_\\d+=attachment_id',
                    'edd_download_files_\\d+=thumbnail_size',
                    'edd_variable_prices_\\d+=index',
                ) );
            }
            return $columns;
        }

        /**
         * Add fields to options page
         * @param array $sections
         * @return array
         */
        function add_settings_page_options( $sections ) {
            $fields = array();
            $sections[] = array(
                'icon'   => 'el-icon-cogs',
                'title'  => esc_html__( 'EDD sheet', vgse_edd_downloads()->textname ),
                'fields' => $fields,
            );
            return $sections;
        }

        function filter_serialized_column_settings(
            $settings,
            $first_set_keys,
            $field,
            $key,
            $post_type
        ) {
            if ( !in_array( $post_type, $this->post_type ) ) {
                return $settings;
            }
            return $settings;
        }

        function filter_cell_data_for_readings(
            $value,
            $id,
            $key,
            $single,
            $context
        ) {
            if ( $context !== 'read' || !in_array( get_post_type( $id ), $this->post_type ) ) {
                return $value;
            }
            return $value;
        }

        function filter_cell_data_for_saving( $new_value, $id, $key ) {
            if ( !in_array( get_post_type( $id ), $this->post_type ) ) {
                return $new_value;
            }
            return $new_value;
        }

        function get_columns() {
            $settings = get_option( VGSE()->options_key, array() );
            $columns = array();
            $columns['_variable_pricing'] = array(
                'data_type'         => 'meta_data',
                'title'             => esc_html__( 'Variable pricing', vgse_edd_downloads()->textname ),
                'allow_to_save'     => true,
                'supports_formulas' => true,
                'allow_to_hide'     => true,
                'allow_to_rename'   => true,
                'formatted'         => array(
                    'type'              => 'checkbox',
                    'checkedTemplate'   => '1',
                    'uncheckedTemplate' => '',
                ),
                'default_value'     => '',
            );
            $columns['_edd_download_sales'] = array(
                'data_type' => 'meta_data',
                'title'     => esc_html__( 'Sales', vgse_edd_downloads()->textname ),
                'is_locked' => true,
            );
            $columns['_edd_download_earnings'] = array(
                'data_type' => 'meta_data',
                'title'     => esc_html__( 'Earnings', vgse_edd_downloads()->textname ),
                'is_locked' => true,
            );
            $serialized_fields = array();
            $serialized_fields[] = array(
                'sample_field_key'               => '_edd_bundled_products',
                'sample_field'                   => array(''),
                'column_width'                   => 150,
                'column_title_prefix'            => esc_html__( 'Bundle product', vgse_edd_downloads()->textname ),
                'level'                          => ( !empty( $settings['edd_max_bundle_products'] ) ? (int) $settings['edd_max_bundle_products'] : 3 ),
                'allowed_post_types'             => array(vgse_edd_downloads()->post_type),
                'is_single_level'                => true,
                'allow_in_wc_product_variations' => false,
                'wpse_source'                    => 'edd_sheet',
            );
            $serialized_fields[] = array(
                'sample_field_key'               => '_edd_bundled_products_conditions',
                'sample_field'                   => array(''),
                'column_width'                   => 150,
                'column_title_prefix'            => esc_html__( 'Bundle required price', vgse_edd_downloads()->textname ),
                'level'                          => ( !empty( $settings['edd_max_bundle_products'] ) ? (int) $settings['edd_max_bundle_products'] : 3 ),
                'allowed_post_types'             => array(vgse_edd_downloads()->post_type),
                'is_single_level'                => true,
                'allow_in_wc_product_variations' => false,
                'wpse_source'                    => 'edd_sheet',
            );
            foreach ( $serialized_fields as $serialized_field ) {
                // Very late init, so we can overwrite the automatic custom columns
                $serialized_field['column_init_priority'] = 80;
                new WP_Sheet_Editor_Serialized_Field($serialized_field);
            }
            return $columns;
        }

    }

    new WPSE_EDD_Downloads_Sheet();
}