<?php
/**
 * Consent manager: handles plugin activation, DB table creation, and consent logging.
 *
 * @package LetsCodeCookieBanner
 */

defined( 'ABSPATH' ) || exit;

/**
 * Manages consent records stored in the lccb_consents database table.
 */
class LCCB_Consent_Manager {

	/**
	 * Runs on plugin activation: creates the DB table and seeds default settings.
	 */
	public static function activate() {
		self::create_table();

		$defaults = array(
			'banner_enabled'    => '1',
			'show_fab_button'   => '1',
			'cookie_policy_url' => '',
			'logging_enabled'   => '1',
			'bg_color'          => '#ffffff',
			'text_color'        => '#333333',
			'btn_bg'            => '#1a73e8',
			'btn_text'          => '#ffffff',
			'btn_border_color'  => '#1a73e8',
			'overlay_bg'        => '#f8f8f8',
		);

		$existing = get_option( 'lccb_settings', array() );
		update_option( 'lccb_settings', array_merge( $defaults, $existing ) );
	}

	/**
	 * Creates the lccb_consents table if it does not already exist.
	 */
	private static function create_table() {
		global $wpdb;

		$table           = $wpdb->prefix . 'lccb_consents';
		$charset_collate = $wpdb->get_charset_collate();

		$sql = "CREATE TABLE IF NOT EXISTS {$table} (
			id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
			consent_id VARCHAR(36) NOT NULL,
			consent_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
			necessary TINYINT(1) NOT NULL DEFAULT 1,
			statistics TINYINT(1) NOT NULL DEFAULT 0,
			marketing TINYINT(1) NOT NULL DEFAULT 0,
			preferences TINYINT(1) NOT NULL DEFAULT 0,
			action VARCHAR(20) NOT NULL DEFAULT 'custom',
			PRIMARY KEY (id),
			KEY consent_id (consent_id),
			KEY consent_date (consent_date)
		) {$charset_collate};";

		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
		dbDelta( $sql );
		update_option( 'lccb_db_version', LCCB_VERSION );
	}

	/**
	 * Inserts a consent record into the database.
	 *
	 * @param string $consent_id UUID identifying the consent session.
	 * @param array  $choices    Associative array of category => bool consent choices.
	 * @param string $action     Action type: 'accept_all', 'reject_all', or 'custom'.
	 */
	public static function log_consent( $consent_id, array $choices, $action ) {
		$settings = get_option( 'lccb_settings', array() );
		if ( empty( $settings['logging_enabled'] ) ) {
			return;
		}

		global $wpdb;
		$table = $wpdb->prefix . 'lccb_consents';

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->insert(
			$table,
			array(
				'consent_id'   => sanitize_text_field( $consent_id ),
				'consent_date' => current_time( 'mysql' ),
				'necessary'    => 1,
				'statistics'   => isset( $choices['statistics'] ) ? (int) $choices['statistics'] : 0,
				'marketing'    => isset( $choices['marketing'] ) ? (int) $choices['marketing'] : 0,
				'preferences'  => isset( $choices['preferences'] ) ? (int) $choices['preferences'] : 0,
				'action'       => sanitize_key( $action ),
			),
			array( '%s', '%s', '%d', '%d', '%d', '%d', '%s' )
		);
	}

	/**
	 * Returns a paginated list of consent log rows.
	 *
	 * @param int $per_page Number of rows per page.
	 * @param int $page     1-based page number.
	 * @return array
	 */
	public static function get_logs( $per_page = 20, $page = 1 ) {
		global $wpdb;
		$table  = esc_sql( $wpdb->prefix . 'lccb_consents' );
		$offset = ( absint( $page ) - 1 ) * absint( $per_page );

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		return $wpdb->get_results(
			$wpdb->prepare(
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"SELECT * FROM {$table} ORDER BY consent_date DESC LIMIT %d OFFSET %d",
				absint( $per_page ),
				$offset
			)
		);
	}

	/**
	 * Returns the total number of consent log rows.
	 *
	 * @return int
	 */
	public static function count_logs() {
		global $wpdb;
		$table = esc_sql( $wpdb->prefix . 'lccb_consents' );
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		return (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$table}" );
	}

	/**
	 * Deletes consent logs older than the given number of years (0 = all logs).
	 *
	 * @param int $years Number of years; 0 deletes all rows.
	 * @return int Number of rows deleted.
	 */
	public static function delete_old_logs( $years ) {
		global $wpdb;
		$table = esc_sql( $wpdb->prefix . 'lccb_consents' );

		if ( 0 === (int) $years ) {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			return (int) $wpdb->query( "DELETE FROM {$table}" );
		}

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		return (int) $wpdb->query(
			$wpdb->prepare(
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"DELETE FROM {$table} WHERE consent_date < DATE_SUB(NOW(), INTERVAL %d YEAR)",
				absint( $years )
			)
		);
	}

	/**
	 * Generates a unique UUID v4 consent identifier.
	 *
	 * @return string
	 */
	public static function generate_consent_id() {
		return wp_generate_uuid4();
	}
}
