<?php
/**
 * Active Carts REST Controller — Admin-only view of live carts.
 *
 * Routes:
 *   GET /titancart/v1/admin/carts           List active carts (paginated)
 *   GET /titancart/v1/admin/carts/{id}      Single cart detail with items
 *   DELETE /titancart/v1/admin/carts/{id}   Delete abandoned cart
 *   GET /titancart/v1/admin/carts/stats     Cart stats
 *
 * @package TitanCart\REST\Cart
 */

namespace TitanCart\REST\Cart;

use TitanCart\DB\Database;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

defined( 'ABSPATH' ) || exit;

class ActiveCartsController {

    private string $namespace = 'titancart/v1';
    private Database $db;

    public function __construct() {
        $this->db = titancart_db();
    }

    public function register_routes(): void {

        register_rest_route( $this->namespace, '/admin/carts', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'list_carts' ],
                'permission_callback' => [ $this, 'admin_permission' ],
                'args'                => [
                    'page'     => [ 'type' => 'integer', 'default' => 1 ],
                    'per_page' => [ 'type' => 'integer', 'default' => 20 ],
                    'type'     => [ 'type' => 'string' ],  // guest | customer
                    'search'   => [ 'type' => 'string' ],
                ],
            ],
        ] );

        register_rest_route( $this->namespace, '/admin/carts/stats', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'get_stats' ],
                'permission_callback' => [ $this, 'admin_permission' ],
            ],
        ] );

        register_rest_route( $this->namespace, '/admin/carts/(?P<id>\d+)', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'get_cart' ],
                'permission_callback' => [ $this, 'admin_permission' ],
            ],
            [
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => [ $this, 'delete_cart' ],
                'permission_callback' => [ $this, 'admin_permission' ],
            ],
        ] );
    }

    // ══════════════════════════════════════════════════════════════════════════

    public function list_carts( WP_REST_Request $request ): WP_REST_Response {
        $page     = max( 1, (int) $request->get_param( 'page' ) );
        $per_page = min( 100, max( 1, (int) $request->get_param( 'per_page' ) ) );
        $offset   = ( $page - 1 ) * $per_page;
        $type     = $request->get_param( 'type' );
        $search   = $request->get_param( 'search' );

        $where  = [];
        $params = [];

        if ( $type === 'guest' ) {
            $where[] = 'c.customer_id IS NULL';
        } elseif ( $type === 'customer' ) {
            $where[] = 'c.customer_id IS NOT NULL';
        }

        if ( $search ) {
            $like     = '%' . $this->db->escape_like( $search ) . '%';
            $where[]  = '(cu.email LIKE ?s OR cu.first_name LIKE ?s OR cu.last_name LIKE ?s)';
            $params[] = $like;
            $params[] = $like;
            $params[] = $like;
        }

        $where_sql = $where ? 'WHERE ' . implode( ' AND ', $where ) : '';

        $count_params = $params;
        $total = (int) $this->db->getField(
            "SELECT COUNT(*)
             FROM {$this->db->table('carts')} c
             LEFT JOIN {$this->db->table('customers')} cu ON cu.id = c.customer_id
             {$where_sql}",
            ...$count_params
        );

        $list_params   = $params;
        $list_params[] = $per_page;
        $list_params[] = $offset;

        $carts = $this->db->getArray(
            "SELECT c.*,
                    cu.first_name, cu.last_name, cu.email,
                    (SELECT COUNT(*) FROM {$this->db->table('cart_items')} ci WHERE ci.cart_id = c.id) AS item_count,
                    (SELECT COALESCE(SUM(ci2.unit_price * ci2.quantity), 0) FROM {$this->db->table('cart_items')} ci2 WHERE ci2.cart_id = c.id) AS subtotal
             FROM {$this->db->table('carts')} c
             LEFT JOIN {$this->db->table('customers')} cu ON cu.id = c.customer_id
             {$where_sql}
             ORDER BY c.updated_at DESC
             LIMIT ?i OFFSET ?i",
            ...$list_params
        );

        return new WP_REST_Response( [
            'carts'    => $carts ?: [],
            'total'    => $total,
            'pages'    => $total > 0 ? (int) ceil( $total / $per_page ) : 1,
            'page'     => $page,
            'per_page' => $per_page,
        ] );
    }

    public function get_cart( WP_REST_Request $request ): WP_REST_Response|WP_Error {
        $id = (int) $request['id'];

        $cart = $this->db->getRow(
            "SELECT c.*, cu.first_name, cu.last_name, cu.email
             FROM {$this->db->table('carts')} c
             LEFT JOIN {$this->db->table('customers')} cu ON cu.id = c.customer_id
             WHERE c.id = ?i LIMIT 1",
            $id
        );

        if ( ! $cart ) {
            return new WP_Error( 'tc_not_found', 'Cart not found.', [ 'status' => 404 ] );
        }

        // Get items with product details.
        $cart['items'] = $this->db->getArray(
            "SELECT ci.*,
                    pd.name AS product_name,
                    p.product_code
             FROM {$this->db->table('cart_items')} ci
             LEFT JOIN {$this->db->table('products')} p ON p.id = ci.product_id
             LEFT JOIN {$this->db->table('product_translations')} pd
                 ON pd.product_id = ci.product_id AND pd.language_code = 'en'
             WHERE ci.cart_id = ?i
             ORDER BY ci.added_at ASC",
            $id
        );

        $cart['subtotal'] = 0;
        foreach ( $cart['items'] as $item ) {
            $cart['subtotal'] += (float) $item['unit_price'] * (int) $item['quantity'];
        }

        return new WP_REST_Response( $cart );
    }

    public function delete_cart( WP_REST_Request $request ): WP_REST_Response|WP_Error {
        $id = (int) $request['id'];

        $exists = $this->db->getField(
            "SELECT id FROM {$this->db->table('carts')} WHERE id = ?i LIMIT 1",
            $id
        );
        if ( ! $exists ) {
            return new WP_Error( 'tc_not_found', 'Cart not found.', [ 'status' => 404 ] );
        }

        $this->db->delete( 'cart_items', [ 'cart_id' => $id ] );
        $this->db->delete( 'carts', [ 'id' => $id ] );

        return new WP_REST_Response( [ 'deleted' => true, 'id' => $id ] );
    }

    public function get_stats( WP_REST_Request $request ): WP_REST_Response {
        $ct = $this->db->table( 'carts' );
        $it = $this->db->table( 'cart_items' );

        $total_carts    = (int) $this->db->getField( "SELECT COUNT(*) FROM {$ct}" );
        $guest_carts    = (int) $this->db->getField( "SELECT COUNT(*) FROM {$ct} WHERE customer_id IS NULL" );
        $customer_carts = $total_carts - $guest_carts;
        $total_items    = (int) $this->db->getField( "SELECT COALESCE(SUM(quantity), 0) FROM {$it}" );
        $total_value    = (float) $this->db->getField( "SELECT COALESCE(SUM(unit_price * quantity), 0) FROM {$it}" );

        return new WP_REST_Response( [
            'total_carts'    => $total_carts,
            'guest_carts'    => $guest_carts,
            'customer_carts' => $customer_carts,
            'total_items'    => $total_items,
            'total_value'    => round( $total_value, 2 ),
        ] );
    }

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