<?php

namespace PloverCRM\Core\Api\V1;

use PloverCRM\Core\Api\AbstractEndpoint;
use PloverCRM\Common\Permissions;
use WP_REST_Request;

/**
 * Notes Endpoint
 * 
 * GET    /wp-json/plover-crm/v1/contacts/{contact_id}/notes
 * POST   /wp-json/plover-crm/v1/contacts/{contact_id}/notes
 * PUT    /wp-json/plover-crm/v1/notes/{id}
 * DELETE /wp-json/plover-crm/v1/notes/{id}
 */
class NotesEndpoint extends AbstractEndpoint
{
    public function getRoute(): string
    {
        return '/(?:contacts/(?P<contact_id>\d+)/notes|notes/(?P<id>\d+))';
    }

    public function getMethod()
    {
        return ['GET', 'POST', 'PUT', 'DELETE'];
    }

    public function handle(WP_REST_Request $request)
    {
        $crm = $this->container->get('crm');

        if (!$crm->isAvailable()) {
            return $this->error('CRM service is currently unavailable', 503, 'crm_unavailable');
        }

        $method = $request->get_method();
        $contact_id = $request->get_param('contact_id');
        $note_id = $request->get_param('id');

        switch ($method) {
            case 'GET':
                return $this->listNotes($crm, $contact_id, $request);
            
            case 'POST':
                return $this->createNote($crm, $contact_id, $request);
            
            case 'PUT':
                return $this->updateNote($crm, $note_id, $request);
            
            case 'DELETE':
                return $this->deleteNote($crm, $note_id, $request);
            
            default:
                return $this->error('The requested method is not supported for this endpoint', 405);
        }
    }

    /**
     * List notes for a contact
     */
    private function listNotes($crm, $contact_id, WP_REST_Request $request)
    {
        // Check read permission
        if (!Permissions::canAccessEntity('notes', 'read')) {
            return $this->error('You do not have permission to view notes', 403, 'notes_read_permission_denied');
        }

        if (empty($contact_id)) {
            return $this->error('Contact ID is required', 400, 'missing_contact_id');
        }

        // Verify contact exists
        $contact = $crm->getContact(intval($contact_id));
        if (!$contact) {
            return $this->error('The requested contact does not exist', 404, 'contact_not_found');
        }

        $page = max(1, intval($request->get_param('page') ?? 1));
        $per_page = min(100, max(1, intval($request->get_param('per_page') ?? 20)));

        $result = $crm->getContactNotes(intval($contact_id), [
            'page' => $page,
            'per_page' => $per_page,
        ]);

        return $this->success($result['notes'], [
            'total' => $result['total'],
            'page' => $page,
            'per_page' => $per_page,
            'total_pages' => ceil($result['total'] / $per_page),
        ]);
    }

    /**
     * Create note
     */
    private function createNote($crm, $contact_id, WP_REST_Request $request)
    {
        // Check create permission
        if (!Permissions::canAccessEntity('notes', 'create')) {
            return $this->error('You do not have permission to create notes', 403, 'notes_create_permission_denied');
        }

        if (empty($contact_id)) {
            return $this->error('Contact ID is required', 400, 'missing_contact_id');
        }

        // Verify contact exists
        $contact = $crm->getContact(intval($contact_id));
        if (!$contact) {
            return $this->error('The requested contact does not exist', 404, 'contact_not_found');
        }

        $data = $request->get_json_params();

        if (empty($data['title']) || empty($data['description'])) {
            return $this->error('Both title and description are required', 400, 'missing_required_fields');
        }

        $note_id = $crm->addContactNote(intval($contact_id), $data);

        if (!$note_id) {
            return $this->error('Unable to create note', 500, 'note_creation_failed');
        }

        return $this->success(['id' => $note_id], ['created' => true], 201);
    }

    /**
     * Update note
     */
    private function updateNote($crm, $note_id, WP_REST_Request $request)
    {
        // Check update permission
        if (!Permissions::canAccessEntity('notes', 'update')) {
            return $this->error('You do not have permission to update notes', 403, 'notes_update_permission_denied');
        }

        if (empty($note_id)) {
            return $this->error('Note ID is required', 400, 'missing_note_id');
        }

        $data = $request->get_json_params();
        
        // Require contact_id for validation
        if (empty($data['contact_id'])) {
            return $this->error('Contact ID is required', 400, 'missing_contact_id');
        }

        $result = $crm->updateNote(intval($note_id), $data);

        if (!$result) {
            return $this->error('The requested note does not exist', 404, 'note_not_found');
        }

        return $this->success(['updated' => true]);
    }

    /**
     * Delete note
     */
    private function deleteNote($crm, $note_id, WP_REST_Request $request)
    {
        // Check delete permission
        if (!Permissions::canAccessEntity('notes', 'delete')) {
            return $this->error('You do not have permission to delete notes', 403, 'notes_delete_permission_denied');
        }

        if (empty($note_id)) {
            return $this->error('Note ID is required', 400, 'missing_note_id');
        }
        
        // Require contact_id as query parameter for validation
        $contact_id = $request->get_param('contact_id');
        if (empty($contact_id)) {
            return $this->error('Contact ID is required', 400, 'missing_contact_id');
        }

        $result = $crm->deleteNote(intval($note_id), ['contact_id' => intval($contact_id)]);

        if (!$result) {
            return $this->error('The requested note does not exist', 404, 'note_not_found');
        }

        return $this->success(['deleted' => true]);
    }
}
