<?php
/**
 * Retention cleanup service.
 *
 * @package SubmissionInbox
 */

namespace SUBIN\Retention;

use SUBIN\Leads\LeadFieldRepository;
use SUBIN\Leads\LeadRepository;
use SUBIN\Leads\LeadActivityRepository;
use SUBIN\MailLog\MailEventRepository;

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

/**
 * Cleans expired lead records.
 */
class RetentionService {
	const CRON_HOOK = 'subin_daily_retention_cleanup';

	/**
	 * Settings repository.
	 *
	 * @var \SUBIN_SettingsRepository
	 */
	private $settings;

	/**
	 * Lead repository.
	 *
	 * @var LeadRepository
	 */
	private $leads;

	/**
	 * Lead field repository.
	 *
	 * @var LeadFieldRepository
	 */
	private $fields;

	/**
	 * Mail event repository.
	 *
	 * @var MailEventRepository
	 */
	private $mail_events;

	/**
	 * Lead activity repository.
	 *
	 * @var LeadActivityRepository
	 */
	private $activity;

	/**
	 * Constructor.
	 *
	 * @param \SUBIN_SettingsRepository $settings Settings repository.
	 * @param LeadRepository          $leads Lead repository.
	 * @param LeadFieldRepository     $fields Lead field repository.
	 * @param MailEventRepository     $mail_events Mail event repository.
	 */
	public function __construct( \SUBIN_SettingsRepository $settings, LeadRepository $leads, LeadFieldRepository $fields, MailEventRepository $mail_events ) {
		$this->settings    = $settings;
		$this->leads       = $leads;
		$this->fields      = $fields;
		$this->mail_events = $mail_events;
		$this->activity    = new LeadActivityRepository();
	}

	/**
	 * Register cleanup hook.
	 *
	 * @return void
	 */
	public function register() {
		add_action( self::CRON_HOOK, array( $this, 'cleanup_expired_leads' ) );
	}

	/**
	 * Delete expired leads and fields while preserving email log rows.
	 *
	 * @return int
	 */
	public function cleanup_expired_leads() {
		$settings = $this->settings->all();
		if ( empty( $settings['store_leads'] ) ) {
			return 0;
		}

		$deleted = 0;
		foreach ( $this->leads->get_expired_lead_ids( 500 ) as $lead_id ) {
			$this->mail_events->detach_lead( $lead_id );
			$this->fields->delete_by_lead_id( $lead_id );
			$this->activity->delete_by_lead_id( $lead_id );

			if ( $this->leads->delete( $lead_id ) ) {
				++$deleted;
			}
		}

		return $deleted;
	}

	/**
	 * Schedule daily cleanup.
	 *
	 * @return void
	 */
	public static function schedule() {
		if ( ! wp_next_scheduled( self::CRON_HOOK ) ) {
			wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', self::CRON_HOOK );
		}
	}

	/**
	 * Clear scheduled cleanup.
	 *
	 * @return void
	 */
	public static function unschedule() {
		wp_clear_scheduled_hook( self::CRON_HOOK );
	}
}
