use std::path::PathBuf;
use std::sync::Arc;
use std::thread;
use anyhow::{Result, Error};
use log::info;

use fuse_backend_rs::api::server::Server;
use fuse_backend_rs::transport::FuseSession;

use crate::fuse::markbase_fs::MarkBaseFs;

pub struct MountHandle {
    session: FuseSession,
    mount_path: PathBuf,
    user_id: String,
}

impl MountHandle {
    pub fn new(
        user_id: String,
        mount_path: PathBuf,
        _db_path: PathBuf,
        readonly: bool,
    ) -> Result<Self> {
        let fsname = "MarkBase";
        let subtype = &user_id;
        
        let session = FuseSession::new(&mount_path, fsname, subtype, readonly)
            .map_err(|e| Error::msg(format!("Failed to create FUSE session: {:?}", e)))?;
        
        Ok(MountHandle {
            session,
            mount_path,
            user_id,
        })
    }
    
    pub fn mount(&mut self, db_path: PathBuf) -> Result<()> {
        info!("Mounting MarkBase FUSE for user: {}", self.user_id);
        info!("Mount path: {}", self.mount_path.display());
        info!("Database: {}", db_path.display());
        
        self.session.mount()
            .map_err(|e| Error::msg(format!("Failed to mount: {:?}", e)))?;
        
        info!("FUSE session mounted successfully");
        
        Ok(())
    }
    
    pub fn unmount(&mut self) -> Result<()> {
        info!("Unmounting MarkBase FUSE for user: {}", self.user_id);
        
        self.session.umount()
            .map_err(|e| Error::msg(format!("Failed to unmount: {:?}", e)))?;
        
        self.session.wake()
            .map_err(|e| Error::msg(format!("Failed to wake session: {:?}", e)))?;
        
        info!("FUSE session unmounted successfully");
        
        Ok(())
    }
}

pub fn mount_user_fs(
    user_id: String,
    mount_path: PathBuf,
    db_path: PathBuf,
    readonly: bool,
) -> Result<()> {
    println!("[DEBUG] Creating mount handle...");
    let mut handle = MountHandle::new(user_id.clone(), mount_path.clone(), db_path.clone(), readonly)?;
    
    println!("[DEBUG] Calling session.mount()...");
    handle.mount(db_path.clone())?;
    
    println!("[DEBUG] Creating filesystem instance...");
    let backend = crate::fuse::backend::select_backend();
    let fs = Arc::new(MarkBaseFs::new(user_id.clone(), db_path, backend));
    
    let server = Arc::new(Server::new(fs));
    
    println!("[DEBUG] Creating FUSE channel...");
    let channel = handle.session.new_channel()
        .map_err(|e| Error::msg(format!("Failed to create channel: {:?}", e)))?;
    
    println!("[DEBUG] Starting FUSE request handler thread...");
    
    let user_id_clone = user_id.clone();
    
    let handler_thread = thread::spawn(move || {
        println!("[DEBUG] Handler thread started for user: {}", user_id_clone);
        
        let mut channel = channel;
        
        loop {
            match channel.get_request() {
                Ok(Some((reader, writer))) => {
                    println!("[DEBUG] Received FUSE request");
                    let writer = writer.into();
                    if let Err(e) = server.handle_message(reader, writer, None, None) {
                        println!("[WARN] Error handling FUSE request: {:?}", e);
                    }
                }
                Ok(None) => {
                    println!("[DEBUG] FUSE channel received signal to exit");
                    break;
                }
                Err(e) => {
                    println!("[WARN] Error getting FUSE request: {:?}", e);
                    break;
                }
            }
        }
        
        println!("[DEBUG] Handler thread exited for user: {}", user_id_clone);
    });
    
    println!("[DEBUG] Calling session.wait_mount()...");
    match handle.session.wait_mount() {
        Ok(_) => {
            println!("[INFO] wait_mount() returned OK - mount completed successfully");
        }
        Err(e) => {
            println!("[ERROR] wait_mount() failed: {:?}", e);
            return Err(Error::msg(format!("Failed to wait mount: {:?}", e)));
        }
    }
    
    println!("[INFO] Mount completed for user: {}", user_id);
    println!("[DEBUG] Handler thread status: {:?}", handler_thread.is_finished());
    
    println!("[DEBUG] Joining handler thread...");
    handler_thread.join()
        .map_err(|e| Error::msg(format!("Handler thread error: {:?}", e)))?;
    
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::path::PathBuf;
    
    #[test]
    fn test_mount_handle_creation() {
        let mount_path = PathBuf::from("/tmp/test_mount");
        let db_path = PathBuf::from("/tmp/test.sqlite");
        
        let result = MountHandle::new(
            "test_user".to_string(),
            mount_path,
            db_path,
            false,
        );
        
        assert!(result.is_ok());
    }
}