<?php
/**
 * /suppliers routes (see docs/SPEC.md §8).
 *
 * @package EmberPrice
 */

namespace EmberPrice\Rest;

use EmberPrice\Core\Suppliers;
use EmberPrice\Pricing\RuleValidator;

defined( 'ABSPATH' ) || exit;

/**
 * Registers the supplier CRUD routes. GET is implemented (T-106, needed by
 * the upload step's supplier picker); PUT saves the pricing rule (T-303,
 * the review-rules wizard step). Create is still a stub -- suppliers are
 * only ever created inline from the upload step (T-105).
 */
final class SuppliersController extends Controller {

	/**
	 * REST base for this resource.
	 *
	 * @var string
	 */
	protected $rest_base = 'suppliers';

	/**
	 * Supplier data access.
	 *
	 * @var Suppliers
	 */
	private Suppliers $suppliers;

	/**
	 * Constructor.
	 *
	 * @param Suppliers|null $suppliers Defaults to a new instance.
	 */
	public function __construct( ?Suppliers $suppliers = null ) {
		$this->suppliers = $suppliers ?? new Suppliers();
	}

	/**
	 * Registers all /suppliers routes.
	 */
	public function register_routes(): void {
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base,
			array(
				array(
					'methods'             => \WP_REST_Server::READABLE,
					'callback'            => array( $this, 'list_suppliers' ),
					'permission_callback' => array( $this, 'permissions_check' ),
				),
				array(
					'methods'             => \WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'not_implemented' ),
					'permission_callback' => array( $this, 'permissions_check' ),
				),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/(?P<id>\d+)',
			array(
				'methods'             => \WP_REST_Server::EDITABLE,
				'callback'            => array( $this, 'update_supplier' ),
				'permission_callback' => array( $this, 'permissions_check' ),
				'args'                => array(
					'default_rule' => array(
						'type'     => 'object',
						'required' => true,
					),
				),
			)
		);
	}

	/**
	 * `GET /suppliers`: lists all suppliers (id, name, column_map, settings).
	 */
	public function list_suppliers(): \WP_REST_Response {
		return new \WP_REST_Response( $this->suppliers->all(), 200 );
	}

	/**
	 * `PUT /suppliers/{id}`: saves the supplier's pricing rule --
	 * `{ default_rule: { rule: {...}, category_overrides: { "<cat_id>": {...} } } }`
	 * (SPEC §5, wizard paso 4).
	 *
	 * @param \WP_REST_Request $request The current request.
	 *
	 * @return \WP_REST_Response|\WP_Error
	 */
	public function update_supplier( \WP_REST_Request $request ) {
		$id = (int) $request->get_param( 'id' );

		if ( null === $this->suppliers->find( $id ) ) {
			return $this->error( 'embp_supplier_not_found', __( 'Supplier not found.', 'emberprice' ), 404 );
		}

		try {
			$default_rule = ( new RuleValidator() )->validate_default_rule( (array) $request->get_param( 'default_rule' ) );
		} catch ( \InvalidArgumentException $exception ) {
			return $this->error(
				'embp_invalid_pricing_rule',
				sprintf(
					/* translators: %s: validation detail. */
					__( 'Invalid pricing rule: %s', 'emberprice' ),
					$exception->getMessage()
				),
				400
			);
		}

		$this->suppliers->save_default_rule( $id, $default_rule );

		return new \WP_REST_Response( array( 'supplier' => $this->suppliers->find( $id ) ), 200 );
	}
}
