<?php
/**
 * Site-level data lifecycle settings and maintenance.
 *
 * @package VoidPulse
 */

namespace VoidPulse\Admin;

defined( 'ABSPATH' ) || exit;

final class DataLifecycle {
	/**
	 * Return lifecycle settings and bounded database usage.
	 *
	 * @return array<string,mixed>
	 */
	public function settings() {
		$usage = $this->database_usage();
		return array(
			'delete_on_uninstall' => (bool) get_option( 'voidpulse_delete_data_on_uninstall', false ),
			'detailed_available'  => (bool) apply_filters( 'voidpulse_detailed_analytics_available', false ),
			'retention_days'      => absint( apply_filters( 'voidpulse_detailed_analytics_retention', 90 ) ),
			'database_bytes'      => $usage['bytes'],
			'database_records'    => $usage['records'],
			'database_tables'     => $usage['tables'],
		);
	}

	/**
	 * Save allowlisted site-level preferences.
	 *
	 * @param array<string,mixed> $input Submitted settings.
	 * @return array<string,mixed>
	 */
	public function save( $input ) {
		$delete = isset( $input['delete_on_uninstall'] ) && rest_sanitize_boolean( $input['delete_on_uninstall'] );
		update_option( 'voidpulse_delete_data_on_uninstall', $delete, false );
		if ( apply_filters( 'voidpulse_detailed_analytics_available', false ) ) {
			$retention = absint( isset( $input['retention_days'] ) ? $input['retention_days'] : 90 );
			if ( ! in_array( $retention, array( 30, 90, 180, 365 ), true ) ) {
				$retention = 90;
			}
			do_action( 'voidpulse_save_detailed_analytics_retention', $retention );
		}
		return $this->settings();
	}

	/**
	 * Clear aggregate and detailed analytics without touching campaigns.
	 *
	 * @return void
	 */
	public function clear_analytics() {
		global $wpdb;
		delete_option( 'voidpulse_analytics_daily' );
		foreach ( $this->detailed_tables() as $suffix ) {
			$table = $wpdb->prefix . $suffix;
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Explicit confirmed deletion from validated plugin-owned analytics tables.
			$wpdb->query( $wpdb->prepare( 'DELETE FROM %i', $table ) );
		}
		do_action( 'voidpulse_analytics_cleared' );
	}

	/**
	 * Calculate approximate storage across existing plugin tables.
	 *
	 * @return array{bytes:int,records:int,tables:int}
	 */
	private function database_usage() {
		global $wpdb;
		$suffixes = array_merge( array( 'voidpulse_campaigns', 'voidpulse_events' ), $this->detailed_tables() );
		$bytes    = 0;
		$records  = 0;
		$tables   = 0;
		foreach ( array_values( array_unique( $suffixes ) ) as $suffix ) {
			$table = $wpdb->prefix . $suffix;
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Read-only table-status diagnostics for a closed list of plugin-owned tables.
			$status = $wpdb->get_row( $wpdb->prepare( 'SHOW TABLE STATUS LIKE %s', $wpdb->esc_like( $table ) ), ARRAY_A );
			if ( ! is_array( $status ) ) {
				continue;
			}
			++$tables;
			$bytes   += absint( $status['Data_length'] ) + absint( $status['Index_length'] );
			$records += absint( $status['Rows'] );
		}
		return array( 'bytes' => $bytes, 'records' => $records, 'tables' => $tables );
	}

	/**
	 * Return validated optional analytics table suffixes.
	 *
	 * @return array<string>
	 */
	private function detailed_tables() {
		$tables = (array) apply_filters( 'voidpulse_detailed_analytics_tables', array() );
		return array_values(
			array_filter(
				$tables,
				static function ( $table ) {
					return is_string( $table ) && (bool) preg_match( '/^voidpulse_[a-z0-9_]+$/', $table );
				}
			)
		);
	}
}
