<?php
/**
 * Allow switching the listing package.
 *
 * @since 1.0
 */

namespace MyListing\Src\Paid_Listings\Controllers;

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

class Switch_Package {
	use \MyListing\Src\Traits\Instantiatable;

	public
		$listing,
		$listing_id;

	public function __construct() {
		// TO DO add step just for relist if needed
		add_filter( 'mylisting/submission-steps', [ $this, 'submission_steps' ], 150 );
		add_filter( 'mylisting/user-listings/actions', [ $this, 'display_switch_action' ], 40 );

		// fires after the subscription has been activated, and the payment package has been created
		add_action( 'mylisting/subscriptions/switch/order-processed', [ $this, 'subscription_processed' ], 10, 2 );

		// fires after the subscription has been activated, and the payment package has been created
		add_action( 'mylisting/subscriptions/relist/order-processed', [ $this, 'relist_subscription_processed' ], 10, 2 );

		// fires after the order has been paid and processed and the payment package has been created
		add_action( 'mylisting/payments/relist/order-processed', [ $this, 'relist_order_processed' ], 10, 2 );
		// handle relist without package directly within this controller
		add_action( 'mylisting/payments/relist/use-without-package', [ $this, 'use_without_package' ], 10 );
	}

	public function submission_steps( $steps ) {
		$actions = [ 'switch', 'relist' ];
		if ( empty( $_GET['action'] ) || ! in_array( $_GET['action'], $actions ) ) {
			return $steps;
		}

		$this->listing_id = ! empty( $_GET['listing'] ) ? absint( $_GET['listing'] ) : 0;
		$this->listing = \MyListing\Src\Listing::get( $this->listing_id );
		if ( ! ( $this->listing_id && $this->listing && $this->listing->type ) ) {
			return;
		}

		if ( $this->listing->type->settings['packages']['enabled'] !== false ) {
			// replace the default choose package step with switch/relist choose package
			if ( isset( $steps['wc-choose-package'] ) ) {
				unset( $steps['wc-choose-package'] );
			}
			$steps['switch-package'] = [
				'name'     => _x( 'Choose a package', 'Switch package', 'my-listing' ),
				'view'     => [ $this, 'choose_package' ],
				'handler'  => [ $this, 'choose_package_handler' ],
				'priority' => 5,
			];
		} else {
			return [ 'relist-package' => [
				'name'     => _x( 'Choose a package', 'Switch package', 'my-listing' ),
				'view'     => [ $this, 'relist_free_view' ],
				'handler'  => [ $this, 'relist_free_handler' ],
				'priority' => 6,
			] ];
		}

		return $steps;
	}

	/**
	 * Choose Package View
	 *
	 * @since 1.6
	 */
	public function choose_package() {
		wp_enqueue_script( 'mylisting-pricing-plans' );
		if ( empty( $_REQUEST['listing_type'] ) || ! ( $type = \MyListing\Src\Listing_Type::get_by_name( $_REQUEST['listing_type'] ) ) ) {
			return;
		}

		if ( mylisting_get_setting( 'user_can_switch_listing_plan' ) === 'no' ) {
			echo '<div class="job-manager-error">' . __( 'Invalid request.', 'my-listing' ) . '</div>';
			return;
		}

		$form = \MyListing\Src\Forms\Add_Listing_Form::instance();
		$tree = \MyListing\Src\Paid_Listings\Util::get_package_tree_for_listing_type( $type, 'switch-package' );
		$action = ! empty( $_GET['action'] ) ? $_GET['action'] : '';
		$listing_id = ! empty( $_GET['job_id'] ) ? absint( $_GET['job_id'] ) : $form->get_job_id();
		$listing = \MyListing\Src\Listing::get( $listing_id );
		if ( ! $listing ) {
			return;
		}

		$title = ( $action === 'relist' )
			? _x( 'Relist', 'Switch Package', 'my-listing' )
			: _x( 'Switch plan for listing', 'Switch Package', 'my-listing' );

		$description = ( $action === 'relist' )
			? _x( 'Previous plan:', 'Switch Package', 'my-listing' )
			: _x( 'Current plan:', 'Switch Package', 'my-listing' );
		?>

		<section class="i-section c27-packages">
			<div class="container">
				<div class="row section-title">
					<h2 class="case27-primary-text">
						<?php echo $title ?>
						<?php printf( ' "<a href="%s" target="_blank">%s</a>"', esc_url( $listing->get_link() ), $listing->get_name() ) ?>
					</h2>

					<?php if ( ( $current_package = $listing->get_package() ) && ( $current_product = $current_package->get_product() ) ): ?>
						<?php printf(
							'%s <a href="%s" title="%s" target="_blank">%s</a>.',
							$description,
							esc_url( $current_product->get_permalink() ),
							esc_attr( sprintf( _x( 'Package #%d', 'Switch Package', 'my-listing' ), $current_package->get_id() ) ),
							$current_product->get_title()
						) ?>
					<?php endif ?>
				</div>
				<form method="post" id="job_package_selection">
					<div class="job_listing_packages">

						<?php require locate_template( 'templates/add-listing/choose-package.php' ) ?>

						<div class="hidden">
							<input type="hidden" name="job_id" value="<?php echo esc_attr( $listing_id ) ?>">
							<input type="hidden" name="step" value="<?php echo esc_attr( $form->get_step() ) ?>">
							<input type="hidden" name="job_manager_form" value="<?php echo esc_attr( $form->form_name ) ?>">
							<?php if ( ! empty( $_REQUEST['listing_type'] ) ): ?>
								<input type="hidden" name="listing_type" value="<?php echo esc_attr( $_REQUEST['listing_type'] ) ?>">
							<?php endif ?>
						</div>
					</div>
				</form>
			</div>
		</section>
		<?php
	}

	public function choose_package_handler() {
		$form = \MyListing\Src\Forms\Add_Listing_Form::instance();
		$actions = [ 'switch', 'relist' ];

		try {
			if ( ! is_user_logged_in() || empty( $_GET['action'] ) || ! in_array( $_GET['action'], $actions ) ) {
				throw new \Exception( _x( 'Invalid request.', 'Switch package', 'my-listing' ) );
			}

			if ( empty( $_REQUEST['listing_package'] ) || empty( $_GET['listing'] ) ) {
				throw new \Exception( _x( 'Invalid request.', 'Switch package', 'my-listing' ) );
			}
			$action = $_GET['action'];
			$listing = \MyListing\Src\Listing::get( $_GET['listing'] );

			if ( ! ( $listing && $listing->type && $listing->editable_by_current_user() ) ) {
				throw new \Exception( _x( 'Something went wrong.', 'Switch package', 'my-listing' ) );
			}

			if ( ! \MyListing\Src\Paid_Listings\Util::validate_package( $_REQUEST['listing_package'], $listing->type->get_slug() ) && $listing->type->settings['packages']['enabled'] !== false ) {
				throw new \Exception( _x( 'Chosen package is not valid.', 'Switch package', 'my-listing' ) );
			}

			// Validate switch packages that are hidden from add listing
			if ( ! empty( $_REQUEST['listing_type'] ) && $type = \MyListing\Src\Listing_Type::get_by_name( $_REQUEST['listing_type'] ) ) {
				if ( get_post( $product_id = $_REQUEST['listing_package'] )->post_type === 'product' ) {
					$package = \MyListing\Src\Paid_Listings\Util::get_package_tree_for_listing_type( $type, 'switch-package', $product_id );
					if (empty($package)) {
						throw new \Exception( _x( 'Chosen package is not valid.', 'Listing submission', 'my-listing' ) );
					}

				} elseif ( get_post( $product_id = $_REQUEST['listing_package'] )->post_type === 'case27_user_package' && is_user_logged_in() ) {
					$product_id = ( get_post($product_id)->post_type === 'case27_user_package' ) ? get_post_meta( get_post($product_id)->ID, '_product_id', true ) : $package->ID;
					$package = \MyListing\Src\Paid_Listings\Util::get_package_tree_for_listing_type( $type, 'switch-package', $product_id );
					if (empty($package)) {
						throw new \Exception( _x( 'Chosen package is not valid.', 'Listing submission', 'my-listing' ) );
					}
				}
			}

			// Package is valid.
			$package = get_post( $_REQUEST['listing_package'] );

			// Store selection in cookie.
			wc_setcookie( 'chosen_package_id', absint( $package->ID ) );

			// Our custom logic: Redirect to edit form instead of immediate switch
			$form->next_step();

			// --TO DO - move these messages to paid-listings.php
			// $message = $action === 'relist'
			// 	? _x( 'Listing has been successfully relisted.', 'Switch Package', 'my-listing' )
			// 	: _x( 'Listing plan has been updated.', 'Switch Package', 'my-listing' );
		} catch (\Exception $e) {
			// Log error message.
			$form->add_error( $e->getMessage() );
			$form->set_step( array_search( 'switch-package', array_keys( $form->get_steps() ) ) );
		}
	}

	public function relist_free_view() {
		$form = \MyListing\Src\Forms\Add_Listing_Form::instance();
		$actions = [ 'relist' ];
		if ( ! is_user_logged_in() || empty( $_GET['action'] ) || ! in_array( $_GET['action'], $actions ) ) {
			echo '<div class="job-manager-error">' . __( 'Invalid request.', 'my-listing' ) . '</div>';
			return;
		}

		if ( empty( $_GET['listing'] ) ) {
			echo '<div class="job-manager-error">' . __( 'Invalid request.', 'my-listing' ) . '</div>';
			return;
		}

		$listing = \MyListing\Src\Listing::get( $_GET['listing'] );
		if ( ! ( $listing && $listing->type && $listing->editable_by_current_user() ) ) {
			echo '<div class="job-manager-error">' . __( 'Something went wrong.', 'my-listing' ) . '</div>';
			return;
		}

		do_action( 'mylisting/payments/relist/use-without-package', $listing );

		// Redirect to user dashboard.
		$message = mylisting_get_setting( 'submission_requires_approval' )
			? _x( 'Listing submitted successfully. Your listing will be visible once approved.', 'Switch Package', 'my-listing' )
			: _x( 'Listing has been successfully relisted.', 'Switch Package', 'my-listing' );

		wc_add_notice( $message, 'success' );
		$redirect_url = wc_get_account_endpoint_url( \MyListing\my_listings_endpoint_slug() );
		?>
		<script type="text/javascript">
		    window.location = <?php echo wp_json_encode( $redirect_url ) ?>;
		</script>
		<?php
		exit;
	}

	public function display_switch_action( $listing ) {
		if ( ! ( $listing->type && in_array( $listing->get_status(), [ 'publish', 'expired' ] ) ) ) {
			return;
		}

		if ( ! ( $plans_page = c27()->get_setting( 'general_add_listing_page' ) ) ) {
			return;
		}

		if ( mylisting_get_setting( 'user_can_switch_listing_plan' ) === 'no' ) {
			add_filter( 'mylisting/display-switch-action', '__return_false' );
		}

		if ( apply_filters( 'mylisting/display-switch-action', true, $listing ) === false ) {
			return;
		}

		if ( ! $listing->type->are_packages_enabled() ) {
			// Packages disabled: show only Relist for expired listings; otherwise no action
			if ( $listing->get_status() === 'expired' ) {
				$action = 'relist';
				$switch_url = add_query_arg( [
					'action' => $action,
					'listing' => $listing->get_id(),
				], $plans_page );

				printf(
					'<li class="cts-listing-action-%s">
						<a href="%s" class="listing-action-switch">%s</a>
					</li>',
					esc_attr( $action ),
					esc_url( $switch_url ),
					_x( 'Relist', 'User listings dashboard', 'my-listing' )
				);
			}
			return;
		}

		$product = $listing->get_product();
		$allow_switch = get_option( 'woocommerce_subscriptions_allow_switching' );
		if (
			$listing->get_status() === 'publish'
			&& $product && $product->is_type( 'job_package_subscription' )
			&& class_exists( '\WC_Subscriptions_Switcher' )
			&& apply_filters( 'mylisting/enable-subscription-switch', true ) !== false
			&& in_array( $allow_switch, ['variable_grouped', 'variable', 'grouped'], true )
		) {
			$package = $listing->get_package();
			$order = $package ? $package->get_order() : false;
			if ( $package && $order ) {
				$items = $order->get_items();
				$item = array_pop( $items );
				if ( $item ) {
					$switch_url = \WC_Subscriptions_Switcher::get_switch_url( $item->get_id(), $item, $order );
					printf(
						'<li class="cts-listing-action-upgrade-subscription">
							<a href="%s" class="listing-action-switch" title="%s">%s</a>
						</li>',
						$switch_url,
						_x( 'Upgrade or Downgrade', 'User listings dashboard', 'my-listing' ),
						_x( 'Upgrade', 'User listings dashboard', 'my-listing' )
					);
					return;
				}
			}
		}

		$action = $listing->get_data('post_status') === 'publish' ? 'switch' : 'relist';
		$switch_url = add_query_arg( [
			'action' => $action,
			'listing' => $listing->get_id(),
		], $plans_page );

		printf(
			'<li class="cts-listing-action-%s">
				<a href="%s" class="listing-action-switch">%s</a>
			</li>',
			esc_attr( $action ),
			esc_url( $switch_url ),
			$action === 'switch'
				? _x( 'Switch Plan', 'User listings dashboard', 'my-listing' )
				: _x( 'Relist', 'User listings dashboard', 'my-listing' )
		);
	}

	/**
	 * Fires after the subscription has been activated, and the payment package
	 * has been created. Assign the package and publish listing.
	 *
	 * @since 2.1.6
	 */
	public function subscription_processed( $listing, $package ) {
		wp_update_post( [
			'ID' => $listing->get_id(),
			'post_status' => 'publish',
		] );

		$package->assign_to_listing( $listing->get_id() );
	}

	/**
	 * Fires after the subscription has been activated, and the payment package
	 * has been created. Assign the package and publish listing.
	 *
	 * @since 2.1.6
	 */
	public function relist_subscription_processed( $listing, $package ) {
		$listing_status = mylisting_get_setting( 'submission_requires_approval' ) ? 'pending' : 'publish';
		wp_update_post( [
			'ID' => $listing->get_id(),
			'post_date' => current_time( 'mysql' ),
			'post_date_gmt' => current_time( 'mysql', 1 ),
			'post_status' => $listing_status,
		] );

		$package->assign_to_listing( $listing->get_id() );
	}

	/**
	 * After the order has been paid and processed and the payment package is
	 * created, update the listing package and publish it.
	 *
	 * @since 2.1.6
	 */
	public function relist_order_processed( $listing, $package ) {
		$listing_status = mylisting_get_setting( 'submission_requires_approval' ) ? 'pending' : 'publish';
		wp_update_post( [
			'ID' => $listing->get_id(),
			'post_date' => current_time( 'mysql' ),
			'post_date_gmt' => current_time( 'mysql', 1 ),
			'post_status' => $listing_status,
		] );

		$package->assign_to_listing( $listing->get_id() );
	}

	/**
	 * Relist handler for the 'use-without-package' flow.
	 *
	 */
	public function use_without_package( $listing ) {
		$post_status = mylisting_get_setting( 'submission_requires_approval' ) ? 'pending' : 'publish';
		$duration    = absint( mylisting_get_setting( 'submission_default_duration' ) );
		$new_expiry  = '';
		if ( $duration ) {
			$new_expiry = date( 'Y-m-d', strtotime( "+{$duration} days", current_time( 'timestamp' ) ) );
		}

		wp_update_post( [
			'ID'          => $listing->get_id(),
			'post_status' => $post_status,
		] );

		if ( $post_status === 'publish' ) {
			update_post_meta( $listing->get_id(), '_job_expires', $new_expiry );
		} else {
			delete_post_meta( $listing->get_id(), '_job_expires' );
		}
	}
}
