<?php
/**
 * Unified Publishing Service
 * Orchestrates content publishing across multiple platforms
 */

require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/facebook.php';
require_once __DIR__ . '/instagram.php';
require_once __DIR__ . '/xiaohongshu.php';

class PublishingService {
    private $db;
    private $facebook;
    private $instagram;
    private $xiaohongshu;

    public function __construct() {
        $this->db = Database::getInstance()->getConnection();
        $this->facebook = new FacebookService();
        $this->instagram = new InstagramService();
        $this->xiaohongshu = new XiaoHongShuService();
    }

    /**
     * Publish content to one or multiple platforms
     *
     * @param array $data Publication data
     * @param array $platforms Target platforms (facebook, instagram, xiaohongshu)
     * @return array Publication results
     */
    public function publish($data, $platforms = []) {
        // Validate platforms
        if (empty($platforms)) {
            return ['success' => false, 'message' => 'No platforms specified'];
        }

        $validPlatforms = ['facebook', 'instagram', 'xiaohongshu'];
        $platforms = array_intersect($platforms, $validPlatforms);

        if (empty($platforms)) {
            return ['success' => false, 'message' => 'No valid platforms specified'];
        }

        // Publish to each platform
        $results = [];
        $successCount = 0;
        $failCount = 0;

        foreach ($platforms as $platform) {
            try {
                $result = $this->publishToPlatform($platform, $data);
                $results[$platform] = $result;

                if ($result['success']) {
                    $successCount++;
                } else {
                    $failCount++;
                }

            } catch (Exception $e) {
                $results[$platform] = [
                    'success' => false,
                    'message' => 'Exception: ' . $e->getMessage()
                ];
                $failCount++;
            }
        }

        // Overall success if at least one platform succeeded
        $overallSuccess = $successCount > 0;

        return [
            'success' => $overallSuccess,
            'message' => "Published to {$successCount} platform(s), {$failCount} failed",
            'results' => $results,
            'summary' => [
                'total' => count($platforms),
                'success' => $successCount,
                'failed' => $failCount
            ]
        ];
    }

    /**
     * Publish to a specific platform
     *
     * @param string $platform Platform name
     * @param array $data Publication data
     * @return array Result
     */
    private function publishToPlatform($platform, $data) {
        switch ($platform) {
            case 'facebook':
                return $this->facebook->publish([
                    'content' => $data['content'] ?? '',
                    'image_url' => $data['image_url'] ?? null,
                    'video_url' => $data['video_url'] ?? null,
                    'link_url' => $data['link_url'] ?? null,
                    'scheduled_time' => $data['scheduled_time'] ?? null
                ]);

            case 'instagram':
                return $this->instagram->publish([
                    'caption' => $data['content'] ?? '',
                    'image_url' => $data['image_url'] ?? null,
                    'video_url' => $data['video_url'] ?? null,
                    'carousel_items' => $data['carousel_items'] ?? null,
                    'location_id' => $data['location_id'] ?? null,
                    'user_tags' => $data['user_tags'] ?? null
                ]);

            case 'xiaohongshu':
                return $this->xiaohongshu->publish([
                    'title' => $data['title'] ?? substr($data['content'] ?? '', 0, 50),
                    'content' => $data['content'] ?? '',
                    'images' => $data['images'] ?? (!empty($data['image_url']) ? [$data['image_url']] : null),
                    'video_url' => $data['video_url'] ?? null,
                    'cover_url' => $data['cover_url'] ?? null,
                    'topics' => $data['topics'] ?? null,
                    'location' => $data['location'] ?? null,
                    'scheduled_time' => $data['scheduled_time'] ?? null
                ]);

            default:
                return ['success' => false, 'message' => 'Unsupported platform'];
        }
    }

    /**
     * Schedule publication for later
     *
     * @param array $data Publication data
     * @param array $platforms Target platforms
     * @param string $scheduledTime Scheduled time (YYYY-MM-DD HH:MM:SS)
     * @return array Result
     */
    public function schedulePublish($data, $platforms, $scheduledTime) {
        // Validate scheduled time
        $timestamp = strtotime($scheduledTime);
        if (!$timestamp || $timestamp <= time()) {
            return ['success' => false, 'message' => 'Invalid scheduled time - must be in the future'];
        }

        try {
            // Store scheduled publication in database
            $stmt = $this->db->prepare("
                INSERT INTO publish_records (
                    platform, content, status, scheduled_time, created_at
                ) VALUES (?, ?, 'scheduled', ?, NOW())
            ");

            $platformsJson = json_encode($platforms);
            $contentJson = json_encode($data);

            $stmt->execute([
                $platformsJson,
                $contentJson,
                $scheduledTime
            ]);

            $scheduleId = $this->db->lastInsertId();

            return [
                'success' => true,
                'message' => 'Publication scheduled successfully',
                'data' => [
                    'schedule_id' => $scheduleId,
                    'scheduled_time' => $scheduledTime,
                    'platforms' => $platforms
                ]
            ];

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

    /**
     * Get publication history
     *
     * @param array $filters Filters (platform, status, date_from, date_to)
     * @param int $limit Limit
     * @param int $offset Offset
     * @return array Publication records
     */
    public function getHistory($filters = [], $limit = 50, $offset = 0) {
        try {
            $where = ['1=1'];
            $params = [];

            if (!empty($filters['platform'])) {
                $where[] = "platform = ?";
                $params[] = $filters['platform'];
            }

            if (!empty($filters['status'])) {
                $where[] = "status = ?";
                $params[] = $filters['status'];
            }

            if (!empty($filters['date_from'])) {
                $where[] = "created_at >= ?";
                $params[] = $filters['date_from'];
            }

            if (!empty($filters['date_to'])) {
                $where[] = "created_at <= ?";
                $params[] = $filters['date_to'];
            }

            $whereClause = implode(' AND ', $where);

            // Get total count
            $countStmt = $this->db->prepare("
                SELECT COUNT(*) as total
                FROM publish_records
                WHERE {$whereClause}
            ");
            $countStmt->execute($params);
            $total = $countStmt->fetch(PDO::FETCH_ASSOC)['total'];

            // Get records
            $params[] = $limit;
            $params[] = $offset;

            $stmt = $this->db->prepare("
                SELECT *
                FROM publish_records
                WHERE {$whereClause}
                ORDER BY created_at DESC
                LIMIT ? OFFSET ?
            ");
            $stmt->execute($params);
            $records = $stmt->fetchAll(PDO::FETCH_ASSOC);

            return [
                'success' => true,
                'data' => [
                    'records' => $records,
                    'total' => $total,
                    'limit' => $limit,
                    'offset' => $offset
                ]
            ];

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

    /**
     * Get publication statistics
     *
     * @param string $dateFrom Start date
     * @param string $dateTo End date
     * @return array Statistics
     */
    public function getStatistics($dateFrom = null, $dateTo = null) {
        try {
            $params = [];
            $where = [];

            if ($dateFrom) {
                $where[] = "created_at >= ?";
                $params[] = $dateFrom;
            } else {
                $where[] = "created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)";
            }

            if ($dateTo) {
                $where[] = "created_at <= ?";
                $params[] = $dateTo;
            }

            $whereClause = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';

            // Get statistics by platform and status
            $stmt = $this->db->prepare("
                SELECT
                    platform,
                    status,
                    COUNT(*) as count
                FROM publish_records
                {$whereClause}
                GROUP BY platform, status
            ");
            $stmt->execute($params);
            $platformStats = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Get daily statistics
            $stmt = $this->db->prepare("
                SELECT
                    DATE(created_at) as date,
                    COUNT(*) as count,
                    SUM(CASE WHEN status = 'published' THEN 1 ELSE 0 END) as published,
                    SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed
                FROM publish_records
                {$whereClause}
                GROUP BY DATE(created_at)
                ORDER BY date DESC
                LIMIT 30
            ");
            $stmt->execute($params);
            $dailyStats = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Get total counts
            $stmt = $this->db->prepare("
                SELECT
                    COUNT(*) as total,
                    SUM(CASE WHEN status = 'published' THEN 1 ELSE 0 END) as published,
                    SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed,
                    SUM(CASE WHEN status = 'scheduled' THEN 1 ELSE 0 END) as scheduled
                FROM publish_records
                {$whereClause}
            ");
            $stmt->execute($params);
            $totals = $stmt->fetch(PDO::FETCH_ASSOC);

            return [
                'success' => true,
                'data' => [
                    'totals' => $totals,
                    'by_platform' => $platformStats,
                    'daily' => $dailyStats
                ]
            ];

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

    /**
     * Delete published content
     *
     * @param int $recordId Record ID
     * @return array Result
     */
    public function deletePublished($recordId) {
        try {
            // Get record
            $stmt = $this->db->prepare("SELECT * FROM publish_records WHERE id = ?");
            $stmt->execute([$recordId]);
            $record = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$record) {
                return ['success' => false, 'message' => 'Record not found'];
            }

            if (empty($record['post_id'])) {
                return ['success' => false, 'message' => 'No post ID to delete'];
            }

            // Delete from platform
            $result = null;
            switch ($record['platform']) {
                case 'facebook':
                    $result = $this->facebook->deletePost($record['post_id']);
                    break;
                case 'instagram':
                    $result = $this->instagram->deleteMedia($record['post_id']);
                    break;
                case 'xiaohongshu':
                    $result = $this->xiaohongshu->deleteNote($record['post_id']);
                    break;
            }

            if ($result && $result['success']) {
                // Update record status
                $stmt = $this->db->prepare("
                    UPDATE publish_records
                    SET status = 'deleted', updated_at = NOW()
                    WHERE id = ?
                ");
                $stmt->execute([$recordId]);

                return [
                    'success' => true,
                    'message' => 'Content deleted successfully'
                ];
            }

            return $result ?? ['success' => false, 'message' => 'Failed to delete content'];

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

    /**
     * Test all platform connections
     *
     * @return array Test results
     */
    public function testConnections() {
        $results = [
            'facebook' => $this->facebook->testConnection(),
            'instagram' => $this->instagram->testConnection(),
            'xiaohongshu' => $this->xiaohongshu->testConnection()
        ];

        $allSuccess = true;
        foreach ($results as $result) {
            if (!$result['success']) {
                $allSuccess = false;
                break;
            }
        }

        return [
            'success' => $allSuccess,
            'message' => $allSuccess ? 'All connections successful' : 'Some connections failed',
            'results' => $results
        ];
    }
}
