<?php

namespace Wpai\AddonAPI;

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

class PMXI_Addon_Post_Data_Importer extends PMXI_Addon_Data_Importer {

    public function get_record( $post_id ) {
        return get_post( $post_id );
    }

    public function get_record_title( $articleData ) {
        return $articleData['post_title'];
    }

    public function get_record_meta( $post_id ) {
        return get_post_meta( $post_id );
    }

	public function upsert( $articleData, $custom_type_details ) {
		$articleTitle = $this->get_record_title( $articleData );
		$labelName = $custom_type_details->labels->singular_name ?? $custom_type_details->labels->name ?? '';

		if ( empty( $articleData['ID'] ) ) {
			/* translators: 1: article title, 2: post type label */
			$this->logger( sprintf( __( '<b>CREATING</b> `%1$s` `%2$s`', 'wp-all-import' ), $articleTitle, $labelName ) );
		} else {
			/* translators: 1: article title, 2: post type label */
			$this->logger( sprintf( __( '<b>UPDATING</b> `%1$s` `%2$s`', 'wp-all-import' ), $articleTitle, $labelName ) );
		}

		return ( empty( $articleData['ID'] ) ) ? wp_insert_post( $articleData, true ) : wp_update_post( $articleData, true );
	}

    public function update_content( $post_id, $content ) {
        wp_update_post( [
            'ID'           => $post_id,
            'post_content' => $content
        ] );
    }

    public function update_meta( $post_id, $meta_key, $meta_value ) {
        update_post_meta( $post_id, $meta_key, $meta_value );

        /* translators: 1: post ID, 2: custom field key, 3: custom field value */
        $this->logger( sprintf( __( 'Instead of deletion post with ID `%1$s`, set Custom Field `%2$s` to value `%3$s`', 'wp-all-import' ), $post_id, $meta_key, $meta_value ) );
    }

    public function move_missing_record_to_trash( $missing_post_id ) {
        if ( $final_post_type = get_post_type( $missing_post_id ) and 'trash' != get_post_status( $missing_post_id ) ) {
            wp_trash_post( $missing_post_id );
            $this->record->recount_terms( $missing_post_id, $final_post_type );
            /* translators: %s: post ID */
            $this->logger( sprintf( __( 'Instead of deletion, change post with ID `%s` status to trash', 'wp-all-import' ), $missing_post_id ) );
        }
    }

    public function change_post_status_to_draft( $missing_post_id ) {
        if ( $final_post_type = get_post_type( $missing_post_id ) and $this->options['status_of_removed'] != get_post_status( $missing_post_id ) ) {
            $this->wpdb->update( $this->wpdb->posts, array( 'post_status' => $this->options['status_of_removed'] ), array( 'ID' => $missing_post_id ) );
            $this->record->recount_terms( $missing_post_id, $final_post_type );
            /* translators: 1: post ID, 2: new post status */
            $this->logger( sprintf( __( 'Instead of deletion, change post with ID `%1$s` status to %2$s', 'wp-all-import' ), $missing_post_id, $this->options['status_of_removed'] ) );
        }
    }

    public function change_post_status( $post_id, $new_status ) {
        if ( $final_post_type = get_post_type( $post_id ) and $new_status != get_post_status( $post_id ) ) {
            $this->wpdb->update( $this->wpdb->posts, array( 'post_status' => $new_status ), array( 'ID' => $post_id ) );
            $this->record->recount_terms( $post_id, $final_post_type );
            /* translators: 1: post ID, 2: new post status */
            $this->logger( sprintf( __( 'Instead of deletion, change post with ID `%1$s` status to %2$s', 'wp-all-import' ), $post_id, $new_status ) );
        }
    }

    public function delete_record_not_present_in_file( $missing_post_id ) {
        // Trigger pre delete hook.
        do_action( 'pmxi_before_delete_post', $missing_post_id, $this->record );

        // Remove attachments
        if ( ! empty( $this->options['is_delete_attachments'] ) ) {
            wp_delete_attachments( $missing_post_id, true, 'files' );
        }

        // Remove images
        if ( ! empty( $this->options['is_delete_imgs'] ) ) {
            wp_delete_attachments( $missing_post_id, true, 'images' );
        }

        // Clear post's relationships
        wp_delete_object_term_relationships( $missing_post_id, get_object_taxonomies( '' != $this->options['custom_type'] ? $this->options['custom_type'] : 'post' ) );
    }

    public function delete_records( $ids ) {
        do_action( 'pmxi_delete_post', $ids, $this->record );

        foreach ( $ids as $id ) {
            wp_delete_post( $id, true );
        }
    }

    public function combine_data( $data ) {
        extract( $data );

        // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
        $articleData = apply_filters( 'wp_all_import_combine_article_data', array(
            'post_type'      => $post_type,
            'post_status'    => ( "xpath" == $this->options['status'] ) ? $post_status : $this->options['status'],
            'comment_status' => ( "xpath" == $this->options['comment_status'] ) ? $comment_status : $this->options['comment_status'],
            'ping_status'    => ( "xpath" == $this->options['ping_status'] ) ? $ping_status : $this->options['ping_status'],
            'post_title'     => ( ! empty( $this->options['is_leave_html'] ) ) ? html_entity_decode( $title ) : $title,
            'post_excerpt'   => apply_filters( 'pmxi_the_excerpt', ( ( ! empty( $this->options['is_leave_html'] ) ) ? html_entity_decode( $post_excerpt ) : $post_excerpt ), $this->id ),
            'post_name'      => $post_slug,
            'post_content'   => apply_filters( 'pmxi_the_content', ( ( ! empty( $this->options['is_leave_html'] ) ) ? html_entity_decode( $contents ) : $contents ), $this->id ),
            'post_date'      => $date,
            'post_date_gmt'  => get_gmt_from_date( $date ),
            'post_author'    => $post_author,
            'menu_order'     => (int) $menu_order,
            'post_parent'    => ( "no" == $this->options['is_multiple_page_parent'] ) ? wp_all_import_get_parent_post( $page_parent, $post_type, $this->options['type'] ) : (int) $this->options['parent'],
            'page_template'  => ( "no" == $this->options['is_multiple_page_template'] ) ? $page_template : $this->options['page_template']
        ), $this->options['custom_type'], $this->record->id, $i );
        if ( 'shop_coupon' == $post_type ) {
            $articleData['post_excerpt'] = $articleData['post_content'];
        }
        /* translators: %s: article title */
        $this->logger( sprintf( __( 'Combine all data for post `%s`...', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );

        // if ( "xpath" == $this->options['status'] )
        // {
        // 	$status_object = get_post_status_object($post_status);

        // 	if ( empty($status_object) )
        // 	{
        // 		$articleData['post_status'] = 'draft';
        /* translators: see placeholders in the string below */
        // 		$this->logger(sprintf(__('<b>WARNING</b>: Post status `%1$s` is not supported, post `%2$s` will be saved in draft.', 'wp-all-import'), $post_status, $articleData['post_title']));
        // 		$logger and !$is_cron and PMXI_Plugin::$session->warnings++;
        // 	}
        // }

        return $articleData;
    }

    public function choose_data_to_update( $post_to_update, $post_to_update_id, $post_type, $taxonomies, &$articleData, $i, &$existing_taxonomies = [] ) {
        // preserve date of already existing article when duplicate is found
        if ( ( ! $this->options['is_update_categories'] and ( is_object_in_taxonomy( $post_type, 'category' ) or is_object_in_taxonomy( $post_type, 'post_tag' ) ) ) or ( $this->options['is_update_categories'] and $this->options['update_categories_logic'] != "full_update" ) ) {
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve taxonomies of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
            $existing_taxonomies = array();
            foreach ( array_keys( $taxonomies ) as $tx_name ) {
                $txes_list = get_the_terms( $articleData['ID'], $tx_name );
                if ( is_wp_error( $txes_list ) ) {
                    /* translators: %d: article ID */
                    $this->logger( sprintf( __( '<b>WARNING</b>: Unable to get current taxonomies for article #%d, updating with those read from XML file', 'wp-all-import' ), $articleData['ID'] ) );
                    ! $this->is_cron and \PMXI_Plugin::$session->warnings ++;
                } else {
                    $txes_new = array();
                    if ( ! empty( $txes_list ) ):
                        foreach ( $txes_list as $t ) {
                            $txes_new[] = $t->term_taxonomy_id;
                        }
                    endif;
                    $existing_taxonomies[ $tx_name ][ $i ] = $txes_new;
                }
            }
        }

        if ( ! $this->options['is_update_dates'] ) { // preserve date of already existing article when duplicate is found
            $articleData['post_date']     = $post_to_update->post_date;
            $articleData['post_date_gmt'] = $post_to_update->post_date_gmt;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve date of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! $this->options['is_update_status'] ) { // preserve status and trashed flag
            $articleData['post_status'] = $post_to_update->post_status;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve status of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! $this->options['is_update_content'] ) {
            unset( $articleData['post_content'] );
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve content of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! $this->options['is_update_title'] ) {
            $articleData['post_title'] = $post_to_update->post_title;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve title of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! $this->options['is_update_slug'] ) {
            $articleData['post_name'] = $post_to_update->post_name;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve slug of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        // Check for changed slugs for published post objects and save the old slug.
        if ( ! empty( $articleData['post_name'] ) and $articleData['post_name'] != $post_to_update->post_name ) {
            $old_slugs = (array) get_post_meta( $post_to_update_id, '_wp_old_slug' );

            // If we haven't added this old slug before, add it now.
            if ( ! empty( $post_to_update->post_name ) && ! in_array( $post_to_update->post_name, $old_slugs ) ) {
                add_post_meta( $post_to_update_id, '_wp_old_slug', $post_to_update->post_name );
            }

            // If the new slug was used previously, delete it from the list.
            if ( in_array( $articleData['post_name'], $old_slugs ) ) {
                delete_post_meta( $post_to_update_id, '_wp_old_slug', $articleData['post_name'] );
            }
        }

        if ( ! $this->options['is_update_excerpt'] ) {
            $articleData['post_excerpt'] = $post_to_update->post_excerpt;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve excerpt of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! $this->options['is_update_menu_order'] ) {
            $articleData['menu_order'] = $post_to_update->menu_order;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve menu order of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! $this->options['is_update_parent'] ) {
            $articleData['post_parent'] = $post_to_update->post_parent;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve post parent of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! $this->options['is_update_post_type'] ) {
            $articleData['post_type'] = $post_to_update->post_type;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve post type of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! $this->options['is_update_comment_status'] ) {
            $articleData['comment_status'] = $post_to_update->comment_status;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve comment status of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! $this->options['is_update_ping_status'] ) {
            $articleData['ping_status'] = $post_to_update->ping_status;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve ping status of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! $this->options['is_update_author'] ) {
            $articleData['post_author'] = $post_to_update->post_author;
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Preserve post author of already existing article for `%s`', 'wp-all-import' ), $this->get_record_title( $articleData ) ) );
        }
        if ( ! wp_all_import_is_update_cf( '_wp_page_template', $this->options ) ) {
            $articleData['page_template'] = get_post_meta( $post_to_update_id, '_wp_page_template', true );
        }
    }

    public function delete_images( $post_id, $articleData, $images_bundle ) {
        $title = $this->get_record_title( $articleData );

        if ( $this->options['update_all_data'] == 'yes' or ( $this->options['update_all_data'] == 'no' and $this->options['is_update_attachments'] ) ) {
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Deleting attachments for `%s`', 'wp-all-import' ), $title ) );
            wp_delete_attachments( $post_id, ! $this->options['is_search_existing_attach'], 'files' );
        }
        // handle obsolete attachments (i.e. delete or keep) according to import settings
        if ( $this->options['update_all_data'] == 'yes' or ( $this->options['update_all_data'] == 'no' and $this->options['is_update_images'] and $this->options['update_images_logic'] == "full_update" ) ) {
            /* translators: %s: article title */
            $this->logger( sprintf( __( 'Deleting images for `%s`', 'wp-all-import' ), $title ) );
            if ( ! empty( $images_bundle ) ) {
                foreach ( $images_bundle as $slug => $bundle_data ) {
                    $option_slug = ( $slug == 'pmxi_gallery_image' ) ? '' : $slug;
                    if ( count( $images_bundle ) > 1 && $slug == 'pmxi_gallery_image' ) {
                        continue;
                    }
                    $do_not_remove_images = ( $this->options[ $option_slug . 'download_images' ] == 'gallery' or $this->options[ $option_slug . 'do_not_remove_images' ] ) ? false : true;
                    $missing_images       = wp_delete_attachments( $post_id, $do_not_remove_images, 'images' );
                }
            }
        }

        return $missing_images ?? [];
    }

    public function delete_image_custom_field( $post_id, $meta_key ) {
        $this->delete_meta( $post_id, $meta_key );
    }

    public function delete_meta( $post_id, $meta_key ) {
        delete_post_meta( $post_id, $meta_key );
    }

    public function get_missing_records( $ids, $missing_status, $missing_cf ) {
        $args  = array();
        $query = "SELECT ID as post_id FROM " . $this->wpdb->prefix . "posts";
        if ( ! empty( $missing_cf ) ) {
            foreach ( $missing_cf as $key => $cf ) {
                if ( ! empty( $cf['name'] ) ) {
                    $alias  = "pm" . (int) $key;
                    $query .= " LEFT JOIN " . $this->wpdb->prefix . "postmeta AS " . $alias . " ON (" . $this->wpdb->prefix . "posts.ID = " . $alias . ".post_id AND " . $alias . ".meta_key = %s)";
                    $args[] = $cf['name'];
                }
            }
        }
        if ( $this->options['custom_type'] == 'product' ) {
            $query .= " WHERE post_type IN (\"product\", \"product_variation\")";
        } else {
            $query .= " WHERE post_type = %s";
            $args[] = $this->options['custom_type'];
        }
        $query .= " AND ID NOT IN (" . implode( ",", array_fill( 0, count( $ids ), "%d" ) ) . ")";
        foreach ( $ids as $id ) {
            $args[] = (int) $id;
        }
        if ( ! empty( $missing_status ) || ! empty( $missing_cf ) ) {
            $query .= " AND (";
        }
        if ( ! empty( $missing_status ) ) {
            $query .= " post_status != %s";
            $args[] = $missing_status;
            if ( $this->options['custom_type'] == 'product' && in_array( $missing_status, array( 'trash', 'draft' ) ) ) {
                $query .= " AND post_status != 'private'";
            }
            if ( ! empty( $missing_cf ) ) {
                $query .= " OR ";
            }
        }
        if ( ! empty( $missing_cf ) ) {
            $cf_conditions = array();
            foreach ( $missing_cf as $key => $cf ) {
                if ( ! empty( $cf['name'] ) ) {
                    $cf_conditions[] = "pm" . (int) $key . ".meta_value != %s";
                    $args[]          = $cf['value'];
                }
            }
            $query .= implode( " OR ", $cf_conditions );
        }
        if ( ! empty( $missing_status ) || ! empty( $missing_cf ) ) {
            $query .= ")";
        }

        if ( ! empty( $args ) ) {
            // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- values bound via prepare(); only int-cast table aliases are interpolated.
            $missing_ids = $this->wpdb->get_results( $this->wpdb->prepare( $query, $args ), ARRAY_A );
        } else {
            // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- no user-supplied values; query is fully constant.
            $missing_ids = $this->wpdb->get_results( $query, ARRAY_A );
        }

        return $missing_ids;
    }
}