<?php
/**
 * @license GPL-2.0-or-later
 * @link    https://wordpress.org/plugins/pressio-crm
 */
namespace PressioCRM\API;

defined( 'ABSPATH' ) || exit;

use PressioCRM\Framework\Controller;
use PressioCRM\Models\ActivityModel;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

class RestActivities extends Controller {

	protected $rest_base = 'activities';

	/** Allowed type values — used to whitelist the `type` filter. */
	private const ALLOWED_TYPES = [
		'contact_created',
		'contact_created_from_form',
		'deal_created',
		'deal_won',
		'deal_lost',
		'stage_change',
		'task_completed',
		'note_added',
		'email_sent',
	];

	public function register_routes(): void {
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base,
			[
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => [ $this, 'index' ],
				'permission_callback' => [ $this, 'require_contacts_cap' ],
				'args'                => [
					'contact_id' => [
						'type'              => 'integer',
						'required'          => false,
						'sanitize_callback' => 'absint',
						'validate_callback' => 'rest_validate_request_arg',
					],
					'deal_id'    => [
						'type'              => 'integer',
						'required'          => false,
						'sanitize_callback' => 'absint',
						'validate_callback' => 'rest_validate_request_arg',
					],
					'limit'      => [
						'type'              => 'integer',
						'default'           => 20,
						'required'          => false,
						'sanitize_callback' => 'absint',
						'validate_callback' => 'rest_validate_request_arg',
					],
					'type'       => [
						'type'              => 'string',
						'required'          => false,
						'sanitize_callback' => 'sanitize_text_field',
						'validate_callback' => 'rest_validate_request_arg',
					],
				],
			]
		);
	}

	public function index( WP_REST_Request $request ): WP_REST_Response {
		$contact_id = $this->get_int_param( $request, 'contact_id' );
		$deal_id    = $this->get_int_param( $request, 'deal_id' );
		$limit      = min( 100, max( 1, absint( $request->get_param( 'limit' ) ?: 20 ) ) );

		// Parse and whitelist the optional `type` filter (comma-separated).
		$type_param  = sanitize_text_field( $request->get_param( 'type' ) ?? '' );
		$types       = [];
		if ( $type_param ) {
			$raw_types = array_map( 'trim', explode( ',', $type_param ) );
			$types     = array_values( array_intersect( $raw_types, self::ALLOWED_TYPES ) );
		}

		if ( $contact_id ) {
			$result = ActivityModel::get_for_contact( $contact_id, $limit, 1, $types );
			return $this->paginated_response( $result, [ $this, 'format_activity' ] );
		}

		if ( $deal_id ) {
			$result = ActivityModel::get_for_deal( $deal_id, $limit, 1 );
			return $this->paginated_response( $result, [ $this, 'format_activity' ] );
		}

		$activities = ActivityModel::get_recent( $limit );

		return $this->ok( array_map( [ $this, 'format_activity' ], $activities ) );
	}

	public function format_activity( object $activity ): array {
		$meta = $activity->meta;
		if ( is_string( $meta ) ) {
			$meta = json_decode( $meta, true ) ?: [];
		}
		if ( ! is_array( $meta ) ) {
			$meta = [];
		}

		return [
			'id'          => (int) $activity->id,
			'contact_id'  => (int) $activity->contact_id,
			'deal_id'     => (int) $activity->deal_id,
			'user_id'     => (int) $activity->user_id,
			'type'        => (string) $activity->type,
			'title'       => (string) $activity->title,
			'description' => (string) $activity->description,
			'meta'        => $meta,
			'created_at'  => (string) $activity->created_at,
		];
	}
}
