<?php
/**
 * Form Builder REST Controller
 *
 * Admin and vendor endpoints for managing form templates.
 *
 * Solo mode:   Admin manages all templates (global + category + product).
 *              No vendor scope available.
 * Marketplace: Admin manages global/category defaults.
 *              Vendors manage vendor-scope and product-scope overrides.
 *
 * @package WahraRentalsBookings
 * @since   2.3.0
 */

defined('ABSPATH') || exit;

/**
 * Class WAHRB_Form_Builder_Controller
 */
class WAHRB_Form_Builder_Controller extends WAHRB_REST_Controller {

    /**
     * Route base
     *
     * @var string
     */
    protected $rest_base = 'form-templates';

    /**
     * Register routes
     */
    public function register_routes(): void {

        // Admin: List / Create form templates
        register_rest_route($this->namespace, '/admin/' . $this->rest_base, [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_admin_templates'],
                'permission_callback' => [$this, 'check_admin_permission'],
            ],
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'create_admin_template'],
                'permission_callback' => [$this, 'check_admin_permission'],
                'args'                => $this->get_template_create_args(),
            ],
        ]);

        // Admin: Single template (Get / Update / Delete)
        register_rest_route($this->namespace, '/admin/' . $this->rest_base . '/(?P<id>[\d]+)', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_admin_template'],
                'permission_callback' => [$this, 'check_admin_permission'],
            ],
            [
                'methods'             => WP_REST_Server::EDITABLE,
                'callback'            => [$this, 'update_admin_template'],
                'permission_callback' => [$this, 'check_admin_permission'],
                'args'                => $this->get_template_update_args(),
            ],
            [
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => [$this, 'delete_admin_template'],
                'permission_callback' => [$this, 'check_admin_permission'],
            ],
        ]);

        // Vendor: List own templates + global/category templates
        register_rest_route($this->namespace, '/vendor/' . $this->rest_base, [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_vendor_templates'],
                'permission_callback' => [$this, 'check_vendor_permission'],
            ],
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'create_vendor_template'],
                'permission_callback' => [$this, 'check_vendor_permission'],
                'args'                => $this->get_template_create_args(),
            ],
        ]);

        // Vendor: Single template (Update / Delete own)
        register_rest_route($this->namespace, '/vendor/' . $this->rest_base . '/(?P<id>[\d]+)', [
            [
                'methods'             => WP_REST_Server::EDITABLE,
                'callback'            => [$this, 'update_vendor_template'],
                'permission_callback' => [$this, 'check_vendor_permission'],
                'args'                => $this->get_template_update_args(),
            ],
            [
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => [$this, 'delete_vendor_template'],
                'permission_callback' => [$this, 'check_vendor_permission'],
            ],
        ]);

        // Public: Get form fields for a product
        register_rest_route($this->namespace, '/' . $this->rest_base . '/product/(?P<product_id>[\d]+)', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_product_form'],
                'permission_callback' => '__return_true',
            ],
        ]);

        // Public: Get available field types
        register_rest_route($this->namespace, '/' . $this->rest_base . '/field-types', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_field_types'],
                'permission_callback' => '__return_true',
            ],
        ]);

        // Public: Get field types grouped (for builder UI)
        register_rest_route($this->namespace, '/' . $this->rest_base . '/field-types-grouped', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_field_types_grouped'],
                'permission_callback' => '__return_true',
            ],
        ]);

        // Auth: Get allowed scopes for current user
        register_rest_route($this->namespace, '/' . $this->rest_base . '/allowed-scopes', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_allowed_scopes'],
                'permission_callback' => [$this, 'check_vendor_permission'],
            ],
        ]);
    }

    // ──────────────────────────────────────────────────────────────
    // Admin Callbacks
    // ──────────────────────────────────────────────────────────────

    /**
     * List all form templates (Admin view)
     *
     * @param WP_REST_Request $request Request
     * @return WP_REST_Response
     */
    public function get_admin_templates($request) {
        $form_builder = WAHRB_Form_Builder::instance();

        $args = [];
        if ($request->get_param('scope')) {
            $args['scope'] = sanitize_text_field($request->get_param('scope'));
        }
        if ($request->get_param('category_slug')) {
            $args['category_slug'] = sanitize_text_field($request->get_param('category_slug'));
        }

        $templates = $form_builder->get_templates($args);

        return $this->success($templates);
    }

    /**
     * Get single template (Admin)
     *
     * @param WP_REST_Request $request Request
     * @return WP_REST_Response|WP_Error
     */
    public function get_admin_template($request) {
        $form_builder = WAHRB_Form_Builder::instance();
        $template = $form_builder->get_template(absint($request['id']));

        if (!$template) {
            return $this->error('not_found', __('Form template not found.', 'wahra-rentals-bookings'), 404);
        }

        return $this->success($template);
    }

    /**
     * Create form template (Admin)
     *
     * @param WP_REST_Request $request Request
     * @return WP_REST_Response|WP_Error
     */
    public function create_admin_template($request) {
        $form_builder = WAHRB_Form_Builder::instance();

        $data = [
            'template_name' => $request->get_param('template_name'),
            'description'   => $request->get_param('description') ?? '',
            'scope'         => $request->get_param('scope') ?? 'global',
            'category_slug' => $request->get_param('category_slug') ?? '',
            'product_id'    => $request->get_param('product_id') ?? 0,
            'vendor_id'     => $request->get_param('vendor_id') ?? 0,
            'fields'        => $request->get_param('fields') ?? [],
            'is_active'     => $request->get_param('is_active') ?? true,
            'sort_order'    => $request->get_param('sort_order') ?? 0,
        ];

        $template_id = $form_builder->create_template($data);

        if (!$template_id) {
            return $this->error('create_failed', __('Failed to create form template. Ensure at least one valid field is defined.', 'wahra-rentals-bookings'), 400);
        }

        return $this->success([
            'template_id' => $template_id,
            'message'     => __('Form template created.', 'wahra-rentals-bookings'),
        ], 201);
    }

    /**
     * Update form template (Admin)
     *
     * @param WP_REST_Request $request Request
     * @return WP_REST_Response|WP_Error
     */
    public function update_admin_template($request) {
        $form_builder = WAHRB_Form_Builder::instance();
        $template_id = absint($request['id']);

        $existing = $form_builder->get_template($template_id);
        if (!$existing) {
            return $this->error('not_found', __('Form template not found.', 'wahra-rentals-bookings'), 404);
        }

        $data = array_filter($request->get_params(), function ($key) {
            return in_array($key, ['template_name', 'description', 'scope', 'category_slug', 'product_id', 'vendor_id', 'fields', 'is_active', 'sort_order'], true);
        }, ARRAY_FILTER_USE_KEY);

        $updated = $form_builder->update_template($template_id, $data);

        if (!$updated) {
            return $this->error('update_failed', __('Failed to update form template.', 'wahra-rentals-bookings'), 400);
        }

        return $this->success(['message' => __('Form template updated.', 'wahra-rentals-bookings')]);
    }

    /**
     * Delete form template (Admin)
     *
     * @param WP_REST_Request $request Request
     * @return WP_REST_Response|WP_Error
     */
    public function delete_admin_template($request) {
        $form_builder = WAHRB_Form_Builder::instance();
        $template_id = absint($request['id']);

        $existing = $form_builder->get_template($template_id);
        if (!$existing) {
            return $this->error('not_found', __('Form template not found.', 'wahra-rentals-bookings'), 404);
        }

        $form_builder->delete_template($template_id);

        return $this->success(['message' => __('Form template deleted.', 'wahra-rentals-bookings')]);
    }

    // ──────────────────────────────────────────────────────────────
    // Vendor Callbacks
    // ──────────────────────────────────────────────────────────────

    /**
     * List vendor's own templates plus global/category defaults
     *
     * @param WP_REST_Request $request Request
     * @return WP_REST_Response
     */
    public function get_vendor_templates($request) {
        $form_builder = WAHRB_Form_Builder::instance();
        $vendor_id = get_current_user_id();

        $templates = $form_builder->get_templates([
            'vendor_id'        => $vendor_id,
            'include_defaults' => true,
        ]);

        return $this->success($templates);
    }

    /**
     * Create vendor form template
     *
     * Solo mode:   Only product scope (admin is the sole vendor)
     * Marketplace: vendor or product scope
     *
     * @param WP_REST_Request $request Request
     * @return WP_REST_Response|WP_Error
     */
    public function create_vendor_template($request) {
        $form_builder = WAHRB_Form_Builder::instance();
        $vendor_id = get_current_user_id();

        $scope = $request->get_param('scope') ?? 'vendor';
        $allowed_scopes = WAHRB_Form_Builder::get_allowed_scopes('vendor');

        // Enforce allowed scopes for current mode
        if (!in_array($scope, $allowed_scopes, true)) {
            if (wahrb_is_dokan_active()) {
                return $this->error('invalid_scope', __('Vendors can only create vendor or product-level form templates.', 'wahra-rentals-bookings'), 403);
            }
            return $this->error('invalid_scope', __('In Solo mode, only product-level form templates can be created here.', 'wahra-rentals-bookings'), 403);
        }

        // If product scope, verify vendor owns the product
        $product_id = absint($request->get_param('product_id') ?? 0);
        if ($scope === 'product' && $product_id > 0) {
            $product_author = (int) get_post_field('post_author', $product_id);
            if ($product_author !== $vendor_id) {
                return $this->error('forbidden', __('You do not own this product.', 'wahra-rentals-bookings'), 403);
            }
        }

        $data = [
            'template_name' => $request->get_param('template_name'),
            'description'   => $request->get_param('description') ?? '',
            'scope'         => $scope,
            'category_slug' => $request->get_param('category_slug') ?? '',
            'product_id'    => $product_id,
            'vendor_id'     => $vendor_id,
            'fields'        => $request->get_param('fields') ?? [],
            'is_active'     => $request->get_param('is_active') ?? true,
            'sort_order'    => $request->get_param('sort_order') ?? 0,
        ];

        $template_id = $form_builder->create_template($data);

        if (!$template_id) {
            return $this->error('create_failed', __('Failed to create form template.', 'wahra-rentals-bookings'), 400);
        }

        return $this->success([
            'template_id' => $template_id,
            'message'     => __('Form template created.', 'wahra-rentals-bookings'),
        ], 201);
    }

    /**
     * Update vendor form template (own only)
     *
     * @param WP_REST_Request $request Request
     * @return WP_REST_Response|WP_Error
     */
    public function update_vendor_template($request) {
        $form_builder = WAHRB_Form_Builder::instance();
        $vendor_id = get_current_user_id();
        $template_id = absint($request['id']);

        $existing = $form_builder->get_template($template_id);
        if (!$existing) {
            return $this->error('not_found', __('Form template not found.', 'wahra-rentals-bookings'), 404);
        }

        // Ensure vendor owns this template
        if ((int) $existing['vendor_id'] !== $vendor_id) {
            return $this->error('forbidden', __('You can only edit your own form templates.', 'wahra-rentals-bookings'), 403);
        }

        $data = array_filter($request->get_params(), function ($key) {
            return in_array($key, ['template_name', 'description', 'fields', 'is_active', 'sort_order', 'category_slug'], true);
        }, ARRAY_FILTER_USE_KEY);

        $updated = $form_builder->update_template($template_id, $data);

        if (!$updated) {
            return $this->error('update_failed', __('Failed to update form template.', 'wahra-rentals-bookings'), 400);
        }

        return $this->success(['message' => __('Form template updated.', 'wahra-rentals-bookings')]);
    }

    /**
     * Delete vendor form template (own only)
     *
     * @param WP_REST_Request $request Request
     * @return WP_REST_Response|WP_Error
     */
    public function delete_vendor_template($request) {
        $form_builder = WAHRB_Form_Builder::instance();
        $vendor_id = get_current_user_id();
        $template_id = absint($request['id']);

        $existing = $form_builder->get_template($template_id);
        if (!$existing) {
            return $this->error('not_found', __('Form template not found.', 'wahra-rentals-bookings'), 404);
        }

        if ((int) $existing['vendor_id'] !== $vendor_id) {
            return $this->error('forbidden', __('You can only delete your own form templates.', 'wahra-rentals-bookings'), 403);
        }

        $form_builder->delete_template($template_id);

        return $this->success(['message' => __('Form template deleted.', 'wahra-rentals-bookings')]);
    }

    // ──────────────────────────────────────────────────────────────
    // Public Callbacks
    // ──────────────────────────────────────────────────────────────

    /**
     * Get resolved form fields for a product (public)
     *
     * @param WP_REST_Request $request Request
     * @return WP_REST_Response
     */
    public function get_product_form($request) {
        $product_id = absint($request['product_id']);

        $form_builder = WAHRB_Form_Builder::instance();
        $template = $form_builder->get_form_for_product($product_id);

        if (!$template || empty($template['fields'])) {
            return $this->success([
                'has_form' => false,
                'fields'   => [],
            ]);
        }

        return $this->success([
            'has_form'      => true,
            'template_id'   => (int) $template['template_id'],
            'template_name' => $template['template_name'],
            'fields'        => $template['fields'],
        ]);
    }

    /**
     * Get available field types (flat list)
     *
     * @return WP_REST_Response
     */
    public function get_field_types() {
        return $this->success(WAHRB_Form_Builder::get_field_types());
    }

    /**
     * Get field types grouped by category (for builder drag-and-drop UI)
     *
     * @return WP_REST_Response
     */
    public function get_field_types_grouped() {
        return $this->success(WAHRB_Form_Builder::get_field_types_grouped());
    }

    /**
     * Get allowed scopes for the current user's role & operating mode
     *
     * @return WP_REST_Response
     */
    public function get_allowed_scopes() {
        $role = current_user_can('manage_woocommerce') ? 'admin' : 'vendor';

        return $this->success([
            'mode'           => wahrb_get_mode(),
            'role'           => $role,
            'allowed_scopes' => WAHRB_Form_Builder::get_allowed_scopes($role),
        ]);
    }

    // ──────────────────────────────────────────────────────────────
    // Args Definitions
    // ──────────────────────────────────────────────────────────────

    /**
     * Get create args
     *
     * @return array
     */
    private function get_template_create_args(): array {
        return [
            'template_name' => [
                'type'     => 'string',
                'required' => true,
            ],
            'description' => [
                'type'    => 'string',
                'default' => '',
            ],
            'scope' => [
                'type'    => 'string',
                'default' => 'global',
                'enum'    => ['global', 'category', 'product', 'vendor'],
            ],
            'category_slug' => [
                'type'    => 'string',
                'default' => '',
            ],
            'product_id' => [
                'type'    => 'integer',
                'default' => 0,
            ],
            'vendor_id' => [
                'type'    => 'integer',
                'default' => 0,
            ],
            'fields' => [
                'type'     => 'array',
                'required' => true,
            ],
            'is_active' => [
                'type'    => 'boolean',
                'default' => true,
            ],
            'sort_order' => [
                'type'    => 'integer',
                'default' => 0,
            ],
        ];
    }

    /**
     * Get update args
     *
     * @return array
     */
    private function get_template_update_args(): array {
        return [
            'template_name' => ['type' => 'string'],
            'description'   => ['type' => 'string'],
            'scope'         => ['type' => 'string', 'enum' => ['global', 'category', 'product', 'vendor']],
            'category_slug' => ['type' => 'string'],
            'product_id'    => ['type' => 'integer'],
            'vendor_id'     => ['type' => 'integer'],
            'fields'        => ['type' => 'array'],
            'is_active'     => ['type' => 'boolean'],
            'sort_order'    => ['type' => 'integer'],
        ];
    }
}
