<?php
/**
 * XiaoHongShu (小紅書) Publishing Service
 * Handles publishing content to XiaoHongShu via RPA adapter
 */

require_once __DIR__ . '/../config/config.php';

class XiaoHongShuService {
    private $db;

    public function __construct() {
        $this->db = Database::getInstance()->getConnection();
    }

    /**
     * Publish content to XiaoHongShu
     *
     * @param array $data Publication data
     * @return array Result
     */
    public function publish($data) {
        // Validate required fields
        $required = ['title', 'content'];
        foreach ($required as $field) {
            if (empty($data[$field])) {
                return ['success' => false, 'message' => "Missing required field: {$field}"];
            }
        }

        // Get XHS settings
        $settings = $this->getSettings();
        if (!$settings['success']) {
            return $settings;
        }

        $config = $settings['data'];

        // Check if XHS is enabled
        if (empty($config['ENABLED']) || $config['ENABLED'] !== '1') {
            return ['success' => false, 'message' => 'XiaoHongShu publishing is not enabled'];
        }

        // Validate configuration based on publisher mode
        $publisherMode = $config['PUBLISHER_MODE'] ?? 'rpa';

        if ($publisherMode === 'api') {
            return $this->publishViaAPI($config, $data);
        } else {
            return $this->publishViaRPA($config, $data);
        }
    }

    /**
     * Publish via official API (if available)
     *
     * @param array $config Configuration
     * @param array $data Publication data
     * @return array Result
     */
    private function publishViaAPI($config, $data) {
        if (empty($config['API_URL']) || empty($config['API_TOKEN'])) {
            return ['success' => false, 'message' => 'XiaoHongShu API configuration incomplete'];
        }

        // Prepare post data
        $postData = [
            'title' => $data['title'],
            'desc' => $data['content'],
            'type' => $data['type'] ?? 'normal' // normal, video
        ];

        // Add images if provided
        if (!empty($data['images'])) {
            $postData['image_list'] = is_array($data['images']) ? $data['images'] : [$data['images']];
        }

        // Add video if provided
        if (!empty($data['video_url'])) {
            $postData['video'] = [
                'url' => $data['video_url']
            ];
            if (!empty($data['cover_url'])) {
                $postData['video']['cover'] = $data['cover_url'];
            }
        }

        // Add topics/hashtags if provided
        if (!empty($data['topics'])) {
            $postData['topics'] = is_array($data['topics']) ? $data['topics'] : explode(',', $data['topics']);
        }

        // Add location if provided
        if (!empty($data['location'])) {
            $postData['poi_name'] = $data['location'];
        }

        // Add scheduled time if provided
        if (!empty($data['scheduled_time'])) {
            $postData['post_time'] = strtotime($data['scheduled_time']);
        }

        // Call XHS API
        $result = $this->callXHSAPI('/note/post', $config, $postData);

        if ($result['success']) {
            $this->logPublication([
                'platform' => 'xiaohongshu',
                'post_id' => $result['data']['note_id'] ?? null,
                'content' => $data['content'],
                'status' => 'published',
                'response' => json_encode($result['data'])
            ]);

            return [
                'success' => true,
                'data' => [
                    'note_id' => $result['data']['note_id'] ?? null,
                    'platform' => 'xiaohongshu'
                ]
            ];
        }

        $this->logPublication([
            'platform' => 'xiaohongshu',
            'post_id' => null,
            'content' => $data['content'],
            'status' => 'failed',
            'error_message' => $result['message']
        ]);

        return $result;
    }

    /**
     * Publish via RPA adapter
     *
     * @param array $config Configuration
     * @param array $data Publication data
     * @return array Result
     */
    private function publishViaRPA($config, $data) {
        if (empty($config['RPA_URL']) || empty($config['RPA_TOKEN'])) {
            return ['success' => false, 'message' => 'XiaoHongShu RPA configuration incomplete'];
        }

        // Prepare RPA task data
        $taskData = [
            'action' => 'publish',
            'data' => [
                'title' => $data['title'],
                'content' => $data['content']
            ]
        ];

        // Add images
        if (!empty($data['images'])) {
            $taskData['data']['images'] = is_array($data['images']) ? $data['images'] : [$data['images']];
        }

        // Add video
        if (!empty($data['video_url'])) {
            $taskData['data']['video_url'] = $data['video_url'];
            if (!empty($data['cover_url'])) {
                $taskData['data']['cover_url'] = $data['cover_url'];
            }
        }

        // Add topics/hashtags
        if (!empty($data['topics'])) {
            $topics = is_array($data['topics']) ? $data['topics'] : explode(',', $data['topics']);
            $taskData['data']['topics'] = array_map('trim', $topics);
        }

        // Add location
        if (!empty($data['location'])) {
            $taskData['data']['location'] = $data['location'];
        }

        // Add scheduled time
        if (!empty($data['scheduled_time'])) {
            $taskData['data']['scheduled_time'] = $data['scheduled_time'];
        }

        // Call RPA adapter
        $result = $this->callRPAAdapter('/task/create', $config, $taskData);

        if ($result['success']) {
            // RPA returns task_id, need to poll for completion
            $taskId = $result['data']['task_id'] ?? null;

            if ($taskId) {
                // Wait for task completion (with timeout)
                $noteId = $this->waitForRPACompletion($config, $taskId, 120); // 2 minutes timeout

                if ($noteId) {
                    $this->logPublication([
                        'platform' => 'xiaohongshu',
                        'post_id' => $noteId,
                        'content' => $data['content'],
                        'status' => 'published',
                        'response' => json_encode(['task_id' => $taskId, 'note_id' => $noteId])
                    ]);

                    return [
                        'success' => true,
                        'data' => [
                            'note_id' => $noteId,
                            'task_id' => $taskId,
                            'platform' => 'xiaohongshu'
                        ]
                    ];
                } else {
                    $this->logPublication([
                        'platform' => 'xiaohongshu',
                        'post_id' => null,
                        'content' => $data['content'],
                        'status' => 'pending',
                        'response' => json_encode(['task_id' => $taskId, 'status' => 'timeout'])
                    ]);

                    return [
                        'success' => false,
                        'message' => 'RPA task timeout - check task status manually',
                        'data' => ['task_id' => $taskId]
                    ];
                }
            }
        }

        $this->logPublication([
            'platform' => 'xiaohongshu',
            'post_id' => null,
            'content' => $data['content'],
            'status' => 'failed',
            'error_message' => $result['message']
        ]);

        return $result;
    }

    /**
     * Wait for RPA task completion
     *
     * @param array $config Configuration
     * @param string $taskId Task ID
     * @param int $timeout Timeout in seconds
     * @return string|null Note ID if successful
     */
    private function waitForRPACompletion($config, $taskId, $timeout = 120) {
        $startTime = time();
        $interval = 5; // Check every 5 seconds

        while ((time() - $startTime) < $timeout) {
            sleep($interval);

            $result = $this->callRPAAdapter("/task/{$taskId}/status", $config);

            if ($result['success']) {
                $status = $result['data']['status'] ?? 'pending';

                if ($status === 'completed') {
                    return $result['data']['note_id'] ?? null;
                } else if ($status === 'failed') {
                    return null;
                }
                // Continue waiting if status is 'pending' or 'processing'
            } else {
                // Error checking status
                return null;
            }
        }

        return null; // Timeout
    }

    /**
     * Get note details
     *
     * @param string $noteId Note ID
     * @return array Note data
     */
    public function getNote($noteId) {
        if (empty($noteId)) {
            return ['success' => false, 'message' => 'Note ID is required'];
        }

        $settings = $this->getSettings();
        if (!$settings['success']) {
            return $settings;
        }

        $config = $settings['data'];
        $publisherMode = $config['PUBLISHER_MODE'] ?? 'rpa';

        if ($publisherMode === 'api') {
            return $this->callXHSAPI("/note/{$noteId}", $config);
        } else {
            return $this->callRPAAdapter("/note/{$noteId}", $config);
        }
    }

    /**
     * Delete note
     *
     * @param string $noteId Note ID
     * @return array Result
     */
    public function deleteNote($noteId) {
        if (empty($noteId)) {
            return ['success' => false, 'message' => 'Note ID is required'];
        }

        $settings = $this->getSettings();
        if (!$settings['success']) {
            return $settings;
        }

        $config = $settings['data'];
        $publisherMode = $config['PUBLISHER_MODE'] ?? 'rpa';

        if ($publisherMode === 'api') {
            return $this->callXHSAPI("/note/{$noteId}", $config, [], 'DELETE');
        } else {
            return $this->callRPAAdapter('/task/create', $config, [
                'action' => 'delete',
                'data' => ['note_id' => $noteId]
            ]);
        }
    }

    /**
     * Test XHS connection
     *
     * @return array Test result
     */
    public function testConnection() {
        $settings = $this->getSettings();
        if (!$settings['success']) {
            return $settings;
        }

        $config = $settings['data'];
        $publisherMode = $config['PUBLISHER_MODE'] ?? 'rpa';

        if ($publisherMode === 'api') {
            if (empty($config['API_URL']) || empty($config['API_TOKEN'])) {
                return ['success' => false, 'message' => 'Missing API_URL or API_TOKEN'];
            }

            $result = $this->callXHSAPI('/user/info', $config);

            if ($result['success']) {
                return [
                    'success' => true,
                    'message' => 'API connection successful',
                    'data' => [
                        'mode' => 'api',
                        'user_id' => $result['data']['user_id'] ?? 'Unknown',
                        'nickname' => $result['data']['nickname'] ?? 'Unknown'
                    ]
                ];
            }

            return $result;
        } else {
            if (empty($config['RPA_URL']) || empty($config['RPA_TOKEN'])) {
                return ['success' => false, 'message' => 'Missing RPA_URL or RPA_TOKEN'];
            }

            $result = $this->callRPAAdapter('/health', $config);

            if ($result['success']) {
                return [
                    'success' => true,
                    'message' => 'RPA connection successful',
                    'data' => [
                        'mode' => 'rpa',
                        'status' => $result['data']['status'] ?? 'active',
                        'version' => $result['data']['version'] ?? 'Unknown'
                    ]
                ];
            }

            return $result;
        }
    }

    /**
     * Call XHS API
     *
     * @param string $endpoint API endpoint
     * @param array $config Configuration
     * @param array $data Request data
     * @param string $method HTTP method
     * @return array Response
     */
    private function callXHSAPI($endpoint, $config, $data = [], $method = 'POST') {
        $url = rtrim($config['API_URL'], '/') . $endpoint;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        $headers = [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $config['API_TOKEN']
        ];
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        if ($method === 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        } else if ($method === 'DELETE') {
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
        }

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            return ['success' => false, 'message' => 'cURL error: ' . $error];
        }

        $result = json_decode($response, true);

        if ($httpCode >= 200 && $httpCode < 300) {
            return ['success' => true, 'data' => $result];
        }

        return [
            'success' => false,
            'message' => $result['message'] ?? 'API request failed',
            'http_code' => $httpCode
        ];
    }

    /**
     * Call RPA adapter
     *
     * @param string $endpoint Endpoint
     * @param array $config Configuration
     * @param array $data Request data
     * @return array Response
     */
    private function callRPAAdapter($endpoint, $config, $data = []) {
        $url = rtrim($config['RPA_URL'], '/') . $endpoint;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        $headers = [
            'Content-Type: application/json',
            'X-RPA-Token: ' . $config['RPA_TOKEN']
        ];
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        if (!empty($data)) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        }

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            return ['success' => false, 'message' => 'cURL error: ' . $error];
        }

        $result = json_decode($response, true);

        if ($httpCode >= 200 && $httpCode < 300) {
            return ['success' => true, 'data' => $result];
        }

        return [
            'success' => false,
            'message' => $result['message'] ?? 'RPA request failed',
            'http_code' => $httpCode
        ];
    }

    /**
     * Get XHS settings
     *
     * @return array Settings data
     */
    private function getSettings() {
        try {
            $stmt = $this->db->prepare("
                SELECT `key`, `value_encrypted` as value
                FROM settings
                WHERE section = 'xhs'
            ");
            $stmt->execute();
            $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $settings = [];
            foreach ($rows as $row) {
                // Map database keys to expected keys
                $key = strtoupper(str_replace('XHS_', '', $row['key']));
                $settings[$key] = $row['value'];
            }

            // Add defaults if not set
            if (!isset($settings['ENABLED'])) {
                // Check from common settings
                $stmt = $this->db->prepare("SELECT value_encrypted FROM settings WHERE section='common' AND `key`='XHS_ENABLED'");
                $stmt->execute();
                $result = $stmt->fetch(PDO::FETCH_ASSOC);
                $settings['ENABLED'] = $result ? ($result['value_encrypted'] === 'true' ? '1' : '0') : '0';
            }

            return ['success' => true, 'data' => $settings];

        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to load settings: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Log publication record
     *
     * @param array $data Publication data
     */
    private function logPublication($data) {
        try {
            $stmt = $this->db->prepare("
                INSERT INTO publish_records (
                    schedule_date, content_id, platform, platform_post_id,
                    status, error_message, published_at
                ) VALUES (CURDATE(), ?, ?, ?, ?, ?, ?)
            ");

            $stmt->execute([
                'manual_' . time(),
                $data['platform'],
                $data['post_id'] ?? null,
                $data['status'],
                $data['error_message'] ?? null,
                $data['status'] === 'published' ? date('Y-m-d H:i:s') : null
            ]);

        } catch (Exception $e) {
            error_log('Failed to log publication: ' . $e->getMessage());
        }
    }
}
