<?php
/**
 * Facebook Graph API Publishing Service
 * Handles publishing content to Facebook Pages
 */

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

class FacebookService {
    private $db;

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

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

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

        $config = $settings['data'];

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

        // Validate configuration
        if (empty($config['PAGE_ID']) || empty($config['ACCESS_TOKEN'])) {
            return ['success' => false, 'message' => 'Facebook configuration incomplete'];
        }

        // Prepare post data
        $postData = [
            'message' => $data['content'],
            'access_token' => $config['ACCESS_TOKEN']
        ];

        // Add image URL if provided
        if (!empty($data['image_url'])) {
            $postData['url'] = $data['image_url'];
            $endpoint = "/{$config['PAGE_ID']}/photos";
        }
        // Add video URL if provided
        else if (!empty($data['video_url'])) {
            $postData['file_url'] = $data['video_url'];
            $endpoint = "/{$config['PAGE_ID']}/videos";
        }
        // Text-only post
        else {
            $endpoint = "/{$config['PAGE_ID']}/feed";
        }

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

        // Add scheduling if provided
        if (!empty($data['scheduled_time'])) {
            $timestamp = strtotime($data['scheduled_time']);
            if ($timestamp > time()) {
                $postData['published'] = false;
                $postData['scheduled_publish_time'] = $timestamp;
            }
        }

        // Call Facebook Graph API
        $result = $this->callGraphAPI($endpoint, 'POST', $postData);

        if ($result['success']) {
            // Log successful publication
            $this->logPublication([
                'platform' => 'facebook',
                'post_id' => $result['data']['id'] ?? null,
                'content' => $data['content'],
                'status' => 'published',
                'response' => json_encode($result['data'])
            ]);

            return [
                'success' => true,
                'data' => [
                    'post_id' => $result['data']['id'] ?? null,
                    'platform' => 'facebook'
                ]
            ];
        }

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

        return $result;
    }

    /**
     * Update existing Facebook post
     *
     * @param string $postId Facebook post ID
     * @param array $data Update data
     * @return array Result
     */
    public function updatePost($postId, $data) {
        if (empty($postId)) {
            return ['success' => false, 'message' => 'Post ID is required'];
        }

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

        $config = $settings['data'];

        $updateData = ['access_token' => $config['ACCESS_TOKEN']];

        if (!empty($data['content'])) {
            $updateData['message'] = $data['content'];
        }

        return $this->callGraphAPI("/{$postId}", 'POST', $updateData);
    }

    /**
     * Delete Facebook post
     *
     * @param string $postId Facebook post ID
     * @return array Result
     */
    public function deletePost($postId) {
        if (empty($postId)) {
            return ['success' => false, 'message' => 'Post ID is required'];
        }

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

        $config = $settings['data'];

        return $this->callGraphAPI("/{$postId}", 'DELETE', [
            'access_token' => $config['ACCESS_TOKEN']
        ]);
    }

    /**
     * Get post details
     *
     * @param string $postId Facebook post ID
     * @return array Post data
     */
    public function getPost($postId) {
        if (empty($postId)) {
            return ['success' => false, 'message' => 'Post ID is required'];
        }

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

        $config = $settings['data'];

        return $this->callGraphAPI("/{$postId}", 'GET', [
            'fields' => 'id,message,created_time,permalink_url,shares,reactions.summary(true),comments.summary(true)',
            'access_token' => $config['ACCESS_TOKEN']
        ]);
    }

    /**
     * Get Page insights
     *
     * @param array $metrics Metrics to retrieve
     * @param string $period Time period (day, week, days_28)
     * @return array Insights data
     */
    public function getInsights($metrics = [], $period = 'day') {
        $settings = $this->getSettings();
        if (!$settings['success']) {
            return $settings;
        }

        $config = $settings['data'];

        if (empty($metrics)) {
            $metrics = ['page_impressions', 'page_engaged_users', 'page_post_engagements'];
        }

        $params = [
            'metric' => implode(',', $metrics),
            'period' => $period,
            'access_token' => $config['ACCESS_TOKEN']
        ];

        return $this->callGraphAPI("/{$config['PAGE_ID']}/insights", 'GET', $params);
    }

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

        $config = $settings['data'];

        if (empty($config['PAGE_ID']) || empty($config['ACCESS_TOKEN'])) {
            return ['success' => false, 'message' => 'Missing PAGE_ID or ACCESS_TOKEN'];
        }

        // Try to get page info
        $result = $this->callGraphAPI("/{$config['PAGE_ID']}", 'GET', [
            'fields' => 'id,name,category,verification_status',
            'access_token' => $config['ACCESS_TOKEN']
        ]);

        if ($result['success']) {
            return [
                'success' => true,
                'message' => 'Connection successful',
                'data' => [
                    'page_name' => $result['data']['name'] ?? 'Unknown',
                    'page_id' => $result['data']['id'] ?? 'Unknown',
                    'category' => $result['data']['category'] ?? 'Unknown',
                    'verified' => $result['data']['verification_status'] ?? 'not_verified'
                ]
            ];
        }

        return $result;
    }

    /**
     * Call Facebook Graph API
     *
     * @param string $endpoint API endpoint
     * @param string $method HTTP method
     * @param array $params Parameters
     * @return array Response data
     */
    private function callGraphAPI($endpoint, $method = 'GET', $params = []) {
        $baseUrl = 'https://graph.facebook.com/v18.0';
        $url = $baseUrl . $endpoint;

        $ch = curl_init();

        if ($method === 'GET') {
            if (!empty($params)) {
                $url .= '?' . http_build_query($params);
            }
            curl_setopt($ch, CURLOPT_URL, $url);
        } else {
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));

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

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/x-www-form-urlencoded'
        ]);

        $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
            ];
        }

        $data = json_decode($response, true);

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

        // Handle error response
        $errorMessage = 'API request failed';
        if (isset($data['error']['message'])) {
            $errorMessage = $data['error']['message'];
        }

        return [
            'success' => false,
            'message' => $errorMessage,
            'error_code' => $data['error']['code'] ?? null,
            'http_code' => $httpCode
        ];
    }

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

            $settings = [];
            foreach ($rows as $row) {
                // Map database keys to expected keys
                $key = strtoupper(str_replace('FB_', '', $row['key']));
                // Handle both FB_ACCESS_TOKEN and FB_PAGE_ACCESS_TOKEN
                if ($key === 'PAGE_ACCESS_TOKEN') {
                    $key = 'ACCESS_TOKEN';
                }
                $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`='FB_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());
        }
    }
}
