<?php
/**
 * Install controller for plugin installation and setup.
 *
 * @package Awesomemotive\Rewardswp\Controllers
 * @since 1.0.0
 */

namespace Awesomemotive\Rewardswp\Controllers;

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

use Awesomemotive\Rewardswp\Controllers\TaskSchedulerController;
use Awesomemotive\Rewardswp\Database\UpgradeManager;
use Awesomemotive\Rewardswp\Interfaces\ControllerInterface;
use Awesomemotive\Rewardswp\Settings\Options\Points\EarnActionsOption;
use Awesomemotive\Rewardswp\Settings\Options\Points\SpendActionsOption;
use Awesomemotive\Rewardswp\Settings\Options\Referrals\RewardsOption;
use Exception;
use function Awesomemotive\Rewardswp\Helpers\get_option_object;

/**
 * Install Controller.
 *
 * @since 1.0.0
 */
class InstallController implements ControllerInterface {
	/**
	 * Upgrade manager instance.
	 *
	 * @since 1.0.0
	 *
	 * @var UpgradeManager
	 */
	private UpgradeManager $upgrade_manager;

	/**
	 * Task scheduler controller instance.
	 *
	 * @since 1.0.6
	 *
	 * @var TaskSchedulerController
	 */
	private TaskSchedulerController $task_scheduler_controller;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param UpgradeManager          $upgrade_manager          Upgrade manager instance.
	 * @param TaskSchedulerController $task_scheduler_controller Task scheduler controller instance.
	 */
	public function __construct( UpgradeManager $upgrade_manager, TaskSchedulerController $task_scheduler_controller ) {
		$this->upgrade_manager           = $upgrade_manager;
		$this->task_scheduler_controller = $task_scheduler_controller;
	}

	/**
	 * Execute routines on install.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 * @throws Exception If installation routines fail.
	 */
	public function init() {
		$this->upgrade_manager->create_tables();
		// Schedule tasks immediately during activation (init hook hasn't run yet).
		$this->task_scheduler_controller->schedule_recurring_actions();
		$this->seed_defaults();

		// Set transient to flush rewrite rules on next init (after rules are registered).
		// We can't flush here because controllers haven't loaded yet to register their rules.
		set_transient( 'rewardswp_flush_rewrite_rules', true, 60 );

		// Set transient to trigger setup wizard redirect on next admin page load.
		// This is needed because wp_safe_redirect() fails during plugin activation when headers are already sent.
		set_transient( 'rewardswp_activation_redirect', true, 60 );
	}

	/**
	 * Seed default earn actions, spend actions, and referral rewards on first activation.
	 *
	 * @since 1.1.0
	 * @return void
	 */
	private function seed_defaults(): void {
		// Check if already seeded.
		if ( get_option( 'rewardswp_defaults_seeded' ) ) {
			return;
		}

		// Seed earn actions (purchase + signup enabled).
		$earn_option = get_option_object( EarnActionsOption::class );
		if ( $earn_option ) {
			$earn_actions = $earn_option->get_value();

			// Enable purchase and signup.
			$earn_actions['purchase']['enabled']    = true;
			$earn_actions['purchase']['configured'] = true;
			$earn_actions['signup']['enabled']      = true;
			$earn_actions['signup']['configured']   = true;

			// Use the option object's update() method (calls sanitize()).
			$earn_option->update( $earn_actions );
		}

		// Seed spend actions (3 fixed discounts enabled).
		$spend_option = get_option_object( SpendActionsOption::class );
		if ( $spend_option ) {
			$spend_actions = [
				[
					'id'              => 'spend_1',
					'type'            => 'fixed_discount',
					'enabled'         => true,
					'custom_title'    => '',
					'points_required' => 500,
					'coupon_amount'   => 5,
					'minimum_spent'   => 0,
					'coupon_prefix'   => '',
					'coupon_duration' => 'never',
					'icon'            => 'reward-amount-coupon',
				],
				[
					'id'              => 'spend_2',
					'type'            => 'fixed_discount',
					'enabled'         => true,
					'custom_title'    => '',
					'points_required' => 1000,
					'coupon_amount'   => 10,
					'minimum_spent'   => 0,
					'coupon_prefix'   => '',
					'coupon_duration' => 'never',
					'icon'            => 'reward-amount-coupon',
				],
				[
					'id'              => 'spend_3',
					'type'            => 'fixed_discount',
					'enabled'         => true,
					'custom_title'    => '',
					'points_required' => 2000,
					'coupon_amount'   => 20,
					'minimum_spent'   => 0,
					'coupon_prefix'   => '',
					'coupon_duration' => 'never',
					'icon'            => 'reward-amount-coupon',
				],
			];

			// Use the option object's update() method (calls sanitize()).
			$spend_option->update( $spend_actions );
		}

		// Seed referral rewards (both advocate and friend get $5).
		$referral_option = get_option_object( RewardsOption::class );
		if ( $referral_option ) {
			$referral_rewards = [
				'advocate' => [
					'name'                 => '',
					'type'                 => 'fixed_discount',
					'reward_amount'        => 5,
					'minimum_order_amount' => 0,
					'reward_expiration'    => '+3 months',
					'products_included'    => [],
				],
				'friend'   => [
					'name'                 => '',
					'type'                 => 'fixed_discount',
					'reward_amount'        => 5,
					'minimum_order_amount' => 0,
					'reward_expiration'    => '+3 months',
					'products_included'    => [],
				],
			];

			// Use the option object's update() method (calls sanitize()).
			$referral_option->update( $referral_rewards );
		}

		// Set flag to prevent re-seeding.
		update_option( 'rewardswp_defaults_seeded', true );
	}
}
