<?php

namespace PloverCRM\Modules\NativeCRM;

use PloverCRM\Common\CrmUserManager;
use PloverCRM\Modules\NativeCRM\Services\Logger;

/**
 * Notes Manager
 * 
 * Manages contact notes using WordPress comments table
 */
class NotesManager
{
    private const CREATED_BY_CRM_USER_META_KEY = 'plover_crm_created_by_user_id';

    /**
     * @var Logger
     */
    private $logger;
    /**
     * Get logger instance
     */
    private function getLogger(): Logger
    {
        if (!$this->logger) {
            $this->logger = new Logger();
        }
        return $this->logger;
    }

    /**
     * Get available note types
     * 
     * @return array
     */
    public static function getNoteTypes(): array
    {
        return [
            'call' => 'Call',
            'email' => 'Email',
            'meeting' => 'Meeting',
            'task' => 'Task',
            'note' => 'Note',
        ];
    }

    /**
     * Get notes for a contact
     * 
     * @param int $contact_id
     * @param int $page
     * @param int $per_page
     * @return array Array with 'notes' and 'total' keys
     */
    public function getContactNotes(int $contact_id, int $page = 1, int $per_page = 20): array
    {
        // Get total count
        $total_args = [
            'post_id' => $contact_id,
            'type' => 'plover_crm_note',
            'status' => 'approve',
            'count' => true,
        ];
        
        $total = get_comments($total_args);

        // Get paginated notes
        $args = [
            'post_id' => $contact_id,
            'type' => 'plover_crm_note',
            'status' => 'approve',
            'orderby' => 'comment_date',
            'order' => 'DESC',
            'number' => $per_page,
            'offset' => ($page - 1) * $per_page,
        ];

        $comments = get_comments($args);
        $notes = [];

        foreach ($comments as $comment) {
            $created_by_name = $comment->comment_author;
            $createdByCrmUserId = (int) get_comment_meta($comment->comment_ID, self::CREATED_BY_CRM_USER_META_KEY, true);

            if (!$createdByCrmUserId && $comment->user_id) {
                $createdByCrmUserId = (int) (CrmUserManager::getPublicIdByWordPressUserId((int) $comment->user_id) ?: 0);
            }

            if ($createdByCrmUserId) {
                $crmUser = CrmUserManager::getPublicProfileById($createdByCrmUserId);
                if ($crmUser) {
                    $created_by_name = $crmUser['display_name'];
                }
            }
            
            $notes[] = [
                'id' => $comment->comment_ID,
                'subscriber_id' => $contact_id,
                'title' => get_comment_meta($comment->comment_ID, 'plover_crm_note_title', true),
                'description' => $comment->comment_content,
                'type' => get_comment_meta($comment->comment_ID, 'plover_crm_note_type', true) ?: 'note',
                'created_by' => $created_by_name,
                'created_at' => $comment->comment_date,
                'updated_at' => $comment->comment_date, // WordPress comments don't track updates separately
            ];
        }

        return [
            'notes' => $notes,
            'total' => $total,
        ];
    }

    /**
     * Add a note to a contact
     * 
     * @param int $contact_id
     * @param array $data
     * @return int|false Note ID or false on failure
     */
    public function addNote(int $contact_id, array $data)
    {
        $current_user = wp_get_current_user();
        $currentActor = CrmUserManager::getPublicProfileByWordPressUserId((int) $current_user->ID);

        if (!$currentActor) {
            return false;
        }
        
        // Get valid note types
        $valid_types = array_keys(self::getNoteTypes());
        
        // Validate type, default to 'note' if invalid or not provided
        $type = 'note';
        if (!empty($data['type']) && in_array($data['type'], $valid_types)) {
            $type = $data['type'];
        }

        $comment_data = [
            'comment_post_ID' => $contact_id,
            'comment_author' => $currentActor['display_name'],
            'comment_author_email' => $currentActor['email'],
            'comment_content' => sanitize_textarea_field($data['description'] ?? ''),
            'comment_type' => 'plover_crm_note',
            'comment_approved' => 1,
            'user_id' => (int) $currentActor['wp_user_id'],
        ];
        
        // Allow custom created_at timestamp
        if (!empty($data['created_at'])) {
            $comment_data['comment_date'] = $data['created_at'];
            $comment_data['comment_date_gmt'] = get_gmt_from_date($data['created_at']);
        }

        $note_id = wp_insert_comment($comment_data);

        if ($note_id) {
            // Save note title
            if (!empty($data['title'])) {
                update_comment_meta($note_id, 'plover_crm_note_title', sanitize_text_field($data['title']));
            }

            // Save note type (validated)
            update_comment_meta($note_id, 'plover_crm_note_type', sanitize_text_field($type));
            update_comment_meta($note_id, self::CREATED_BY_CRM_USER_META_KEY, (int) $currentActor['id']);
        }

        return $note_id;
    }

    /**
     * Update a note
     * 
     * @param int $note_id
     * @param array $data
     * @return bool
     */
    public function updateNote(int $note_id, array $data): bool
    {
        // Get the comment to verify it exists
        $comment = get_comment($note_id);
        if (!$comment || $comment->comment_type !== 'plover_crm_note') {
            return false;
        }
        
        // Verify note belongs to contact if contact_id is provided
        if (isset($data['contact_id']) && $comment->comment_post_ID != $data['contact_id']) {
            $this->getLogger()->logError('Note does not belong to specified contact', [
                'note_id' => $note_id,
                'expected_contact_id' => $data['contact_id'],
                'actual_contact_id' => $comment->comment_post_ID
            ]);
            return false;
        }
        
        $updated = false;
        
        // Update comment fields if provided
        if (isset($data['description']) || isset($data['created_at'])) {
            $comment_data = ['comment_ID' => $note_id];
            
            // Update description if provided
            if (isset($data['description'])) {
                $comment_data['comment_content'] = sanitize_textarea_field($data['description']);
            }
            
            // Update created_at if provided
            if (isset($data['created_at'])) {
                $comment_data['comment_date'] = $data['created_at'];
                $comment_data['comment_date_gmt'] = get_gmt_from_date($data['created_at']);
            }

            $result = wp_update_comment($comment_data);
            if ($result !== false) {
                $updated = true;
            }
        } else {
            // If no comment fields to update, consider it successful
            $updated = true;
        }

        // Update note title if provided
        if (isset($data['title'])) {
            update_comment_meta($note_id, 'plover_crm_note_title', sanitize_text_field($data['title']));
            $updated = true;
        }

        // Update note type if provided and valid
        if (isset($data['type'])) {
            $valid_types = array_keys(self::getNoteTypes());
            if (in_array($data['type'], $valid_types)) {
                update_comment_meta($note_id, 'plover_crm_note_type', sanitize_text_field($data['type']));
                $updated = true;
            }
        }

        return $updated;
    }

    /**
     * Delete a note
     * 
     * @param int $note_id
     * @param array $data Optional data (e.g., contact_id for validation)
     * @return bool
     */
    public function deleteNote(int $note_id, array $data = []): bool
    {
        // Get the comment to verify it exists
        $comment = get_comment($note_id);
        if (!$comment || $comment->comment_type !== 'plover_crm_note') {
            return false;
        }
        
        // Verify note belongs to contact if contact_id is provided
        if (isset($data['contact_id']) && $comment->comment_post_ID != $data['contact_id']) {
            $this->getLogger()->logError('Note does not belong to specified contact', [
                'note_id' => $note_id,
                'expected_contact_id' => $data['contact_id'],
                'actual_contact_id' => $comment->comment_post_ID
            ]);
            return false;
        }
        
        return wp_delete_comment($note_id, true);
    }
}
