<?php
/**
 * REST endpoint for the Overview dashboard.
 *
 * @package StoreSheet
 */

declare( strict_types=1 );

namespace StoreSheet\Rest;

defined( 'ABSPATH' ) || exit;

use WP_REST_Response;
use WP_REST_Server;

class OverviewController {

	private const NAMESPACE = 'storesheet/v1';
	private const CACHE_KEY = 'storesheet_overview_stats';
	private const CACHE_TTL = 5 * MINUTE_IN_SECONDS;

	public function register_routes(): void {
		register_rest_route(
			self::NAMESPACE,
			'/overview',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => array( $this, 'get_overview' ),
				'permission_callback' => array( $this, 'admin_permission' ),
			)
		);

		register_rest_route(
			self::NAMESPACE,
			'/log',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => array( $this, 'get_log' ),
				'permission_callback' => array( $this, 'admin_permission' ),
			)
		);

		register_rest_route(
			self::NAMESPACE,
			'/sync/trigger',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'trigger_sync' ),
				'permission_callback' => array( $this, 'admin_permission' ),
			)
		);

		register_rest_route(
			self::NAMESPACE,
			'/sync/resync-orders',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'resync_orders' ),
				'permission_callback' => array( $this, 'admin_permission' ),
			)
		);
	}

	public function get_overview(): WP_REST_Response {
		$cached = wp_cache_get( self::CACHE_KEY, 'storesheet' );
		if ( false !== $cached ) {
			return new WP_REST_Response( $cached, 200 );
		}

		$data = array(
			'oauth_status'    => storesheet()->oauth_client()->get_status(),
			'last_sync'       => get_option( 'storesheet_last_sync', null ),
			'spreadsheet_url' => get_option( 'storesheet_settings', array() )['spreadsheet_url'] ?? '',
			'counts'          => $this->get_sync_counts(),
			'recent_log'      => $this->get_recent_log( 10 ),
			'plan'            => storesheet()->is_pro() ? 'pro' : 'free',
		);

		wp_cache_set( self::CACHE_KEY, $data, 'storesheet', self::CACHE_TTL );

		return new WP_REST_Response( $data, 200 );
	}

	public function get_log(): WP_REST_Response {
		global $wpdb;

		$table = $wpdb->prefix . 'storesheet_sync_log';
		$rows  = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare( 'SELECT * FROM %i ORDER BY created_at DESC LIMIT 50', $table ), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
			ARRAY_A
		);

		return new WP_REST_Response( $rows ?: array(), 200 );
	}

	public function trigger_sync(): WP_REST_Response {
		if ( ! function_exists( 'as_enqueue_async_action' ) ) {
			return new WP_REST_Response( array( 'message' => __( 'Action Scheduler not available.', 'storesheet' ) ), 500 );
		}

		as_enqueue_async_action( 'storesheet_scheduled_sync', array(), 'storesheet' );
		wp_cache_delete( self::CACHE_KEY, 'storesheet' );

		return new WP_REST_Response( array( 'queued' => true ), 200 );
	}

	/**
	 * Kick off a background re-push of every order into the (per-status) tabs.
	 * Chunked via Action Scheduler so it never blocks the request.
	 */
	public function resync_orders(): WP_REST_Response {
		if ( ! function_exists( 'as_enqueue_async_action' ) ) {
			return new WP_REST_Response( array( 'message' => __( 'Action Scheduler not available.', 'storesheet' ) ), 500 );
		}

		as_enqueue_async_action( 'storesheet_resync_orders_chunk', array( 0 ), 'storesheet' );

		return new WP_REST_Response( array( 'queued' => true ), 200 );
	}

	public function admin_permission(): bool {
		return current_user_can( 'manage_woocommerce' );
	}

	// -------------------------------------------------------------------------
	// Helpers
	// -------------------------------------------------------------------------

	/**
	 * @return array<string, int>
	 */
	private function get_sync_counts(): array {
		global $wpdb;

		$table = $wpdb->prefix . 'storesheet_sync_log';

		$counts = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare( 'SELECT status, COUNT(*) as cnt FROM %i GROUP BY status', $table ), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
			ARRAY_A
		);

		$result = array(
			'success' => 0,
			'failed'  => 0,
			'pending' => 0,
			'skipped' => 0,
		);
		foreach ( (array) $counts as $row ) {
			$result[ $row['status'] ] = (int) $row['cnt'];
		}

		return $result;
	}

	/**
	 * @param int $limit
	 * @return array<int, array<string, mixed>>
	 */
	private function get_recent_log( int $limit ): array {
		global $wpdb;

		$table = $wpdb->prefix . 'storesheet_sync_log';
		$rows  = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare(
				'SELECT id, direction, resource, resource_id, status, message, created_at FROM %i ORDER BY created_at DESC LIMIT %d', // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
				$table,
				$limit
			),
			ARRAY_A
		);

		return $rows ?: array();
	}
}
