-- Lua snippets
local ls = require("luasnip")
local s = ls.snippet
local t = ls.text_node
local i = ls.insert_node
local f = ls.function_node
local c = ls.choice_node
local d = ls.dynamic_node
local sn = ls.snippet_node
local fmt = require("luasnip.extras.fmt").fmt
local rep = require("luasnip.extras").rep

-- Return a table of snippets for Rust
-- stylua: ignore start
return {
  -- Basic main function
  s("main", fmt([[
  fn main() {{
      {}
  }}
  ]], {
    i(1, "// Your code here"),
  })),

  -- Function definition
  s("fn", fmt([[
  fn {}({}) {} {{
      {}
  }}
  ]], {
    i(1, "function_name"),
    i(2, ""),
    c(3, {
      t(""),
      t("-> ()"),
      sn(nil, {t("-> "), i(1, "ReturnType")}),
    }),
    i(4, "// Function body"),
  })),

  -- Public function
  s("pfn", fmt([[
  pub fn {}({}) {} {{
      {}
  }}
  ]], {
    i(1, "function_name"),
    i(2, ""),
    c(3, {
      t(""),
      t("-> ()"),
      sn(nil, {t("-> "), i(1, "ReturnType")}),
    }),
    i(4, "// Function body"),
  })),

  -- Struct definition
  s("struct", fmt([[
  struct {} {{
      {}
  }}
  ]], {
    i(1, "StructName"),
    i(2, "// fields"),
  })),

  -- Public struct
  s("pstruct", fmt([[
  pub struct {} {{
      {}
  }}
  ]], {
    i(1, "StructName"),
    i(2, "// fields"),
  })),

  -- Struct implementation
  s("impl", fmt([[
  impl {} {{
      {}
  }}
  ]], {
    i(1, "StructName"),
    i(2, "// methods"),
  })),

  -- Trait implementation
  s("implfor", fmt([[
  impl {} for {} {{
      {}
  }}
  ]], {
    i(1, "Trait"),
    i(2, "Type"),
    i(3, "// trait implementation"),
  })),

  -- Trait definition
  s("trait", fmt([[
  trait {} {{
      {}
  }}
  ]], {
    i(1, "TraitName"),
    i(2, "// trait methods"),
  })),

  -- Public trait
  s("ptrait", fmt([[
  pub trait {} {{
      {}
  }}
  ]], {
    i(1, "TraitName"),
    i(2, "// trait methods"),
  })),

  -- Enum definition
  s("enum", fmt([[
  enum {} {{
      {},
  }}
  ]], {
    i(1, "EnumName"),
    i(2, "// variants"),
  })),

  -- Public enum
  s("penum", fmt([[
  pub enum {} {{
      {},
  }}
  ]], {
    i(1, "EnumName"),
    i(2, "// variants"),
  })),

  -- Match expression
  s("match", fmt([[
  match {} {{
      {} => {},
      _ => {},
  }}
  ]], {
    i(1, "expression"),
    i(2, "pattern"),
    i(3, "result"),
    i(4, "default_result"),
  })),

  -- If let expression
  s("iflet", fmt([[
  if let {} = {} {{
      {}
  }}
  ]], {
    i(1, "pattern"),
    i(2, "expression"),
    i(3, "// code"),
  })),

  -- While let loop
  s("whilelet", fmt([[
  while let {} = {} {{
      {}
  }}
  ]], {
    i(1, "pattern"),
    i(2, "expression"),
    i(3, "// loop body"),
  })),

  -- For loop
  s("for", fmt([[
  for {} in {} {{
      {}
  }}
  ]], {
    i(1, "item"),
    i(2, "iterator"),
    i(3, "// loop body"),
  })),

  -- Loop
  s("loop", fmt([[
  loop {{
      {}

      {}
  }}
  ]], {
    i(1, "// loop body"),
    i(2, "break;"),
  })),

  -- Closure
  s("closure", fmt([[
  |{}| {} {{
      {}
  }}
  ]], {
    i(1, "args"),
    c(2, {
      t(""),
      sn(nil, {t("-> "), i(1, "ReturnType")}),
    }),
    i(3, "// closure body"),
  })),

  -- Derive attribute
  s("derive", fmt([[
  #[derive({})]
  ]], {
    i(1, "Debug, Clone"),
  })),

  -- Module
  s("mod", fmt([[
  mod {} {{
      {}
  }}
  ]], {
    i(1, "module_name"),
    i(2, "// module contents"),
  })),

  -- Public module
  s("pmod", fmt([[
  pub mod {} {{
      {}
  }}
  ]], {
    i(1, "module_name"),
    i(2, "// module contents"),
  })),

  -- Use statement
  s("use", fmt([[
  use {};
  ]], {
    i(1, "path::to::module"),
  })),

  -- Test module
  s("testmod", fmt([[
  #[cfg(test)]
  mod tests {{
      use super::*;

      #[test]
      fn {}() {{
          {}
      }}
  }}
  ]], {
    i(1, "test_name"),
    i(2, "// test code"),
  })),

  -- Test function
  s("test", fmt([[
  #[test]
  fn {}() {{
      {}
  }}
  ]], {
    i(1, "test_name"),
    i(2, "// test code"),
  })),

  -- Async function
  s("async", fmt([[
  async fn {}({}) {} {{
      {}
  }}
  ]], {
    i(1, "function_name"),
    i(2, ""),
    c(3, {
      t(""),
      t("-> ()"),
      sn(nil, {t("-> "), i(1, "ReturnType")}),
    }),
    i(4, "// async function body"),
  })),

  -- Result type
  s("result", fmt([[
  Result<{}, {}>
  ]], {
    i(1, "T"),
    i(2, "Error"),
  })),

  -- Option type
  s("option", fmt([[
  Option<{}>
  ]], {
    i(1, "T"),
  })),

  -- Unwrap with error message
  s("expect", fmt([[
  .expect("{}")
  ]], {
    i(1, "Failed to unwrap value"),
  })),

  -- Print debug
  s("dbg", fmt([[
  dbg!({});
  ]], {
    i(1, "expression"),
  })),

  -- Print
  s("print", fmt([[
  println!("{}", {});
  ]], {
    i(1, "{}"),
    i(2, "expression"),
  })),

  -- Let statement
  s("let", fmt([[
  let {} = {};
  ]], {
    i(1, "variable"),
    i(2, "value"),
  })),

  -- Let mut statement
  s("letmut", fmt([[
  let mut {} = {};
  ]], {
    i(1, "variable"),
    i(2, "value"),
  })),
}
-- stylua: ignore end
