<?php

namespace FleekDash\API\Comments;

use FleekDash\API\Posts\PostsDataFormatter;
use WP_Comment;

/**
 * Comments Data Mapper
 *
 * Handles mapping WordPress comments to API response format
 * Extracted from FLEEKDASH_Comments_Optimized_API for better organization
 *
 * @package FleekDash\API\Comments
 * @since 2.2.0
 */
class CommentsDataMapper
{
    /**
     * Map WordPress comment object to array format
     *
     * @param WP_Comment $comment WordPress comment object
     * @return array Formatted comment data
     */
    public function mapCommentToArray($comment)
    {
        $post = \get_post($comment->comment_post_ID);
        $frontend_status = $this->mapCommentStatus($comment->comment_approved);
        $author_data = $this->getAuthorData($comment);
        $parent_data = $this->getParentData($comment->comment_parent);

        return [
            'id' => $comment->comment_ID,
            'author' => $author_data,
            'content' => $comment->comment_content,
            'status' => $frontend_status,
            'date' => \mysql_to_rfc3339($comment->comment_date),
            'relative_date' => PostsDataFormatter::getRelativeTime($comment->comment_date),
            'post_title' => $post ? $post->post_title : 'Unknown Post',
            'post_id' => $comment->comment_post_ID,
            'post_type' => $post ? $post->post_type : 'post',
            'post_url' => $post ? get_permalink($post->ID) : '',
            'parent_id' => $comment->comment_parent,
            'parent_author' => $parent_data['author'] ?? '',
            'ip_address' => $comment->comment_author_IP,
            'user_agent' => $comment->comment_agent,
            'approved_date' => $comment->comment_approved === '1' ? \mysql_to_rfc3339($comment->comment_date) : '',
            'created_date' => \mysql_to_rfc3339($comment->comment_date),
            'updated_date' => \mysql_to_rfc3339($comment->comment_date),
        ];
    }

    /**
     * Map WordPress comment status to frontend status
     *
     * @param string $wp_status WordPress comment status
     * @return string Frontend status
     */
    private function mapCommentStatus($wp_status)
    {
        $status_mapping = [
            'approve' => 'approved',
            '1' => 'approved',
            'hold' => 'pending',
            '0' => 'pending',
            'spam' => 'spam',
            'trash' => 'trash',
        ];

        return $status_mapping[$wp_status] ?? $wp_status;
    }

    /**
     * Get comment author data
     *
     * @param WP_Comment $comment Comment object
     * @return array Author data
     */
    private function getAuthorData($comment)
    {
        if ($comment->user_id) {
            // Registered user
            $user = \get_userdata($comment->user_id);
            
            if ($user) {
                return [
                    'id' => (string) $user->ID,
                    'name' => $user->display_name,
                    'email' => $user->user_email,
                    'avatarUrl' => get_avatar_url($user->ID, ['size' => 32]),
                    'username' => $user->user_login,
                ];
            }
        }

        // Guest commenter
        return [
            'id' => 'guest_' . md5($comment->comment_author_email),
            'name' => $comment->comment_author,
            'email' => $comment->comment_author_email,
            'avatarUrl' => get_avatar_url($comment->comment_author_email, ['size' => 32]),
            'username' => 'guest',
        ];
    }

    /**
     * Get parent comment data
     *
     * @param int $parent_id Parent comment ID
     * @return array Parent data
     */
    private function getParentData($parent_id)
    {
        if (!$parent_id) {
            return [
                'author' => '',
                'content' => '',
            ];
        }

        $parent_author = get_comment_author($parent_id);
        $parent_comment = \get_comment($parent_id);

        return [
            'author' => $parent_author ?: '',
            'content' => $parent_comment ? $parent_comment->comment_content : '',
        ];
    }

    /**
     * Map multiple comments to array
     *
     * @param array $comments Array of WP_Comment objects
     * @return array Array of formatted comments
     */
    public function mapCommentsToArray($comments)
    {
        if (empty($comments) || !is_array($comments)) {
            return [];
        }

        $formatted_comments = [];

        foreach ($comments as $comment) {
            if (!$comment instanceof WP_Comment) {
                continue;
            }

            $formatted_comments[] = $this->mapCommentToArray($comment);
        }

        return $formatted_comments;
    }

    /**
     * Get comment statistics
     *
     * @return array Comment stats
     */
    public function getCommentStats()
    {
        global $wpdb;

        // Get counts by status
        $stats = $wpdb->get_results(
            "SELECT comment_approved AS status, COUNT(*) AS count FROM {$wpdb->comments} WHERE comment_type = '' GROUP BY comment_approved",
            ARRAY_A
        );

        $formatted_stats = [
            'total' => 0,
            'approved' => 0,
            'pending' => 0,
            'spam' => 0,
            'trash' => 0,
        ];

        foreach ($stats as $stat) {
            $count = (int) $stat['count'];
            $formatted_stats['total'] += $count;

            $status = $stat['status'];
            if ($status === '1' || $status === 'approve') {
                $formatted_stats['approved'] += $count;
            } elseif ($status === '0' || $status === 'hold') {
                $formatted_stats['pending'] += $count;
            } elseif ($status === 'spam') {
                $formatted_stats['spam'] += $count;
            } elseif ($status === 'trash') {
                $formatted_stats['trash'] += $count;
            }
        }

        return $formatted_stats;
    }

    /**
     * Get comments metadata (authors, posts, etc)
     *
     * @return array Metadata
     */
    public function getCommentsMetadata()
    {
        global $wpdb;

        // Get unique comment authors
        $authors = $wpdb->get_results(
            "SELECT DISTINCT comment_author, comment_author_email, user_id FROM {$wpdb->comments} WHERE comment_type = '' AND comment_approved != 'spam' ORDER BY comment_author ASC",
            ARRAY_A
        );

        $formatted_authors = [];
        foreach ($authors as $author) {
            $formatted_authors[] = [
                'name' => $author['comment_author'],
                'email' => $author['comment_author_email'],
                'user_id' => $author['user_id'] ? (int) $author['user_id'] : null,
            ];
        }

        // Get posts with comments
        $posts_with_comments = $wpdb->get_results(
            "SELECT DISTINCT comment_post_ID AS post_id, COUNT(*) AS comment_count FROM {$wpdb->comments} WHERE comment_type = '' AND comment_approved != 'spam' GROUP BY comment_post_ID ORDER BY comment_count DESC LIMIT 20",
            ARRAY_A
        );

        $formatted_posts = [];
        foreach ($posts_with_comments as $post_data) {
            $post = \get_post($post_data['post_id']);
            if ($post) {
                $formatted_posts[] = [
                    'id' => $post->ID,
                    'title' => $post->post_title,
                    'comment_count' => (int) $post_data['comment_count'],
                ];
            }
        }

        return [
            'authors' => $formatted_authors,
            'posts' => $formatted_posts,
        ];
    }
}

