// Prevents additional console window on Windows in release
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use base64::Engine;
use std::fs;
use std::sync::Mutex;
use subtitle_merge_lib::{
    check_ffmpeg, extract_thumbnails_impl, get_video_duration, merge_video_subtitle_impl,
    process_transcription_impl, test_gemini_api_impl, Error, MergeArgs, ProgressState,
    ThumbnailState, TranscriptionArgs,
};
use tauri::Runtime;

#[tauri::command]
async fn check_dependencies() -> Result<(), Error> {
    check_ffmpeg().await
}

#[tauri::command]
fn get_progress(progress_state: tauri::State<'_, ProgressState>) -> f32 {
    *progress_state.0.lock().unwrap()
}

#[tauri::command]
async fn merge_video_subtitle<R: Runtime>(
    args: MergeArgs,
    progress_state: tauri::State<'_, ProgressState>,
    app_handle: tauri::AppHandle<R>,
) -> Result<String, Error> {
    merge_video_subtitle_impl(args, progress_state, app_handle).await
}

#[tauri::command]
async fn test_gemini_api<R: Runtime>(
    app_handle: tauri::AppHandle<R>,
    api_key: String,
) -> Result<(), Error> {
    test_gemini_api_impl(&app_handle, &api_key).await
}

#[tauri::command]
async fn get_video_duration_command(path: String) -> Result<f32, Error> {
    get_video_duration(&path).await
}

#[tauri::command]
async fn extract_thumbnails(
    path: String,
    interval: u32,
    thumbnail_state: tauri::State<'_, Mutex<ThumbnailState>>,
) -> Result<Vec<subtitle_merge_lib::Thumbnail>, Error> {
    extract_thumbnails_impl(&path, interval, thumbnail_state).await
}

#[tauri::command]
async fn process_transcription<R: Runtime>(
    app_handle: tauri::AppHandle<R>,
    args: TranscriptionArgs,
) -> Result<subtitle_merge_lib::TranscriptionResult, Error> {
    process_transcription_impl(&app_handle, args).await
}

#[tauri::command]
async fn generate_thumbnails(
    video_path: String,
    thumbnail_state: tauri::State<'_, Mutex<ThumbnailState>>,
) -> Result<Vec<subtitle_merge_lib::Thumbnail>, Error> {
    // Generate thumbnails every 10 seconds
    extract_thumbnails_impl(&video_path, 10, thumbnail_state).await
}

#[tauri::command]
async fn read_thumbnail(
    path: String,
    thumbnail_state: tauri::State<'_, Mutex<ThumbnailState>>,
) -> Result<String, Error> {
    // Verify the path is within our temp directory to prevent unauthorized access
    let state = thumbnail_state.lock().unwrap();
    if let Some(temp_dir) = state.get_temp_dir() {
        let temp_path = temp_dir.path();
        let requested_path = std::path::Path::new(&path);

        // Check if the requested path is within our temp directory
        if !requested_path.starts_with(temp_path) {
            return Err(Error::IoError(std::io::Error::new(
                std::io::ErrorKind::PermissionDenied,
                "Attempted to access file outside of temporary directory",
            )));
        }

        let data = fs::read(&path).map_err(|e| Error::IoError(e))?;
        Ok(base64::engine::general_purpose::STANDARD.encode(&data))
    } else {
        Err(Error::IoError(std::io::Error::new(
            std::io::ErrorKind::NotFound,
            "No active thumbnail session",
        )))
    }
}

fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_store::Builder::new().build())
        .plugin(tauri_plugin_shell::init())
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_fs::init())
        .manage(ProgressState::default())
        .manage(Mutex::new(ThumbnailState::default()))
        .setup(|_app| Ok(()))
        .invoke_handler(tauri::generate_handler![
            merge_video_subtitle,
            check_dependencies,
            get_progress,
            test_gemini_api,
            get_video_duration_command,
            extract_thumbnails,
            process_transcription,
            generate_thumbnails,
            read_thumbnail
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
