<?php
/**
 * Configuration exporter/importer (courses, modules, slides)
 *
 * @package SlideMind
 * @since 2.0.0
 */

namespace SlideMind\Core;

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

class ConfigExporter {

    /**
     * @var ConfigRepository
     */
    private $config_repository;

    /**
     * Constructor
     *
     * @param ConfigRepository $config_repository
     */
    public function __construct(ConfigRepository $config_repository) {
        $this->config_repository = $config_repository;
    }

    // =========================================================================
    // EXPORT
    // =========================================================================

    /**
     * Exports a course with all its modules and slides (JSON)
     *
     * @param int $id Post ID of the course
     * @return string|WP_Error JSON or error
     */
    public function export_course(int $id) {
        $data = $this->export_course_array($id);
        if (is_wp_error($data)) {
            return $data;
        }
        return wp_json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    }

    /**
     * Exports a course as a structured array
     *
     * @param int $id Post ID of the course
     * @return array|WP_Error
     */
    public function export_course_array(int $id) {
        $course = $this->config_repository->get_course($id);

        if (!$course) {
            return new \WP_Error('not_found', __('Course not found', 'slidemind'));
        }

        $modules_data = [];
        $modules = $this->config_repository->get_modules_by_course($id);

        foreach ($modules as $module) {
            $slides_data = [];
            $slides = $this->config_repository->get_slides_by_module($module['id']);

            foreach ($slides as $slide) {
                $slides_data[] = $this->format_slide_for_export($slide);
            }

            $modules_data[] = [
                'title'   => $module['title'],
                'subject' => $module['subject'],
                'context' => $module['context'],
                'slides'  => $slides_data,
            ];
        }

        return [
            'slidemind_export_version' => '1.0',
            'export_type'       => 'course',
            'exported_at'       => gmdate('c'),
            'course'            => [
                'title'      => $course['title'],
                'theme'      => $course['theme'],
                'objectives' => $course['objectives'],
                'content'    => $course['content'],
            ],
            'modules' => $modules_data,
        ];
    }

    /**
     * Exports a module with all its slides (JSON)
     *
     * @param int $id Post ID of the module
     * @return string|WP_Error JSON or error
     */
    public function export_module(int $id) {
        $data = $this->export_module_array($id);
        if (is_wp_error($data)) {
            return $data;
        }
        return wp_json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    }

    /**
     * Exports a module as a structured array
     *
     * @param int $id Post ID of the module
     * @return array|WP_Error
     */
    public function export_module_array(int $id) {
        $module = $this->config_repository->get_module($id);

        if (!$module) {
            return new \WP_Error('not_found', __('Module not found', 'slidemind'));
        }

        $slides_data = [];
        $slides = $this->config_repository->get_slides_by_module($id);

        foreach ($slides as $slide) {
            $slides_data[] = $this->format_slide_for_export($slide);
        }

        return [
            'slidemind_export_version' => '1.0',
            'export_type'       => 'module',
            'exported_at'       => gmdate('c'),
            'module'            => [
                'title'   => $module['title'],
                'subject' => $module['subject'],
                'context' => $module['context'],
            ],
            'slides' => $slides_data,
        ];
    }

    /**
     * Exports a slide (JSON)
     *
     * @param int $id Post ID of the slide
     * @return string|WP_Error JSON or error
     */
    public function export_slide(int $id) {
        $data = $this->export_slide_array($id);
        if (is_wp_error($data)) {
            return $data;
        }
        return wp_json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    }

    /**
     * Exports a slide as a structured array
     *
     * @param int $id Post ID of the slide
     * @return array|WP_Error
     */
    public function export_slide_array(int $id) {
        $slide = $this->config_repository->get_slide($id);

        if (!$slide) {
            return new \WP_Error('not_found', __('Slide not found', 'slidemind'));
        }

        return [
            'slidemind_export_version' => '1.0',
            'export_type'       => 'slide',
            'exported_at'       => gmdate('c'),
            'slide'             => $this->format_slide_for_export($slide),
        ];
    }

    /**
     * Formats a slide for export (excludes API key and IDs)
     *
     * @param array $slide Slide data
     * @return array
     */
    public function format_slide_for_export(array $slide): array {
        $slide_number = $slide['slide_number'];
        if ($slide_number !== '' && $slide_number !== null) {
            $slide_number = (int) $slide_number;
        } else {
            $slide_number = null;
        }

        return [
            'title'                 => $slide['title'],
            'slide_number'          => $slide_number,
            'model_id'              => $slide['model_id'],
            'system_prompt'         => $slide['system_prompt'],
            'temperature'           => $slide['temperature'],
            'max_tokens'            => $slide['max_tokens'],
            'variables'             => $slide['variables'] ?: [],
            'override_course'       => $slide['override_course'] ?: [],
            'override_module'       => $slide['override_module'] ?: [],
            'output_variables'      => $slide['output_variables'] ?: [],
            'notes'                 => $slide['notes'],
            'widget_mode'           => $slide['widget_mode'] ?? 'qa',
            'max_turns'             => isset($slide['max_turns']) ? (int) $slide['max_turns'] : 0,
            'closing_message'       => $slide['closing_message'] ?? '',
            'opening_message'       => $slide['opening_message'] ?? '',
            'graceful_close'        => $slide['graceful_close'] ?? '0',
            'graceful_close_prompt' => $slide['graceful_close_prompt'] ?? '',
            // NOTE: api_key is never exported (sensitive and site-specific)
        ];
    }

    // =========================================================================
    // IMPORT
    // =========================================================================

    /**
     * Imports from an exported JSON
     *
     * Detects the type and creates the elements. Never copies the API key.
     * Always creates as duplicate, never overwrites.
     *
     * @param string $json    JSON content
     * @param array  $options Options: course_id (for module), module_id (for slide)
     * @return array|WP_Error ['created' => [...]] or WP_Error
     */
    public function import(string $json, array $options = []) {
        $data = json_decode($json, true);

        if (!is_array($data) || empty($data['slidemind_export_version']) || empty($data['export_type'])) {
            return new \WP_Error('invalid_format', __('Invalid file format', 'slidemind'));
        }

        return $this->import_array($data, $options);
    }

    /**
     * Imports from an already decoded array
     *
     * @param array $data    Decoded data
     * @param array $options Options: course_id (for module), module_id (for slide)
     * @return array|WP_Error ['created' => [...]] or WP_Error
     */
    public function import_array(array $data, array $options = []) {
        if (empty($data['slidemind_export_version']) || empty($data['export_type'])) {
            return new \WP_Error('invalid_format', __('Invalid file format', 'slidemind'));
        }

        $type = $data['export_type'];
        $created = [];

        switch ($type) {
            case 'course':
            case 'formation': // backward compat
                $result = $this->import_course($data, $created);
                break;

            case 'courses': // multi-course (per-type bulk export)
                foreach ($data['courses'] ?? [] as $course_item) {
                    $course_wrap = [
                        'slidemind_export_version' => '1.0',
                        'export_type'       => 'course',
                        'course'            => $course_item,
                        'modules'           => [],
                    ];
                    $result = $this->import_course($course_wrap, $created);
                    if (is_wp_error($result)) {
                        return $result;
                    }
                }
                $result = true;
                break;

            case 'module':
                $course_id = isset($options['course_id']) ? (int) $options['course_id'] : (isset($options['formation_id']) ? (int) $options['formation_id'] : 0);
                if (!$course_id) {
                    return new \WP_Error('missing_parent', __('Target course is required', 'slidemind'));
                }
                $module_data = $data['module'] ?? [];
                $slides = $data['slides'] ?? [];
                $result = $this->import_module($module_data, $slides, $course_id, $created);
                break;

            case 'modules': // multi-module (per-type bulk export)
                $course_id = isset($options['course_id']) ? (int) $options['course_id'] : 0;
                if (!$course_id) {
                    return new \WP_Error('missing_parent', __('Target course is required', 'slidemind'));
                }
                foreach ($data['modules'] ?? [] as $module_item) {
                    $result = $this->import_module($module_item, [], $course_id, $created);
                    if (is_wp_error($result)) {
                        return $result;
                    }
                }
                $result = true;
                break;

            case 'slide':
                $module_id = isset($options['module_id']) ? (int) $options['module_id'] : 0;
                $course_id = isset($options['course_id']) ? (int) $options['course_id'] : 0;
                $result = $this->import_slide($data['slide'] ?? [], $module_id, $course_id, $created);
                break;

            case 'slides': // multi-slide (per-type bulk export)
                $module_id = isset($options['module_id']) ? (int) $options['module_id'] : 0;
                $course_id = isset($options['course_id']) ? (int) $options['course_id'] : 0;
                foreach ($data['slides'] ?? [] as $slide_item) {
                    $result = $this->import_slide($slide_item, $module_id, $course_id, $created);
                    if (is_wp_error($result)) {
                        return $result;
                    }
                }
                $result = true;
                break;

            default:
                return new \WP_Error('unknown_type', __('Unknown export type', 'slidemind'));
        }

        if (is_wp_error($result)) {
            return $result;
        }

        return ['created' => $created];
    }

    /**
     * Imports a course with its modules and slides
     *
     * @param array $data    Decoded data
     * @param array $created Array of created elements (reference)
     * @return bool|WP_Error
     */
    private function import_course(array $data, array &$created) {
        $course_data = $data['course'] ?? $data['formation'] ?? [];

        $course_id = $this->config_repository->create_course([
            'title'      => $course_data['title'] ?? __('Imported Course', 'slidemind'),
            'theme'      => $course_data['theme'] ?? '',
            'objectives' => $course_data['objectives'] ?? '',
            'content'    => $course_data['content'] ?? '',
            'status'     => 'publish',
        ]);

        if (is_wp_error($course_id)) {
            return $course_id;
        }

        $created[] = [
            'type'  => 'course',
            'id'    => $course_id,
            'title' => $course_data['title'] ?? '',
        ];

        foreach ($data['modules'] ?? [] as $module_data) {
            $slides = $module_data['slides'] ?? [];
            $result = $this->import_module($module_data, $slides, $course_id, $created);

            if (is_wp_error($result)) {
                return $result;
            }
        }

        return true;
    }

    /**
     * Imports a module with its slides
     *
     * @param array $module_data  Module data
     * @param array $slides       Array of slides
     * @param int   $course_id    Parent course ID
     * @param array $created      Array of created elements (reference)
     * @return bool|WP_Error
     */
    private function import_module(array $module_data, array $slides, int $course_id, array &$created) {
        $module_id = $this->config_repository->create_module([
            'title'               => $module_data['title'] ?? __('Imported Module', 'slidemind'),
            'subject'             => $module_data['subject'] ?? '',
            'context'             => $module_data['context'] ?? '',
            'parent_course_id' => $course_id,
            'status'              => 'publish',
        ]);

        if (is_wp_error($module_id)) {
            return $module_id;
        }

        $created[] = [
            'type'  => 'module',
            'id'    => $module_id,
            'title' => $module_data['title'] ?? '',
        ];

        foreach ($slides as $slide_data) {
            $result = $this->import_slide($slide_data, $module_id, $course_id, $created);

            if (is_wp_error($result)) {
                return $result;
            }
        }

        return true;
    }

    /**
     * Imports a slide
     *
     * Generates a new config_uid (via create_slide -> generate_slide_config_uid).
     * Does not copy _slidemind_api_key_encrypted.
     *
     * @param array $slide_data Slide data
     * @param int   $module_id  Parent module ID (0 if none)
     * @param int   $course_id  Parent course ID (0 if none)
     * @param array $created    Array of created elements (reference)
     * @return bool|WP_Error
     */
    private function import_slide(array $slide_data, int $module_id, int $course_id, array &$created) {
        $slide_number = isset($slide_data['slide_number']) && $slide_data['slide_number'] !== null
            ? (int) $slide_data['slide_number']
            : '';

        $slide_id = $this->config_repository->create_slide([
            'title'                 => $slide_data['title'] ?? __('Imported Slide', 'slidemind'),
            'parent_course_id'      => $course_id,
            'parent_module_id'      => $module_id,
            'slide_number'          => $slide_number,
            'model_id'              => $slide_data['model_id'] ?? '',
            'system_prompt'         => $slide_data['system_prompt'] ?? '',
            'temperature'           => isset($slide_data['temperature']) ? (float) $slide_data['temperature'] : 0.7,
            'max_tokens'            => isset($slide_data['max_tokens']) ? (int) $slide_data['max_tokens'] : 1024,
            'variables'             => $slide_data['variables'] ?? [],
            'override_course'       => $slide_data['override_course'] ?? [],
            'override_module'       => $slide_data['override_module'] ?? [],
            'output_variables'      => $slide_data['output_variables'] ?? [],
            'notes'                 => $slide_data['notes'] ?? '',
            'widget_mode'           => $slide_data['widget_mode'] ?? 'qa',
            'max_turns'             => isset($slide_data['max_turns']) ? (int) $slide_data['max_turns'] : 0,
            'closing_message'       => $slide_data['closing_message'] ?? '',
            'opening_message'       => $slide_data['opening_message'] ?? '',
            'graceful_close'        => $slide_data['graceful_close'] ?? '0',
            'graceful_close_prompt' => $slide_data['graceful_close_prompt'] ?? '',
            'status'                => 'draft',
            // No api_key: never import API keys
        ]);

        if (is_wp_error($slide_id)) {
            return $slide_id;
        }

        $created[] = [
            'type'  => 'slide',
            'id'    => $slide_id,
            'title' => $slide_data['title'] ?? '',
        ];

        return true;
    }
}
