<?php

namespace SerpIQ\Api\Controllers;

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

final class Alerts_Controller {
	private static ?Alerts_Controller $instance = null;

	public static function instance(): Alerts_Controller {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	public function register_routes(): void {
		register_rest_route(
			'serpiq/v1',
			'/alerts',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'list' ),
				'permission_callback' => array( \SerpIQ\Api\Rest_Permission::class, 'admin_rest_request' ),
				'args'                => array(
					'type'    => array(
						'required'          => false,
						'type'              => 'string',
						'sanitize_callback' => 'sanitize_key',
						'enum'              => array( 'position_drop', 'ctr_drop', 'traffic_drop', 'impressions_spike' ),
					),
					'page'    => array(
						'required'          => false,
						'type'              => 'integer',
						'default'           => 1,
						'sanitize_callback' => 'absint',
					),
					'perPage' => array(
						'required'          => false,
						'type'              => 'integer',
						'default'           => 20,
						'sanitize_callback' => 'absint',
					),
				),
			)
		);
	}

	public function list( \WP_REST_Request $request ): \WP_REST_Response {
		global $wpdb;

		$type = sanitize_key( (string) $request->get_param( 'type' ) );
		$page = max( 1, absint( $request->get_param( 'page' ) ) );
		$per_page = absint( $request->get_param( 'perPage' ) );
		$per_page = $per_page > 0 ? min( 100, $per_page ) : 20;
		$offset = ( $page - 1 ) * $per_page;

		$table = $wpdb->prefix . 'serpiq_alerts';
		$where = '1=1';
		$params = array();

		if ( '' !== $type && in_array( $type, array( 'position_drop', 'ctr_drop', 'traffic_drop', 'impressions_spike' ), true ) ) {
			$where .= ' AND alert_type = %s';
			$params[] = $type;
		}

		$sql_count = "SELECT COUNT(*) FROM %i WHERE {$where}";
		$total     = (int) $wpdb->get_var( $wpdb->prepare( $sql_count, array_merge( array( $table ), $params ) ) );

		$params[] = $per_page;
		$params[] = $offset;
		$sql      = "SELECT * FROM %i WHERE {$where} ORDER BY created_at DESC LIMIT %d OFFSET %d";
		$items    = $wpdb->get_results( $wpdb->prepare( $sql, array_merge( array( $table ), $params ) ), ARRAY_A );

		return new \WP_REST_Response(
			array(
				'page'    => $page,
				'perPage' => $per_page,
				'total'   => $total,
				'items'   => is_array( $items ) ? $items : array(),
			),
			200
		);
	}
}
