<?php
/**
 * Activity Logger
 * 
 * Logs user activities and system events.
 * 
 * @package WooNooW\Core\ActivityLog
 */

namespace WooNooW\Core\ActivityLog;

class Logger {
	
	/**
	 * Log an activity
	 * 
	 * @param string $action Action type (e.g., 'order.created')
	 * @param string $object_type Object type (e.g., 'order', 'product')
	 * @param int $object_id Object ID
	 * @param string $description Human-readable description
	 * @param array $metadata Additional metadata
	 * @param int|null $user_id User ID (null = current user)
	 * @return int|false Activity ID or false on failure
	 */
	public static function log($action, $object_type, $object_id, $description = '', $metadata = [], $user_id = null) {
		global $wpdb;
		
		// Get user info
		if ($user_id === null) {
			$user_id = get_current_user_id();
		}
		
		$user = get_userdata($user_id);
		$user_name = $user ? $user->display_name : __('System', 'woonoow');
		
		// Get object name
		$object_name = self::get_object_name($object_type, $object_id);
		
		// Get IP and user agent
		$ip_address = self::get_client_ip();
		$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
		
		// Prepare data
		$data = [
			'user_id' => $user_id,
			'user_name' => $user_name,
			'action' => $action,
			'object_type' => $object_type,
			'object_id' => $object_id,
			'object_name' => $object_name,
			'description' => $description,
			'metadata' => json_encode($metadata),
			'ip_address' => $ip_address,
			'user_agent' => $user_agent,
			'created_at' => current_time('mysql'),
		];
		
		// Insert
		$table_name = ActivityLogTable::get_table_name();
		$result = $wpdb->insert($table_name, $data);
		
		if ($result === false) {
			return false;
		}
		
		return $wpdb->insert_id;
	}
	
	/**
	 * Get object name based on type and ID
	 * 
	 * @param string $object_type
	 * @param int $object_id
	 * @return string
	 */
	private static function get_object_name($object_type, $object_id) {
		switch ($object_type) {
			case 'order':
				return sprintf(__('Order #%d', 'woonoow'), $object_id);
				
			case 'product':
				$product = wc_get_product($object_id);
				return $product ? $product->get_name() : sprintf(__('Product #%d', 'woonoow'), $object_id);
				
			case 'customer':
				$customer = get_userdata($object_id);
				return $customer ? $customer->display_name : sprintf(__('Customer #%d', 'woonoow'), $object_id);
				
			case 'notification':
				return sprintf(__('Notification #%d', 'woonoow'), $object_id);
				
			case 'settings':
				return __('Settings', 'woonoow');
				
			default:
				return sprintf(__('%s #%d', 'woonoow'), ucfirst($object_type), $object_id);
		}
	}
	
	/**
	 * Get client IP address
	 * 
	 * @return string
	 */
	private static function get_client_ip() {
		$ip_keys = ['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR'];
		
		foreach ($ip_keys as $key) {
			if (isset($_SERVER[$key]) && filter_var($_SERVER[$key], FILTER_VALIDATE_IP)) {
				return $_SERVER[$key];
			}
		}
		
		return '0.0.0.0';
	}
	
	/**
	 * Get activities
	 * 
	 * @param array $args Query arguments
	 * @return array
	 */
	public static function get_activities($args = []) {
		global $wpdb;
		
		$defaults = [
			'page' => 1,
			'per_page' => 20,
			'action' => null,
			'object_type' => null,
			'object_id' => null,
			'user_id' => null,
			'date_from' => null,
			'date_to' => null,
			'search' => null,
		];
		
		$args = wp_parse_args($args, $defaults);
		
		$table_name = ActivityLogTable::get_table_name();
		$where = ['1=1'];
		$where_values = [];
		
		// Filters
		if ($args['action']) {
			$where[] = 'action = %s';
			$where_values[] = $args['action'];
		}
		
		if ($args['object_type']) {
			$where[] = 'object_type = %s';
			$where_values[] = $args['object_type'];
		}
		
		if ($args['object_id']) {
			$where[] = 'object_id = %d';
			$where_values[] = $args['object_id'];
		}
		
		if ($args['user_id']) {
			$where[] = 'user_id = %d';
			$where_values[] = $args['user_id'];
		}
		
		if ($args['date_from']) {
			$where[] = 'created_at >= %s';
			$where_values[] = $args['date_from'];
		}
		
		if ($args['date_to']) {
			$where[] = 'created_at <= %s';
			$where_values[] = $args['date_to'];
		}
		
		if ($args['search']) {
			$where[] = '(description LIKE %s OR object_name LIKE %s OR user_name LIKE %s)';
			$search_term = '%' . $wpdb->esc_like($args['search']) . '%';
			$where_values[] = $search_term;
			$where_values[] = $search_term;
			$where_values[] = $search_term;
		}
		
		// Build query
		$where_clause = implode(' AND ', $where);
		$offset = ($args['page'] - 1) * $args['per_page'];
		
		// Count total
		$count_query = "SELECT COUNT(*) FROM {$table_name} WHERE {$where_clause}";
		if (!empty($where_values)) {
			$count_query = $wpdb->prepare($count_query, $where_values);
		}
		$total = (int) $wpdb->get_var($count_query);
		
		// Get activities
		$query = "SELECT * FROM {$table_name} WHERE {$where_clause} ORDER BY created_at DESC LIMIT %d OFFSET %d";
		$where_values[] = $args['per_page'];
		$where_values[] = $offset;
		
		$query = $wpdb->prepare($query, $where_values);
		$activities = $wpdb->get_results($query, ARRAY_A);
		
		// Parse metadata
		foreach ($activities as &$activity) {
			$activity['metadata'] = json_decode($activity['metadata'], true);
		}
		
		return [
			'activities' => $activities,
			'total' => $total,
			'page' => $args['page'],
			'per_page' => $args['per_page'],
			'total_pages' => ceil($total / $args['per_page']),
		];
	}
	
	/**
	 * Get activity stats
	 * 
	 * @param string $date_from
	 * @param string $date_to
	 * @return array
	 */
	public static function get_stats($date_from = null, $date_to = null) {
		global $wpdb;
		
		$table_name = ActivityLogTable::get_table_name();
		$where = ['1=1'];
		$where_values = [];
		
		if ($date_from) {
			$where[] = 'created_at >= %s';
			$where_values[] = $date_from;
		}
		
		if ($date_to) {
			$where[] = 'created_at <= %s';
			$where_values[] = $date_to;
		}
		
		$where_clause = implode(' AND ', $where);
		
		// Total activities
		$total_query = "SELECT COUNT(*) FROM {$table_name} WHERE {$where_clause}";
		if (!empty($where_values)) {
			$total_query = $wpdb->prepare($total_query, $where_values);
		}
		$total = (int) $wpdb->get_var($total_query);
		
		// By action
		$by_action_query = "SELECT action, COUNT(*) as count FROM {$table_name} WHERE {$where_clause} GROUP BY action ORDER BY count DESC LIMIT 10";
		if (!empty($where_values)) {
			$by_action_query = $wpdb->prepare($by_action_query, $where_values);
		}
		$by_action = $wpdb->get_results($by_action_query, ARRAY_A);
		
		// By user
		$by_user_query = "SELECT user_id, user_name, COUNT(*) as count FROM {$table_name} WHERE {$where_clause} GROUP BY user_id ORDER BY count DESC LIMIT 10";
		if (!empty($where_values)) {
			$by_user_query = $wpdb->prepare($by_user_query, $where_values);
		}
		$by_user = $wpdb->get_results($by_user_query, ARRAY_A);
		
		return [
			'total' => $total,
			'by_action' => $by_action,
			'by_user' => $by_user,
		];
	}
	
	/**
	 * Delete old activities
	 * 
	 * @param int $days Days to keep
	 * @return int Number of deleted rows
	 */
	public static function cleanup($days = 90) {
		global $wpdb;
		
		$table_name = ActivityLogTable::get_table_name();
		$date = date('Y-m-d H:i:s', strtotime("-{$days} days"));
		
		return $wpdb->query($wpdb->prepare(
			"DELETE FROM {$table_name} WHERE created_at < %s",
			$date
		));
	}
}
