<?php
/**
 * CastConductor Export Manager
 *
 * Handles exporting content blocks, scenes, containers, and all related data
 * to JSON format for backup and migration purposes.
 *
 * @package CastConductor
 * @subpackage Export
 * @since 5.2.1
 */

if (!defined('ABSPATH')) {
    exit;
}

class CastConductor_Export_Manager {

    /**
     * Export full library to JSON
     *
     * @return array Complete export data structure
     */
    public function export_full_library() {
        $export = array(
            'castconductor_export' => array(
                'version' => CASTCONDUCTOR_VERSION,
                'export_date' => current_time('c'),
                'export_type' => 'full',
                'content_blocks' => $this->export_content_blocks(),
                'scenes' => $this->export_scenes(),
                'containers' => $this->export_containers(),
                'media_references' => $this->export_media_references(),
                'fonts' => $this->export_fonts(),
                'settings' => $this->export_settings()
            )
        );
        
        return $export;
    }

    /**
     * Export content blocks
     *
     * @param array|null $block_ids Optional array of specific block IDs to export
     * @return array Array of content block data
     */
    public function export_content_blocks($block_ids = null) {
        global $wpdb;
        
        $where = '';
        if ($block_ids && is_array($block_ids) && !empty($block_ids)) {
            $placeholders = implode(',', array_fill(0, count($block_ids), '%d'));
            $where = $wpdb->prepare("WHERE id IN ($placeholders)", $block_ids);
        }
        
        $query = "SELECT * FROM {$wpdb->prefix}castconductor_content_blocks {$where} ORDER BY id ASC";
        $blocks = $wpdb->get_results($query);
        
        $exported = array();
        foreach ($blocks as $block) {
            $exported[] = array(
                'id' => (int)$block->id,
                'name' => $block->name,
                'type' => $block->type,
                'config' => json_decode($block->config, true),
                'metadata' => json_decode($block->metadata, true),
                'created_at' => $block->created_at,
                'updated_at' => $block->updated_at
            );
        }
        
        return $exported;
    }

    /**
     * Export scenes
     *
     * @param array|null $scene_ids Optional array of specific scene IDs to export
     * @return array Array of scene data
     */
    public function export_scenes($scene_ids = null) {
        global $wpdb;
        
        $where = '';
        if ($scene_ids && is_array($scene_ids) && !empty($scene_ids)) {
            $placeholders = implode(',', array_fill(0, count($scene_ids), '%d'));
            $where = $wpdb->prepare("WHERE id IN ($placeholders)", $scene_ids);
        }
        
        $query = "SELECT * FROM {$wpdb->prefix}castconductor_scenes {$where} ORDER BY id ASC";
        $scenes = $wpdb->get_results($query);
        
        $exported = array();
        foreach ($scenes as $scene) {
            $exported[] = array(
                'id' => (int)$scene->id,
                'name' => $scene->name,
                'config' => json_decode($scene->config, true),
                'metadata' => json_decode($scene->metadata, true),
                'created_at' => $scene->created_at,
                'updated_at' => $scene->updated_at
            );
        }
        
        return $exported;
    }

    /**
     * Export containers
     *
     * @param array|null $container_ids Optional array of specific container IDs to export
     * @return array Array of container data
     */
    public function export_containers($container_ids = null) {
        global $wpdb;
        
        $where = '';
        if ($container_ids && is_array($container_ids) && !empty($container_ids)) {
            $placeholders = implode(',', array_fill(0, count($container_ids), '%d'));
            $where = $wpdb->prepare("WHERE id IN ($placeholders)", $container_ids);
        }
        
        $query = "SELECT * FROM {$wpdb->prefix}castconductor_containers {$where} ORDER BY id ASC";
        $containers = $wpdb->get_results($query);
        
        $exported = array();
        foreach ($containers as $container) {
            $exported[] = array(
                'id' => (int)$container->id,
                'name' => $container->name,
                'type' => $container->type,
                'config' => json_decode($container->config, true),
                'content_block_ids' => json_decode($container->content_block_ids, true),
                'metadata' => json_decode($container->metadata, true),
                'created_at' => $container->created_at,
                'updated_at' => $container->updated_at
            );
        }
        
        return $exported;
    }

    /**
     * Export media references
     *
     * Scans all content blocks for media URLs and creates a reference list
     *
     * @return array Array of media references with usage tracking
     */
    public function export_media_references() {
        global $wpdb;
        
        $media_refs = array();
        $blocks = $wpdb->get_results("SELECT id, config FROM {$wpdb->prefix}castconductor_content_blocks");
        
        foreach ($blocks as $block) {
            $config = json_decode($block->config, true);
            
            // Extract media from layers
            if (!empty($config['layers'])) {
                foreach ($config['layers'] as $layer) {
                    if (!empty($layer['url'])) {
                        $this->add_media_reference($media_refs, $layer['url'], 'content_block_' . $block->id);
                    }
                    if (!empty($layer['background_image'])) {
                        $this->add_media_reference($media_refs, $layer['background_image'], 'content_block_' . $block->id);
                    }
                }
            }
            
            // Extract media from artwork items (legacy)
            if (!empty($config['artwork']['items'])) {
                foreach ($config['artwork']['items'] as $item) {
                    if (!empty($item['url'])) {
                        $this->add_media_reference($media_refs, $item['url'], 'content_block_' . $block->id);
                    }
                }
            }
        }
        
        return array_values($media_refs);
    }

    /**
     * Helper to add media reference
     *
     * @param array &$refs Reference array to modify
     * @param string $url Media URL
     * @param string $used_in Location identifier
     */
    private function add_media_reference(&$refs, $url, $used_in) {
        $key = md5($url);
        
        if (!isset($refs[$key])) {
            $refs[$key] = array(
                'url' => $url,
                'filename' => basename(parse_url($url, PHP_URL_PATH)),
                'type' => $this->guess_mime_type($url),
                'used_in' => array()
            );
        }
        
        if (!in_array($used_in, $refs[$key]['used_in'])) {
            $refs[$key]['used_in'][] = $used_in;
        }
    }

    /**
     * Guess MIME type from URL
     *
     * @param string $url File URL
     * @return string MIME type
     */
    private function guess_mime_type($url) {
        $ext = strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION));
        
        $mime_types = array(
            'jpg' => 'image/jpeg',
            'jpeg' => 'image/jpeg',
            'png' => 'image/png',
            'gif' => 'image/gif',
            'svg' => 'image/svg+xml',
            'webp' => 'image/webp',
            'mp4' => 'video/mp4',
            'webm' => 'video/webm',
            'mp3' => 'audio/mpeg',
            'wav' => 'audio/wav',
            'woff' => 'font/woff',
            'woff2' => 'font/woff2',
            'ttf' => 'font/ttf',
            'otf' => 'font/otf'
        );
        
        return isset($mime_types[$ext]) ? $mime_types[$ext] : 'application/octet-stream';
    }

    /**
     * Export font references
     *
     * @return array Array of custom fonts used
     */
    public function export_fonts() {
        global $wpdb;
        
        $fonts = array();
        $blocks = $wpdb->get_results("SELECT id, config FROM {$wpdb->prefix}castconductor_content_blocks");
        
        foreach ($blocks as $block) {
            $config = json_decode($block->config, true);
            
            if (!empty($config['layers'])) {
                foreach ($config['layers'] as $layer) {
                    if (!empty($layer['font_family']) && !empty($layer['font_url'])) {
                        $key = md5($layer['font_family']);
                        
                        if (!isset($fonts[$key])) {
                            $fonts[$key] = array(
                                'family' => $layer['font_family'],
                                'url' => $layer['font_url'],
                                'used_in' => array()
                            );
                        }
                        
                        $used_in = 'content_block_' . $block->id;
                        if (!in_array($used_in, $fonts[$key]['used_in'])) {
                            $fonts[$key]['used_in'][] = $used_in;
                        }
                    }
                }
            }
        }
        
        return array_values($fonts);
    }

    /**
     * Export global settings
     *
     * @return array Array of CastConductor settings
     */
    public function export_settings() {
        return array(
            'stream_url' => get_option('castconductor_stream_url', ''),
            'metadata_url' => get_option('castconductor_metadata_url', ''),
            'default_duration' => get_option('castconductor_default_duration', 5000),
            'canvas_width' => get_option('castconductor_canvas_width', 1920),
            'canvas_height' => get_option('castconductor_canvas_height', 1080)
        );
    }

    /**
     * Generate downloadable export file
     *
     * @param string $export_type Type of export: 'full', 'content_blocks', 'scenes', 'containers'
     * @param array|null $ids Optional array of specific IDs to export
     * @param bool $include_media Whether to include media references
     */
    public function download_export($export_type = 'full', $ids = null, $include_media = true) {
        $filename = 'castconductor_export_' . $export_type . '_' . date('Y-m-d_H-i-s') . '.json';
        
        $export_data = array(
            'castconductor_export' => array(
                'version' => CASTCONDUCTOR_VERSION,
                'export_date' => current_time('c'),
                'export_type' => $export_type
            )
        );
        
        switch ($export_type) {
            case 'content_blocks':
                $export_data['castconductor_export']['content_blocks'] = $this->export_content_blocks($ids);
                if ($include_media) {
                    $export_data['castconductor_export']['media_references'] = $this->export_media_references();
                    $export_data['castconductor_export']['fonts'] = $this->export_fonts();
                }
                break;
                
            case 'scenes':
                $export_data['castconductor_export']['scenes'] = $this->export_scenes($ids);
                break;
                
            case 'containers':
                $export_data['castconductor_export']['containers'] = $this->export_containers($ids);
                break;
                
            case 'full':
            default:
                $export_data = $this->export_full_library();
                break;
        }
        
        header('Content-Type: application/json');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Cache-Control: no-cache, must-revalidate');
        header('Expires: 0');
        
        echo json_encode($export_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
        exit;
    }
}
