<?php

/**
 * Subscription Notes REST Controller
 *
 * REST API endpoints for subscription notes management.
 *
 * @package ArraySubs\Features\SubscriptionNotes\REST
 */

namespace ArraySubs\Features\SubscriptionNotes\REST;

defined('ABSPATH') || exit;

use ArraySubs\Supports\BaseRestController;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

/**
 * Notes REST controller
 */
class NotesController extends BaseRestController
{
    /**
     * Enable auto-loading
     *
     * @var bool
     */
    public static $loadable = true;

    /**
     * Initialize controller
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Register REST routes
     *
     * @return void
     */
    public function registerRoutes(): void
    {
        // Get notes for a subscription
        register_rest_route(
            $this->namespace,
            '/subscriptions/(?P<id>\d+)/notes',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [$this, 'getNotes'],
                    'permission_callback' => [$this, 'getNotesPermission'],
                    'args'                => [
                        'id' => [
                            'required'          => true,
                            'type'              => 'integer',
                            'sanitize_callback' => 'absint',
                        ],
                        'type' => [
                            'type'    => 'string',
                            'enum'    => ['all', 'private', 'customer'],
                            'default' => 'all',
                        ],
                        'per_page' => [
                            'type'              => 'integer',
                            'default'           => 50,
                            'sanitize_callback' => 'absint',
                        ],
                        'page' => [
                            'type'              => 'integer',
                            'default'           => 1,
                            'sanitize_callback' => 'absint',
                        ],
                    ],
                ],
                [
                    'methods'             => 'POST',
                    'callback'            => [$this, 'addNote'],
                    'permission_callback' => [$this, 'addNotePermission'],
                    'args'                => [
                        'id' => [
                            'required'          => true,
                            'type'              => 'integer',
                            'sanitize_callback' => 'absint',
                        ],
                        'content' => [
                            'required' => true,
                            'type'     => 'string',
                        ],
                        'type' => [
                            'type'    => 'string',
                            'enum'    => ['private', 'customer'],
                            'default' => 'private',
                        ],
                    ],
                ],
            ]
        );

        // Delete a note
        register_rest_route(
            $this->namespace,
            '/subscriptions/(?P<id>\d+)/notes/(?P<note_id>\d+)',
            [
                'methods'             => 'DELETE',
                'callback'            => [$this, 'deleteNote'],
                'permission_callback' => [$this, 'deleteNotePermission'],
                'args'                => [
                    'id' => [
                        'required'          => true,
                        'type'              => 'integer',
                        'sanitize_callback' => 'absint',
                    ],
                    'note_id' => [
                        'required'          => true,
                        'type'              => 'integer',
                        'sanitize_callback' => 'absint',
                    ],
                ],
            ]
        );
    }

    /**
     * Permission check for getting notes
     *
     * Admin can see all notes, customer can see only their own subscription's customer notes
     *
     * @param WP_REST_Request $request The request object.
     * @return bool|WP_Error
     */
    public function getNotesPermission(WP_REST_Request $request)
    {
        // Admins can see all
        if (current_user_can('manage_woocommerce') || current_user_can('manage_options')) {
            return true;
        }

        if (!is_user_logged_in()) {
            return new WP_Error(
                'rest_forbidden',
                __('You must be logged in to view notes.', 'arraysubs'),
                ['status' => 401]
            );
        }

        // Check if customer owns this subscription
        $subscription_id = $request->get_param('id');
        $subscription = get_post($subscription_id);

        if (!$subscription || $subscription->post_type !== 'arraysubs_data') {
            return new WP_Error(
                'rest_forbidden',
                __('Invalid subscription.', 'arraysubs'),
                ['status' => 404]
            );
        }

        $customer_id = (int) get_post_meta($subscription_id, '_customer_id', true);

        if ($customer_id <= 0) {
            return new WP_Error(
                'rest_forbidden',
                __('Invalid subscription customer.', 'arraysubs'),
                ['status' => 403]
            );
        }

        if ($customer_id !== get_current_user_id()) {
            return new WP_Error(
                'rest_forbidden',
                __('You do not have permission to view these notes.', 'arraysubs'),
                ['status' => 403]
            );
        }

        return true;
    }

    /**
     * Permission check for adding notes - Admin only
     *
     * @param WP_REST_Request $request The request object.
     * @return bool|WP_Error
     */
    public function addNotePermission(WP_REST_Request $request)
    {
        if (!current_user_can('manage_woocommerce') && !current_user_can('manage_options')) {
            return new WP_Error(
                'rest_forbidden',
                __('You do not have permission to add notes.', 'arraysubs'),
                ['status' => 403]
            );
        }

        return true;
    }

    /**
     * Permission check for deleting notes - Admin only
     *
     * @param WP_REST_Request $request The request object.
     * @return bool|WP_Error
     */
    public function deleteNotePermission(WP_REST_Request $request)
    {
        if (!current_user_can('manage_woocommerce') && !current_user_can('manage_options')) {
            return new WP_Error(
                'rest_forbidden',
                __('You do not have permission to delete notes.', 'arraysubs'),
                ['status' => 403]
            );
        }

        return true;
    }

    /**
     * Get notes for a subscription
     *
     * @param WP_REST_Request $request The request object.
     * @return WP_REST_Response|WP_Error
     */
    public function getNotes(WP_REST_Request $request)
    {
        $subscription_id = $request->get_param('id');
        $type            = $request->get_param('type');
        $per_page        = $request->get_param('per_page');
        $page            = $request->get_param('page');

        // Non-admin users can only see customer notes
        if (!current_user_can('manage_woocommerce') && !current_user_can('manage_options')) {
            $type = 'customer';
        }

        $notes = arraysubs_get_subscription_notes($subscription_id, [
            'type'     => $type,
            'per_page' => $per_page,
            'page'     => $page,
        ]);

        $formatted_notes = [];
        foreach ($notes as $note) {
            $formatted_notes[] = arraysubs_format_note($note);
        }

        $total = arraysubs_count_subscription_notes($subscription_id, $type);

        return arraysubs_rest_response(
            [
                'notes'       => $formatted_notes,
                'total'       => $total,
                'total_pages' => $per_page > 0 ? ceil($total / $per_page) : 1,
                'page'        => $page,
            ],
            200,
            __('Notes retrieved successfully.', 'arraysubs')
        );
    }

    /**
     * Add a note to a subscription
     *
     * @param WP_REST_Request $request The request object.
     * @return WP_REST_Response|WP_Error
     */
    public function addNote(WP_REST_Request $request)
    {
        $subscription_id = $request->get_param('id');
        $content         = $request->get_param('content');
        $type            = $request->get_param('type');

        // Validate content
        if (empty(trim($content))) {
            return new WP_Error(
                'empty_content',
                __('Note content cannot be empty.', 'arraysubs'),
                ['status' => 400]
            );
        }

        $note_id = arraysubs_add_subscription_note(
            $subscription_id,
            $content,
            $type,
            get_current_user_id(),
            [],
            'subscription'
        );

        if (is_wp_error($note_id)) {
            return $note_id;
        }

        $note = arraysubs_get_subscription_note($note_id);

        return arraysubs_rest_response(
            [
                'note' => arraysubs_format_note($note),
            ],
            201,
            __('Note added successfully.', 'arraysubs')
        );
    }

    /**
     * Delete a subscription note
     *
     * @param WP_REST_Request $request The request object.
     * @return WP_REST_Response|WP_Error
     */
    public function deleteNote(WP_REST_Request $request)
    {
        $subscription_id = $request->get_param('id');
        $note_id         = $request->get_param('note_id');

        // Verify note belongs to this subscription
        $note = arraysubs_get_subscription_note($note_id);

        if (!$note) {
            return new WP_Error(
                'note_not_found',
                __('Note not found.', 'arraysubs'),
                ['status' => 404]
            );
        }

        $note_subscription_id = (int) get_post_meta($note_id, '_subscription_id', true);

        if ($note_subscription_id !== $subscription_id) {
            return new WP_Error(
                'note_mismatch',
                __('Note does not belong to this subscription.', 'arraysubs'),
                ['status' => 400]
            );
        }

        $deleted = arraysubs_delete_subscription_note($note_id);

        if (!$deleted) {
            return new WP_Error(
                'delete_failed',
                __('Failed to delete note.', 'arraysubs'),
                ['status' => 500]
            );
        }

        return arraysubs_rest_response(
            ['deleted' => true],
            200,
            __('Note deleted successfully.', 'arraysubs')
        );
    }
}
