pub trait ClipboardProvider {
  fn read_text(&self) -> Result<String, String>;
  fn write_text(&self, text: &str) -> Result<(), String>;
}

pub struct MockClipboard {
  content: std::cell::RefCell<String>,
}

impl MockClipboard {
  pub fn new(initial: &str) -> Self {
    Self {
      content: std::cell::RefCell::new(initial.to_string()),
    }
  }
}

impl ClipboardProvider for MockClipboard {
  fn read_text(&self) -> Result<String, String> {
    Ok(self.content.borrow().clone())
  }

  fn write_text(&self, text: &str) -> Result<(), String> {
    *self.content.borrow_mut() = text.to_string();
    Ok(())
  }
}

pub struct SystemClipboard {
  app_handle: tauri::AppHandle,
}

impl SystemClipboard {
  pub fn new(app_handle: tauri::AppHandle) -> Self {
    Self { app_handle }
  }
}

impl ClipboardProvider for SystemClipboard {
  fn read_text(&self) -> Result<String, String> {
    use tauri_plugin_clipboard_manager::ClipboardExt;
    self
      .app_handle
      .clipboard()
      .read_text()
      .map_err(|e| e.to_string())
  }

  fn write_text(&self, text: &str) -> Result<(), String> {
    use tauri_plugin_clipboard_manager::ClipboardExt;
    self
      .app_handle
      .clipboard()
      .write_text(text.to_string())
      .map_err(|e| e.to_string())
  }
}
