<?php
/**
 * TitanCart Todo REST Controller
 *
 * @package TitanCart\REST\Todo
 */

namespace TitanCart\REST\Todo;

use TitanCart\Modules\Todo\TodoManager;
use WP_REST_Request;
use WP_REST_Response;

defined( 'ABSPATH' ) || exit;

class TodoController {

    private string $ns = 'titancart/v1';
    private ?TodoManager $mgr = null;

    private function mgr(): TodoManager {
        if ( ! $this->mgr ) $this->mgr = new TodoManager();
        return $this->mgr;
    }

    public function admin_check(): bool {
        return current_user_can( 'manage_options' );
    }

    public function register_routes(): void {

        register_rest_route( $this->ns, '/todos', [
            [ 'methods' => 'GET',  'callback' => [ $this, 'list_todos' ],  'permission_callback' => [ $this, 'admin_check' ] ],
            [ 'methods' => 'POST', 'callback' => [ $this, 'create_todo' ], 'permission_callback' => [ $this, 'admin_check' ] ],
        ] );

        register_rest_route( $this->ns, '/todos/stats', [
            'methods' => 'GET', 'callback' => [ $this, 'stats' ], 'permission_callback' => [ $this, 'admin_check' ],
        ] );

        register_rest_route( $this->ns, '/todos/users', [
            'methods' => 'GET', 'callback' => [ $this, 'assignable_users' ], 'permission_callback' => [ $this, 'admin_check' ],
        ] );

        register_rest_route( $this->ns, '/todos/reorder', [
            'methods' => 'PUT', 'callback' => [ $this, 'reorder' ], 'permission_callback' => [ $this, 'admin_check' ],
        ] );

        register_rest_route( $this->ns, '/todos/(?P<id>\d+)', [
            [ 'methods' => 'GET',    'callback' => [ $this, 'get_todo' ],    'permission_callback' => [ $this, 'admin_check' ] ],
            [ 'methods' => 'PUT',    'callback' => [ $this, 'update_todo' ], 'permission_callback' => [ $this, 'admin_check' ] ],
            [ 'methods' => 'DELETE', 'callback' => [ $this, 'delete_todo' ], 'permission_callback' => [ $this, 'admin_check' ] ],
        ] );
    }

    public function list_todos( WP_REST_Request $req ): WP_REST_Response {
        return new WP_REST_Response( $this->mgr()->get_list( $req->get_params() ) );
    }

    public function stats( WP_REST_Request $req ): WP_REST_Response {
        return new WP_REST_Response( $this->mgr()->get_stats() );
    }

    public function assignable_users( WP_REST_Request $req ): WP_REST_Response {
        return new WP_REST_Response( $this->mgr()->get_assignable_users() );
    }

    public function get_todo( WP_REST_Request $req ): WP_REST_Response {
        $item = $this->mgr()->get( (int) $req['id'] );
        return $item ? new WP_REST_Response( $item ) : new WP_REST_Response( [ 'error' => 'Not found' ], 404 );
    }

    public function create_todo( WP_REST_Request $req ): WP_REST_Response {
        $data = $req->get_json_params();
        if ( empty( $data['title'] ) ) {
            return new WP_REST_Response( [ 'error' => 'Title is required' ], 422 );
        }
        $id   = $this->mgr()->create( $data );
        $item = $id ? $this->mgr()->get( $id ) : null;
        if ( ! $item ) {
            return new WP_REST_Response( [ 'error' => 'Failed to create task' ], 500 );
        }
        return new WP_REST_Response( $item, 201 );
    }

    public function update_todo( WP_REST_Request $req ): WP_REST_Response {
        $this->mgr()->update( (int) $req['id'], $req->get_json_params() ?: [] ); // KI-85
        // KI-87 (S407) — a missing id used to return 200 + a ZERO-BYTE body: get() returned
        // null and WP core (class-wp-rest-server.php L536-538) emits nothing for a null result.
        // Mirrors get_todo() L70. The preceding update() matched 0 rows, so there is no write.
        $item = $this->mgr()->get( (int) $req['id'] );
        return $item ? new WP_REST_Response( $item ) : new WP_REST_Response( [ 'error' => 'Not found' ], 404 );
    }

    public function delete_todo( WP_REST_Request $req ): WP_REST_Response {
        $this->mgr()->delete( (int) $req['id'] );
        return new WP_REST_Response( [ 'deleted' => true ] );
    }

    public function reorder( WP_REST_Request $req ): WP_REST_Response {
        $data = $req->get_json_params();
        $ids  = $data['ids'] ?? [];
        if ( ! is_array( $ids ) || empty( $ids ) ) {
            return new WP_REST_Response( [ 'error' => 'ids array required' ], 422 );
        }
        $this->mgr()->reorder( $ids );
        return new WP_REST_Response( [ 'reordered' => true ] );
    }
}
