<?php
/**
 * Analytics service class.
 *
 * Handles recording and reading generation history for dashboards, reports, and charts.
 *
 * @package    100Prints
 */

class Hundred_Prints_Analytics_Service {

	/**
	 * Get the generation history table name.
	 *
	 * @return string
	 */
	private function get_table_name() {
		global $wpdb;
		return $wpdb->prefix . '100p_generation_history';
	}

	/**
	 * Check if the table exists.
	 *
	 * @return bool
	 */
	private function table_exists() {
		global $wpdb;
		$table = $this->get_table_name();
		return $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table ) ) ) === $table;
	}

	/**
	 * Log a generation event.
	 *
	 * @param array $args {
	 *     @type string $template_id    Template identifier.
	 *     @type string $template_name  Human-readable template name.
	 *     @type int    $page_id        Page/post where generation occurred.
	 *     @type string $format         Output format (pdf, png).
	 *     @type string $status         Generation status (success, error).
	 *     @type string $quality        Render quality.
	 *     @type array  $variables      Resolved variable key-value pairs.
	 *     @type string $visitor_ip     Visitor IP address.
	 * }
	 * @return bool
	 */
	public function log_generation( $args ) {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return false;
		}

		// Support legacy positional arguments for backward compat.
		if ( is_string( $args ) ) {
			$args = [
				'template_id'   => func_get_arg( 0 ),
				'page_id'       => func_num_args() > 1 ? func_get_arg( 1 ) : 0,
				'format'        => func_num_args() > 2 ? func_get_arg( 2 ) : 'pdf',
				'status'        => func_num_args() > 3 ? func_get_arg( 3 ) : 'success',
				'template_name' => func_num_args() > 4 ? func_get_arg( 4 ) : '',
			];
		}

		$template_id   = isset( $args['template_id'] ) ? sanitize_text_field( $args['template_id'] ) : '';
		$template_name = isset( $args['template_name'] ) ? sanitize_text_field( $args['template_name'] ) : '';
		$page_id       = isset( $args['page_id'] ) ? absint( $args['page_id'] ) : 0;
		$format        = isset( $args['format'] ) ? sanitize_key( $args['format'] ) : 'pdf';
		$status        = isset( $args['status'] ) ? sanitize_key( $args['status'] ) : 'success';
		$quality       = isset( $args['quality'] ) ? sanitize_key( $args['quality'] ) : 'high';
		$variables     = isset( $args['variables'] ) && is_array( $args['variables'] ) ? $args['variables'] : [];
		$visitor_ip    = isset( $args['visitor_ip'] ) ? sanitize_text_field( $args['visitor_ip'] ) : '';

		if ( empty( $template_name ) ) {
			$template_service = new Hundred_Prints_Template_Service();
			$template = $template_service->get_template( $template_id );
			if ( is_array( $template ) && isset( $template['name'] ) ) {
				$template_name = $template['name'];
			} else {
				$template_name = 'Unknown Template';
			}
		}

		$format = in_array( $format, [ 'pdf', 'png' ], true ) ? $format : 'pdf';
		$status = in_array( $status, [ 'success', 'error' ], true ) ? $status : 'success';

		return (bool) $wpdb->insert(
			$this->get_table_name(),
			[
				'generation_uuid' => wp_generate_uuid4(),
				'template_id'     => $template_id,
				'template_name'   => $template_name,
				'page_id'         => $page_id,
				'user_id'         => get_current_user_id() ?: null,
				'visitor_ip'      => $visitor_ip,
				'variables_json'  => wp_json_encode( $variables ),
				'output_format'   => $format,
				'render_quality'  => $quality,
				'status'          => $status,
			],
			[ '%s', '%s', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%s' ]
		);
	}

	/**
	 * Delete generation history older than the configured retention period.
	 *
	 * @param int|null $days Retention window in days.
	 * @return int|false Number of rows deleted, or false on failure.
	 */
	public function prune_old_logs( $days = null ) {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return false;
		}

		if ( null === $days ) {
			$settings = function_exists( 'hundred_prints_get_settings' ) ? hundred_prints_get_settings() : [];
			$days = isset( $settings['log_retention_days'] ) ? absint( $settings['log_retention_days'] ) : 30;
		}

		$days = min( 365, max( 1, absint( $days ) ) );
		$cutoff = gmdate( 'Y-m-d H:i:s', current_time( 'timestamp', true ) - ( $days * DAY_IN_SECONDS ) );

		return $wpdb->query(
			$wpdb->prepare(
				"DELETE FROM {$this->get_table_name()} WHERE created_at < %s",
				$cutoff
			)
		);
	}

	/**
	 * Get total count of generations.
	 */
	public function get_total_generations() {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return 0;
		}

		$table = $this->get_table_name();
		return (int) $wpdb->get_var( "SELECT COUNT(*) FROM $table" );
	}

	/**
	 * Get count of active blocks.
	 */
	public function get_active_blocks_count() {
		global $wpdb;
		$query = "SELECT COUNT(*) FROM $wpdb->posts 
			WHERE post_status = 'publish' 
			AND post_content LIKE '%wp-block-100prints-document%'";
		return (int) $wpdb->get_var( $query );
	}

	/**
	 * Get recent activity log entries.
	 */
	public function get_recent_activity( $limit = 10 ) {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return [];
		}

		$table = $this->get_table_name();
		$query = $wpdb->prepare(
			"SELECT * FROM $table ORDER BY created_at DESC LIMIT %d",
			$limit
		);

		return $wpdb->get_results( $query );
	}

	/**
	 * Get count of generations in the last 30 days.
	 */
	public function get_generations_last_30_days() {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return 0;
		}

		$table = $this->get_table_name();
		$query = "SELECT COUNT(*) FROM $table WHERE created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)";
		return (int) $wpdb->get_var( $query );
	}

	/**
	 * Get the success rate of generated documents.
	 */
	public function get_success_rate() {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return 100.0;
		}

		$total = $this->get_total_generations();
		if ( $total === 0 ) {
			return 100.0;
		}

		$table = $this->get_table_name();
		$success = (int) $wpdb->get_var( $wpdb->prepare(
			"SELECT COUNT(*) FROM $table WHERE status = %s",
			'success'
		) );

		return round( ( $success / $total ) * 100, 1 );
	}

	/**
	 * Get daily generation counts for the last 30 days.
	 */
	public function get_daily_counts_30_days() {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return [];
		}

		$table = $this->get_table_name();
		$query = "SELECT DATE(created_at) as date, COUNT(*) as count 
			FROM $table 
			WHERE created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY) 
			GROUP BY DATE(created_at) 
			ORDER BY DATE(created_at) ASC";
		
		$results = $wpdb->get_results( $query, ARRAY_A );

		// Fill in missing dates to prevent blank graph segments.
		$daily_data = [];
		for ( $i = 29; $i >= 0; $i-- ) {
			$date = date( 'Y-m-d', strtotime( "-$i days" ) );
			$daily_data[ $date ] = 0;
		}

		foreach ( $results as $row ) {
			if ( isset( $daily_data[ $row['date'] ] ) ) {
				$daily_data[ $row['date'] ] = (int) $row['count'];
			}
		}

		return $daily_data;
	}

	/**
	 * Get template usage breakdown.
	 */
	public function get_template_breakdown() {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return [];
		}

		$table = $this->get_table_name();
		$query = "SELECT template_id, template_name, COUNT(*) as count, MAX(created_at) as last_used 
			FROM $table 
			GROUP BY template_id, template_name 
			ORDER BY count DESC";

		return $wpdb->get_results( $query );
	}

	/**
	 * Get all logs for CSV exports.
	 */
	public function get_all_activity_logs() {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return [];
		}

		$table = $this->get_table_name();
		return $wpdb->get_results( "SELECT * FROM $table ORDER BY created_at DESC" );
	}

	/**
	 * Get a single generation history record by ID.
	 *
	 * @param int $id Record ID.
	 * @return object|null
	 */
	public function get_record( $id ) {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return null;
		}

		$table = $this->get_table_name();
		return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE id = %d", absint( $id ) ) );
	}

	/**
	 * Delete a single generation history record.
	 *
	 * @param int $id Record ID.
	 * @return bool
	 */
	public function delete_record( $id ) {
		global $wpdb;

		if ( ! $this->table_exists() ) {
			return false;
		}

		$table = $this->get_table_name();
		return (bool) $wpdb->delete( $table, [ 'id' => absint( $id ) ], [ '%d' ] );
	}

	/**
	 * Bulk delete generation history records.
	 *
	 * @param array $ids Array of record IDs.
	 * @return int Number of rows deleted.
	 */
	public function bulk_delete( array $ids ) {
		global $wpdb;

		if ( ! $this->table_exists() || empty( $ids ) ) {
			return 0;
		}

		$table = $this->get_table_name();
		$ids = array_map( 'absint', $ids );
		$placeholders = implode( ', ', array_fill( 0, count( $ids ), '%d' ) );

		return (int) $wpdb->query(
			$wpdb->prepare( "DELETE FROM $table WHERE id IN ($placeholders)", ...$ids )
		);
	}
}
