<?php
/**
 * @package Hafenstudios\Leadlotse
 */

namespace Hafenstudios\Leadlotse\Rest;

use Hafenstudios\Leadlotse\Db\EntryRepository;

defined( 'ABSPATH' ) || exit;

/**
 * REST: Entries list/get und Status-Update (`leadlotse/v1/entries`),
 * Capability `hs_view_entries` (Persona Jonas: Inbox ohne Einstellungen).
 */
final class EntriesController {

	public const REST_NAMESPACE = 'leadlotse/v1';

	private EntryRepository $entries;

	/**
	 * @param EntryRepository $entries Entry-Repository.
	 */
	public function __construct( EntryRepository $entries ) {
		$this->entries = $entries;
	}

	/**
	 * Registriert die Routen.
	 *
	 * @return void
	 */
	public function register_routes(): void {
		register_rest_route(
			self::REST_NAMESPACE,
			'/entries',
			array(
				'methods'             => \WP_REST_Server::READABLE,
				'callback'            => array( $this, 'list_entries' ),
				'permission_callback' => array( $this, 'can_view' ),
				'args'                => array(
					'page'     => array(
						'type'    => 'integer',
						'default' => 1,
						'minimum' => 1,
					),
					'per_page' => array(
						'type'    => 'integer',
						'default' => 20,
						'minimum' => 1,
						'maximum' => 100,
					),
					'status'   => array(
						'type'    => 'string',
						'default' => '',
						'enum'    => array( '', 'new', 'in_progress', 'done' ),
					),
					'form_id'  => array(
						'type'    => 'integer',
						'default' => 0,
					),
					'search'   => array(
						'type'              => 'string',
						'default'           => '',
						'sanitize_callback' => 'sanitize_text_field',
					),
				),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE,
			'/entries/(?P<id>\d+)',
			array(
				'methods'             => \WP_REST_Server::READABLE,
				'callback'            => array( $this, 'get_entry' ),
				'permission_callback' => array( $this, 'can_view' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE,
			'/entries/(?P<id>\d+)/status',
			array(
				'methods'             => \WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'update_status' ),
				'permission_callback' => array( $this, 'can_view' ),
				'args'                => array(
					'status' => array(
						'type'     => 'string',
						'required' => true,
						'enum'     => EntryRepository::STATUSES,
					),
				),
			)
		);
	}

	/**
	 * Capability-Check (Inbox: hs_view_entries reicht, D12).
	 *
	 * @return bool|\WP_Error
	 */
	public function can_view() {
		if ( current_user_can( 'hs_view_entries' ) ) {
			return true;
		}
		return new \WP_Error(
			'leadlotse_forbidden',
			__( 'Sie haben keine Berechtigung, Anfragen einzusehen. Bitte wenden Sie sich an eine Administratorin oder einen Administrator.', 'leadlotse' ),
			array( 'status' => rest_authorization_required_code() )
		);
	}

	/**
	 * GET /entries - paginierte Liste mit Filtern und Suche.
	 *
	 * @param \WP_REST_Request $request Request.
	 * @return \WP_REST_Response
	 */
	public function list_entries( \WP_REST_Request $request ): \WP_REST_Response {
		$result = $this->entries->query(
			array(
				'page'     => (int) $request->get_param( 'page' ),
				'per_page' => (int) $request->get_param( 'per_page' ),
				'status'   => (string) $request->get_param( 'status' ),
				'form_id'  => (int) $request->get_param( 'form_id' ),
				'search'   => (string) $request->get_param( 'search' ),
			)
		);

		$response = new \WP_REST_Response( $result['items'], 200 );
		$response->header( 'X-WP-Total', (string) $result['total'] );
		$response->header( 'X-WP-TotalPages', (string) (int) ceil( $result['total'] / max( 1, $result['per_page'] ) ) );
		return $response;
	}

	/**
	 * GET /entries/{id}.
	 *
	 * @param \WP_REST_Request $request Request.
	 * @return \WP_REST_Response|\WP_Error
	 */
	public function get_entry( \WP_REST_Request $request ) {
		$entry = $this->entries->get( (int) $request->get_param( 'id' ) );
		if ( null === $entry ) {
			return new \WP_Error(
				'leadlotse_entry_not_found',
				__( 'Die Anfrage wurde nicht gefunden. Bitte aktualisieren Sie die Inbox.', 'leadlotse' ),
				array( 'status' => 404 )
			);
		}
		return new \WP_REST_Response( $entry, 200 );
	}

	/**
	 * POST /entries/{id}/status - Status Neu / In Arbeit / Erledigt.
	 *
	 * @param \WP_REST_Request $request Request.
	 * @return \WP_REST_Response|\WP_Error
	 */
	public function update_status( \WP_REST_Request $request ) {
		$id    = (int) $request->get_param( 'id' );
		$entry = $this->entries->get( $id );
		if ( null === $entry ) {
			return new \WP_Error(
				'leadlotse_entry_not_found',
				__( 'Die Anfrage wurde nicht gefunden. Bitte aktualisieren Sie die Inbox.', 'leadlotse' ),
				array( 'status' => 404 )
			);
		}

		$status = (string) $request->get_param( 'status' );
		if ( ! $this->entries->update_status( $id, $status ) ) {
			return new \WP_Error(
				'leadlotse_status_failed',
				__( 'Der Status konnte nicht gespeichert werden. Bitte versuchen Sie es erneut.', 'leadlotse' ),
				array( 'status' => 500 )
			);
		}

		return new \WP_REST_Response( $this->entries->get( $id ), 200 );
	}
}
