<?php
/**
 * Class Noesia Cs Data Service.
 *
 * @package Noesia_Commerce_Suite
 */

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

/**
 * Class implementation.
 */
class Noesia_CS_Data_Service {
	/**
	 * Handles the related plugin operation.
	 */
	public function cleanup_operational_data() {
		$settings       = Noesia_CS_Settings::get_all();
		$logs_days      = max( 1, absint( $settings['logs_retention_days'] ) );
		$email_days     = max( 1, absint( $settings['email_log_retention_days'] ?? 15 ) );
		$doctor_days    = max( 1, absint( $settings['doctor_result_retention_days'] ) );
		$logs_cutoff    = time() - ( $logs_days * DAY_IN_SECONDS );
		$email_cutoff   = time() - ( $email_days * DAY_IN_SECONDS );
		$doctor_cutoff  = time() - ( $doctor_days * DAY_IN_SECONDS );
		$summary        = array(
			'email_logs_removed'        => $this->prune_timestamped_option( Noesia_CS_Email_Service::EMAIL_LOG_OPTION, $email_cutoff ),
			'care_action_logs_removed'  => class_exists( 'Noesia_CS_Care_Action_Service' ) ? ( new Noesia_CS_Care_Action_Service() )->prune_logs( $logs_cutoff ) : 0,
			'reorder_logs_removed'      => $this->prune_timestamped_option( Noesia_CS_Reorder_Service::LOG_OPTION, $logs_cutoff ),
			'reorder_queue_removed'     => $this->prune_reorder_queue( $logs_cutoff ),
			'sent_keys_removed'         => $this->prune_sent_keys( $logs_cutoff ),
			'doctor_report_removed'     => $this->prune_doctor_report( $doctor_cutoff ),
		);

		update_option( 'noesia_cs_last_cleanup_summary', array_merge( $summary, array( 'time' => time() ) ), false );

		return $summary;
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function get_last_cleanup_summary() {
		$summary = get_option( 'noesia_cs_last_cleanup_summary', array() );
		return is_array( $summary ) ? $summary : array();
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $option Option.
	 * @param mixed $cutoff Cutoff.
	 */
	private function prune_timestamped_option( $option, $cutoff ) {
		$items = get_option( $option, array() );
		if ( ! is_array( $items ) ) {
			return 0;
		}

		$before = count( $items );
		$items  = array_values(
			array_filter(
				$items,
				function ( $item ) use ( $cutoff ) {
					$time = is_array( $item ) && isset( $item['time'] ) ? absint( $item['time'] ) : 0;
					return ! $time || $time >= $cutoff;
				}
			)
		);
		update_option( $option, $items, false );

		return max( 0, $before - count( $items ) );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $cutoff Cutoff.
	 */
	private function prune_reorder_queue( $cutoff ) {
		$queue = get_option( Noesia_CS_Reorder_Service::QUEUE_OPTION, array() );
		if ( ! is_array( $queue ) ) {
			return 0;
		}

		$before = count( $queue );
		foreach ( $queue as $key => $entry ) {
			if ( ! is_array( $entry ) ) {
				unset( $queue[ $key ] );
				continue;
			}
			$status   = isset( $entry['status'] ) ? sanitize_key( $entry['status'] ) : 'pending';
			$updated  = isset( $entry['updated_at'] ) ? absint( $entry['updated_at'] ) : 0;
			if ( 'pending' !== $status && $updated && $updated < $cutoff ) {
				unset( $queue[ $key ] );
			}
		}
		update_option( Noesia_CS_Reorder_Service::QUEUE_OPTION, $queue, false );

		return max( 0, $before - count( $queue ) );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $cutoff Cutoff.
	 */
	private function prune_sent_keys( $cutoff ) {
		$sent = get_option( Noesia_CS_Reorder_Service::SENT_OPTION, array() );
		if ( ! is_array( $sent ) ) {
			return 0;
		}

		$before = count( $sent );
		foreach ( $sent as $key => $time ) {
			if ( absint( $time ) < $cutoff ) {
				unset( $sent[ $key ] );
			}
		}
		update_option( Noesia_CS_Reorder_Service::SENT_OPTION, $sent, false );

		return max( 0, $before - count( $sent ) );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $cutoff Cutoff.
	 */
	private function prune_doctor_report( $cutoff ) {
		$report = get_option( Noesia_CS_Doctor_Service::REPORT_OPTION, array() );
		if ( ! is_array( $report ) || empty( $report['generated_at'] ) ) {
			return 0;
		}

		if ( absint( $report['generated_at'] ) < $cutoff ) {
			delete_option( Noesia_CS_Doctor_Service::REPORT_OPTION );
			return 1;
		}

		return 0;
	}
}
