<?php
/**
 * Wishlist REST API Controller.
 *
 * Endpoints:
 *   GET    /titancart/v1/wishlist               Get all wishlist items
 *   GET    /titancart/v1/wishlist/count          Item count (lightweight)
 *   POST   /titancart/v1/wishlist/items          Add item
 *   DELETE /titancart/v1/wishlist/items/{id}     Remove item
 *   POST   /titancart/v1/wishlist/items/{id}/move-to-cart  Move to cart
 *   POST   /titancart/v1/wishlist/share          Enable sharing, get URL
 *   DELETE /titancart/v1/wishlist/share          Disable sharing
 *
 * All write endpoints require authentication.
 * The GET /count and public shared wishlist views are accessible without login.
 *
 * @package TitanCart\REST\Wishlist
 */

namespace TitanCart\REST\Wishlist;

use TitanCart\Modules\Wishlist\WishlistManager;
use TitanCart\Modules\Accounts\AccountManager;
use WP_REST_Controller;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

defined( 'ABSPATH' ) || exit;

class WishlistController extends WP_REST_Controller {

    protected $namespace = 'titancart/v1';
    protected $rest_base = 'wishlist';

    private WishlistManager $manager;
    private AccountManager  $accounts;

    public function __construct() {
        $this->manager  = new WishlistManager();
        $this->accounts = new AccountManager();
    }

    public function register_routes(): void {

        // GET /wishlist  — all items
        register_rest_route( $this->namespace, '/' . $this->rest_base, [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'get_items' ],
                'permission_callback' => [ $this, 'is_authenticated' ],
                'args'                => [
                    'page'     => [ 'type' => 'integer', 'default' => 1, 'minimum' => 1 ],
                    'per_page' => [ 'type' => 'integer', 'default' => 20, 'minimum' => 1, 'maximum' => 100 ],
                ],
            ],
        ] );

        // GET /wishlist/count
        register_rest_route( $this->namespace, '/' . $this->rest_base . '/count', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'get_count' ],
                'permission_callback' => [ $this, 'is_authenticated' ],
            ],
        ] );

        // POST /wishlist/items  — add item
        register_rest_route( $this->namespace, '/' . $this->rest_base . '/items', [
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [ $this, 'add_item' ],
                'permission_callback' => [ $this, 'is_authenticated' ],
                'args'                => [
                    'product_id'   => [ 'type' => 'integer', 'required' => true, 'minimum' => 1 ],
                    'variation_id' => [ 'type' => 'integer', 'minimum' => 1 ],
                ],
            ],
        ] );

        // DELETE /wishlist/items/{id}  — remove by product_id
        register_rest_route( $this->namespace, '/' . $this->rest_base . '/items/(?P<id>[\d]+)', [
            [
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => [ $this, 'remove_item' ],
                'permission_callback' => [ $this, 'is_authenticated' ],
                'args'                => [ 'id' => [ 'type' => 'integer', 'minimum' => 1 ] ],
            ],
        ] );

        // POST /wishlist/items/{id}/move-to-cart
        register_rest_route( $this->namespace, '/' . $this->rest_base . '/items/(?P<id>[\d]+)/move-to-cart', [
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [ $this, 'move_to_cart' ],
                'permission_callback' => [ $this, 'is_authenticated' ],
                'args'                => [ 'id' => [ 'type' => 'integer', 'minimum' => 1 ] ],
            ],
        ] );

        // POST /wishlist/share  — enable sharing
        register_rest_route( $this->namespace, '/' . $this->rest_base . '/share', [
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [ $this, 'enable_sharing' ],
                'permission_callback' => [ $this, 'is_authenticated' ],
            ],
            [
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => [ $this, 'disable_sharing' ],
                'permission_callback' => [ $this, 'is_authenticated' ],
            ],
        ] );

        // GET /wishlist/shared/{key}  — public shared list (no auth required)
        // WP.org R1 🅱4: public by design — the whole feature is "share my
        // wishlist by link". Capability IS the unguessable share key the owner
        // opted into generating; owner can revoke via DELETE above.
        register_rest_route( $this->namespace, '/' . $this->rest_base . '/shared/(?P<key>[a-zA-Z0-9]+)', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'get_shared' ],
                'permission_callback' => '__return_true', // Public by design: shared-wishlist view — the unguessable share key IS the credential, verified inside the handler.
                'args'                => [ 'key' => [ 'type' => 'string' ] ],
            ],
        ] );

        // ── Flat alias ────────────────────────────────────────────────────────

        register_rest_route( $this->namespace, '/wishlists', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'get_items' ],
                'permission_callback' => [ $this, 'is_authenticated' ],
            ],
        ] );
    }

    // ══════════════════════════════════════════════════════════════════════════
    // HANDLERS
    // ══════════════════════════════════════════════════════════════════════════

    public function get_items( $request ): WP_REST_Response {
        $customer = $this->current_customer();
        if ( ! $customer ) {
            return $this->error( 'not_found', __( 'Customer record not found.', 'titancart-lite' ), 404 );
        }

        $result = $this->manager->get_items(
            (int) $customer['id'],
            (int) $request->get_param( 'page' ),
            (int) $request->get_param( 'per_page' )
        );

        $response = new WP_REST_Response( $result['items'] );
        $response->header( 'X-TC-Total', (string) $result['total'] );
        $response->header( 'X-TC-Pages', (string) $result['pages'] );
        return $response;
    }

    public function get_count( WP_REST_Request $request ): WP_REST_Response {
        $customer = $this->current_customer();
        if ( ! $customer ) {
            return new WP_REST_Response( [ 'count' => 0 ] );
        }
        return new WP_REST_Response( [
            'count' => $this->manager->get_count( (int) $customer['id'] ),
        ] );
    }

    public function add_item( WP_REST_Request $request ): WP_REST_Response {
        $customer = $this->current_customer();
        if ( ! $customer ) {
            return $this->error( 'not_found', __( 'Customer record not found.', 'titancart-lite' ), 404 );
        }

        $product_id   = (int) $request->get_param( 'product_id' );
        $variation_id = $request->get_param( 'variation_id' ) ? (int) $request->get_param( 'variation_id' ) : null;
        $result       = $this->manager->add_item( (int) $customer['id'], $product_id, $variation_id );

        if ( is_wp_error( $result ) ) {
            return $this->error( $result->get_error_code(), $result->get_error_message(), 422 );
        }

        return new WP_REST_Response( [
            'added' => true,
            'count' => $this->manager->get_count( (int) $customer['id'] ),
        ], 201 );
    }

    public function remove_item( WP_REST_Request $request ): WP_REST_Response {
        $customer = $this->current_customer();
        if ( ! $customer ) {
            return $this->error( 'not_found', __( 'Customer record not found.', 'titancart-lite' ), 404 );
        }

        $product_id = (int) $request->get_param( 'id' );
        $this->manager->remove_item( (int) $customer['id'], $product_id );

        return new WP_REST_Response( [
            'removed' => true,
            'count'   => $this->manager->get_count( (int) $customer['id'] ),
        ] );
    }

    public function move_to_cart( WP_REST_Request $request ): WP_REST_Response {
        $customer = $this->current_customer();
        if ( ! $customer ) {
            return $this->error( 'not_found', __( 'Customer record not found.', 'titancart-lite' ), 404 );
        }

        $product_id = (int) $request->get_param( 'id' );
        $result     = $this->manager->move_to_cart( (int) $customer['id'], $product_id );

        if ( is_wp_error( $result ) ) {
            return $this->error( $result->get_error_code(), $result->get_error_message(), 422 );
        }

        return new WP_REST_Response( [
            'added_to_cart' => true,
            'count'         => $this->manager->get_count( (int) $customer['id'] ),
        ] );
    }

    public function enable_sharing( WP_REST_Request $request ): WP_REST_Response {
        $customer = $this->current_customer();
        if ( ! $customer ) {
            return $this->error( 'not_found', __( 'Customer record not found.', 'titancart-lite' ), 404 );
        }

        $url = $this->manager->enable_sharing( (int) $customer['id'] );
        return new WP_REST_Response( [ 'share_url' => $url ] );
    }

    public function disable_sharing( WP_REST_Request $request ): WP_REST_Response {
        $customer = $this->current_customer();
        if ( ! $customer ) {
            return $this->error( 'not_found', __( 'Customer record not found.', 'titancart-lite' ), 404 );
        }

        $this->manager->disable_sharing( (int) $customer['id'] );
        return new WP_REST_Response( null, 204 );
    }

    public function get_shared( WP_REST_Request $request ): WP_REST_Response {
        $share_key = sanitize_key( $request->get_param( 'key' ) );
        $wishlist  = $this->manager->find_by_share_key( $share_key );

        if ( ! $wishlist ) {
            return $this->error( 'not_found', __( 'Wishlist not found.', 'titancart-lite' ), 404 );
        }

        $result = $this->manager->get_items( (int) $wishlist['customer_id'], 1, 100 );
        return new WP_REST_Response( $result['items'] );
    }

    // ══════════════════════════════════════════════════════════════════════════
    // HELPERS
    // ══════════════════════════════════════════════════════════════════════════

    public function is_authenticated( WP_REST_Request $request ): bool {
        return is_user_logged_in();
    }

    private function current_customer(): ?array {
        return $this->accounts->get_or_create_current_customer();
    }

    private function error( string $code, string $message, int $status ): WP_REST_Response {
        return new WP_REST_Response( [ 'code' => $code, 'message' => $message ], $status );
    }
}
