/// Windows Cloud Filter API 平台适配器
/// 仅在 windows-cfapi feature 启用时编译
#[cfg(feature = "windows-cfapi")]
use std::path::Path;
#[cfg(feature = "windows-cfapi")]
use std::sync::Arc;
#[cfg(feature = "windows-cfapi")]
use tokio::sync::mpsc;

#[cfg(feature = "windows-cfapi")]
use crate::api_client::ApiClient;
#[cfg(feature = "windows-cfapi")]
use crate::errors::Result;
#[cfg(feature = "windows-cfapi")]
use crate::models::SyncConfig;
#[cfg(feature = "windows-cfapi")]
use crate::sync_db::SyncDb;
#[cfg(feature = "windows-cfapi")]
use crate::worker::PlaceholderCreator;

#[cfg(feature = "windows-cfapi")]
pub struct WcfPlatformAdapter {
    adapter: std::sync::Mutex<sync_windows::WindowsAdapter>,
    fetch_rx: std::sync::Mutex<Option<mpsc::Receiver<sync_windows::FetchDataRequest>>>,
    #[allow(dead_code)]
    db: Arc<SyncDb>,
    #[allow(dead_code)]
    api: Arc<ApiClient>,
    #[allow(dead_code)]
    config: SyncConfig,
}

#[cfg(feature = "windows-cfapi")]
impl WcfPlatformAdapter {
    pub fn new(
        db: Arc<SyncDb>,
        api: Arc<ApiClient>,
        config: SyncConfig,
    ) -> anyhow::Result<Self> {
        let mut adapter = sync_windows::WindowsAdapter::new();

        // 注册同步根目录
        adapter.register_sync_root(
            &config.local_root,
            "Cloudreve4",
            "1.0",
        )?;

        // 连接同步根，注册回调
        adapter.connect_sync_root(&config.local_root)?;
        let fetch_rx = adapter.take_callback_receiver();

        tracing::info!("WcfPlatformAdapter 初始化完成: {}", config.local_root.display());

        Ok(Self {
            adapter: std::sync::Mutex::new(adapter),
            fetch_rx: std::sync::Mutex::new(fetch_rx),
            db,
            api,
            config,
        })
    }

    /// 取走 FETCH_DATA 回调接收端（供 SyncEngine 持续同步消费）
    pub fn take_fetch_receiver(&self) -> Option<mpsc::Receiver<sync_windows::FetchDataRequest>> {
        self.fetch_rx.lock().unwrap().take()
    }

    /// 创建占位符文件
    pub fn create_placeholder_for_remote(
        &self,
        base_dir: &Path,
        file_name: &str,
        file_size: u64,
        remote_uri: &str,
        remote_hash: Option<&str>,
        remote_mtime_ms: i64,
    ) -> Result<()> {
        let file_identity = serde_json::to_vec(&serde_json::json!({
            "uri": remote_uri,
            "size": file_size,
            "hash": remote_hash.unwrap_or(""),
            "mtime_ms": remote_mtime_ms,
        })).unwrap_or_default();

        self.adapter.lock().unwrap().create_single_placeholder(
            base_dir,
            file_name,
            file_size,
            &file_identity,
        ).map_err(|e| crate::errors::SyncError::FileSystem(e.to_string()))?;

        Ok(())
    }

    /// 水合文件（按需下载）
    pub fn hydrate_file(&self, local_path: &Path) -> Result<()> {
        self.adapter.lock().unwrap().hydrate_placeholder(local_path)
            .map_err(|e| crate::errors::SyncError::FileSystem(e.to_string()))
    }

    /// 脱水文件（释放本地空间）
    pub fn dehydrate_file(&self, local_path: &Path) -> Result<()> {
        self.adapter.lock().unwrap().dehydrate_placeholder(local_path)
            .map_err(|e| crate::errors::SyncError::FileSystem(e.to_string()))
    }

    /// 通过 CfExecute 将数据推送回 CFApi（内核层写入，绕过文件锁）
    pub fn fulfill_fetch_data(
        connection_key: i64,
        transfer_key: i64,
        data: &[u8],
        offset: i64,
    ) -> Result<()> {
        sync_windows::WindowsAdapter::fulfill_fetch_data(connection_key, transfer_key, data, offset)
            .map_err(|e| crate::errors::SyncError::FileSystem(e.to_string()))
    }

    /// 通过 CfExecute 报告水合失败
    pub fn reject_fetch_data(
        connection_key: i64,
        transfer_key: i64,
    ) -> Result<()> {
        sync_windows::WindowsAdapter::reject_fetch_data(connection_key, transfer_key)
            .map_err(|e| crate::errors::SyncError::FileSystem(e.to_string()))
    }

    /// 断开连接
    pub fn disconnect(&self) -> Result<()> {
        self.adapter.lock().unwrap().disconnect()
            .map_err(|e| crate::errors::SyncError::FileSystem(e.to_string()))
    }
}

#[cfg(feature = "windows-cfapi")]
#[async_trait::async_trait]
impl PlaceholderCreator for WcfPlatformAdapter {
    async fn create_placeholder_file(
        &self,
        base_dir: &Path,
        file_name: String,
        file_size: u64,
        file_identity: &[u8],
    ) -> Result<()> {
        self.adapter.lock().unwrap().create_single_placeholder(
            base_dir,
            &file_name,
            file_size,
            file_identity,
        ).map_err(|e| crate::errors::SyncError::FileSystem(e.to_string()))
    }
}
