use serde::de::DeserializeOwned;
use tauri::{plugin::PluginApi, AppHandle, Runtime};

use crate::models::*;

pub fn init<R: Runtime, C: DeserializeOwned>(
    app: &AppHandle<R>,
    _api: PluginApi<R, C>,
) -> crate::Result<Wallpaper<R>> {
    Ok(Wallpaper(app.clone()))
}

/// Access to the wallpaper APIs.
pub struct Wallpaper<R: Runtime>(AppHandle<R>);

impl<R: Runtime> Wallpaper<R> {
    fn demo() -> WallpaperState {
        WallpaperState {
            image_count: 3,
            enabled: true,
            interval_minutes: 30,
            shuffle: true,
            lock_screen_only: true,
            current_index: 0,
            image_urls: vec![
                "/wallpapers/alpine.png".into(),
                "/wallpapers/waterfall.png".into(),
                "/wallpapers/coast.png".into(),
            ],
        }
    }
    pub fn get_state(&self) -> crate::Result<WallpaperState> {
        Ok(Self::demo())
    }
    pub fn get_gallery(&self, payload: GalleryRequest) -> crate::Result<GalleryPage> {
        let urls = Self::demo().image_urls;
        let items = urls
            .into_iter()
            .enumerate()
            .skip(payload.offset)
            .take(payload.limit)
            .map(|(index, url)| GalleryImage {
                id: format!("demo-{index}"),
                url,
                selected: index == 0,
                crop_mode: "cover".into(),
                crop_zoom: 1.0,
                crop_position_x: 0.5,
                crop_position_y: 0.5,
                crop_rotation: 0,
            })
            .collect();
        Ok(GalleryPage { total: 3, items })
    }
    pub fn select_images(&self) -> crate::Result<WallpaperState> {
        Ok(Self::demo())
    }
    pub fn delete_image(&self, _payload: DeleteImageRequest) -> crate::Result<WallpaperState> {
        Ok(Self::demo())
    }
    pub fn get_image_ids(&self) -> crate::Result<Vec<String>> {
        Ok((0..Self::demo().image_count).map(|index| format!("demo-{index}")).collect())
    }
    pub fn delete_images(&self, _payload: DeleteImagesRequest) -> crate::Result<WallpaperState> {
        Ok(Self::demo())
    }
    pub fn set_image_crop(&self, payload: ImageCropRequest) -> crate::Result<GalleryImage> {
        let url = Self::demo()
            .image_urls
            .into_iter()
            .nth(payload.id.trim_start_matches("demo-").parse().unwrap_or(0))
            .unwrap_or_default();
        Ok(GalleryImage {
            id: payload.id,
            url,
            selected: false,
            crop_mode: payload.mode,
            crop_zoom: payload.zoom,
            crop_position_x: payload.position_x,
            crop_position_y: payload.position_y,
            crop_rotation: payload.rotation,
        })
    }
    pub fn set_setting(&self, payload: SettingRequest) -> crate::Result<WallpaperState> {
        let mut state = Self::demo();
        match payload.name.as_str() {
            "enabled" => state.enabled = payload.value,
            "shuffle" => state.shuffle = payload.value,
            "lockScreenOnly" => state.lock_screen_only = payload.value,
            _ => {}
        };
        Ok(state)
    }
    pub fn set_interval(&self, payload: IntervalRequest) -> crate::Result<WallpaperState> {
        let mut state = Self::demo();
        state.interval_minutes = payload.minutes;
        state.enabled = payload.minutes > 0;
        Ok(state)
    }
    pub fn next_wallpaper(&self) -> crate::Result<WallpaperState> {
        let mut state = Self::demo();
        state.current_index = 1;
        Ok(state)
    }
    pub fn get_immich_connection(&self) -> crate::Result<ImmichConnection> {
        Ok(ImmichConnection::default())
    }
    pub fn connect_immich(&self, payload: ImmichConnectRequest) -> crate::Result<ImmichConnection> {
        Ok(ImmichConnection {
            configured: true,
            server_url: payload.server_url,
            user_name: "Demo User".into(),
        })
    }
    pub fn disconnect_immich(&self) -> crate::Result<ImmichConnection> {
        Ok(ImmichConnection::default())
    }
    pub fn get_immich_albums(&self) -> crate::Result<ImmichAlbumsResponse> {
        Ok(ImmichAlbumsResponse {
            albums: vec![ImmichAlbum {
                id: "demo-album".into(),
                name: "Nature".into(),
                asset_count: 3,
                thumbnail_url: "/wallpapers/alpine.png".into(),
            }],
        })
    }
    pub fn get_immich_assets(&self, payload: ImmichAssetsRequest) -> crate::Result<ImmichAssetsPage> {
        let urls = Self::demo().image_urls;
        Ok(ImmichAssetsPage {
            items: urls
                .into_iter()
                .enumerate()
                .map(|(index, thumbnail_url)| ImmichAsset {
                    id: format!("immich-demo-{index}"),
                    file_name: format!("wallpaper-{}.jpg", index + 1),
                    thumbnail_url,
                    taken_at: "2026-08-21T12:00:00Z".into(),
                })
                .collect(),
            page: payload.page,
            has_more: false,
        })
    }
    pub fn import_immich_assets(&self, _payload: ImmichImportRequest) -> crate::Result<WallpaperState> {
        Ok(Self::demo())
    }
    pub fn get_immich_import_progress(&self) -> crate::Result<ImmichImportProgress> {
        Ok(ImmichImportProgress::default())
    }
}
