// Copyright 2025 SkyReels SDK Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Image-to-video example for SkyReels SDK
//!
//! This example demonstrates how to:
//! - Create a client
//! - Submit an image-to-video task
//! - Query task status
//! - Wait for task completion

use skyreels::{Mode, SkyReelsClient, TaskStatus};
use tracing::{info, warn};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load environment variables from .env file
    dotenv::dotenv().ok();

    // Initialize tracing for logging
    tracing_subscriber::fmt::init();

    // Get API key from environment variable
    let api_key = std::env::var("SKYREELS_API_KEY")
        .expect("SKYREELS_API_KEY environment variable not set");

    info!("Creating SkyReels client");
    let client = SkyReelsClient::new(&api_key);

    // Example 1: Basic image-to-video submission
    info!("Submitting basic image-to-video task");
    let request = client
        .image2video()
        .submit_request(
            "Slowly pull the camera back and then cut to a frontal close up shot of the man's face looking thoughtfully at the paper in the typewriter.",
            "https://skyreels-api.oss-cn-hongkong.aliyuncs.com/examples/image2video/image_03.png",
        )
        .duration(5)
        .sound(true)
        .mode(Mode::Std)
        .build();

    // Submit the request
    match client.image2video().submit(request).await {
        Ok(task_id) => {
            info!("Task submitted successfully with ID: {}", task_id);

            // Example 2: Query task status
            info!("Querying task status...");
            match client.image2video().get_task(&task_id).await {
                Ok(response) => {
                    info!("Task status: {}", response.get_status());

                    // Output complete JSON response for debugging
                    if let Ok(json) = response.pretty_print() {
                        info!("Full response JSON:\n{}", json);
                    }

                    match response.get_status() {
                        TaskStatus::Success => {
                            if let Some(video_data) = response.get_video_data() {
                                info!("Video ready!");
                                info!("URL: {}", video_data.video_url);
                                info!("Duration: {} seconds", video_data.duration);
                                info!("Resolution: {}", video_data.resolution);
                            }
                        }
                        TaskStatus::Failed => {
                            warn!("Task failed: {}", response.msg);
                        }
                        TaskStatus::Submitted | TaskStatus::Pending | TaskStatus::Running => {
                            info!("Task is still being processed...");

                            // Example 3: Wait for task completion
                            info!("Waiting for task completion...");
                            match client
                                .image2video()
                                .wait_for_completion(&task_id, 5, 120)
                                .await
                            {
                                Ok(result) => {
                                    if let Some(video_data) = result.get_video_data() {
                                        info!("Video completed successfully!");
                                        info!("Video URL: {}", video_data.video_url);
                                        info!("Duration: {} seconds", video_data.duration);
                                        info!("Resolution: {}", video_data.resolution);
                                    }
                                }
                                Err(e) => {
                                    warn!("Failed to wait for task completion: {}", e);
                                }
                            }
                        }
                        _ => {
                            info!("Unknown task status");
                        }
                    }
                }
                Err(e) => {
                    warn!("Failed to query task status: {}", e);
                }
            }
        }
        Err(e) => {
            warn!("Failed to submit task: {}", e);
        }
    }

    // Example 4: Submit with custom parameters
    info!("\nSubmitting image-to-video task with custom parameters");
    let _custom_request = client
        .image2video()
        .submit_request(
            "Camera pans slowly across a landscape scene",
            "https://skyreels-api.oss-cn-hongkong.aliyuncs.com/examples/image2video/image_03.png",
        )
        .duration(10)
        .sound(true)
        .mode(Mode::Std)
        .build();

    info!("Custom request created (not submitted in this example)");

    // Example 5: Query an existing task (if you have a task ID)
    let existing_task_id = std::env::var("EXISTING_TASK_ID").ok();
    if let Some(task_id) = existing_task_id {
        info!("\nQuerying existing task: {}", task_id);
        match client.image2video().get_task(&task_id).await {
            Ok(response) => {
                info!("Task status: {}", response.get_status());
                if let Some(video_data) = response.get_video_data() {
                    info!("Video URL: {}", video_data.video_url);
                }
            }
            Err(e) => {
                warn!("Failed to query existing task: {}", e);
            }
        }
    } else {
        info!("\nNo existing task ID provided (set EXISTING_TASK_ID env var to query an existing task)");
    }

    Ok(())
}
