#![allow(clippy::module_name_repetitions)]
use proc_macro::TokenStream;
use quote::quote;

pub fn category_enum_impl(_input: TokenStream) -> TokenStream {
    let expanded = quote! {
       use std::str::FromStr;
       use strum::{Display, EnumIter, EnumString, IntoEnumIterator, IntoStaticStr};

       #[derive(Debug, Clone, Copy, Display, PartialEq, Eq, EnumIter, EnumString, IntoStaticStr)]
       #[strum(serialize_all = "snake_case", use_phf)]
       enum Category {
           ANSI,
           AST,
           CLI,
           DSL,
           REPL,
           Async,
           AttributeMacros,
           AttributeParsing,
           Automation,
           Basic,
           Benchmark,
           BigNumbers,
           BuilderPattern,
           Caching,
           Color,
           CompileTime,
           Concepts,
           Configuration,
           Crates,
           Customization,
           Debugging,
           Demo,
           DeriveMacros,
           Detection,
           Diagnosis,
           Documentation,
           Environment,
           Ergonomics,
           ErrorHandling,
           Examples,
           Exploration,
           FileHandling,
           Filesystem,
           FunctionLikeMacros,
           GUI,
           Interactive,
           Learning,
           Linux,
           MacOS,
           Macros,
           Math,
           Migration,
           Mintty,
           Performance,
           ProcMacros,
           Profiling,
           Prototype,
           Recreational,
           Reference,
           Resilience,
           Styling,
           Synchronization,
           Technique,
           Terminal,
           Testing,
           ThagFrontEnds,
           Theming,
           Timing,
           Tools,
           TraitImplementation,
           TypeIdentification,
           TUI,
           Unsafe,
           Validation,
           Windows,
           Xterm,
       }

       /// Returns a vector of all valid category names as strings.
       ///
       /// This function is automatically generated by the `category_enum` macro and provides
       /// a complete list of categories, making it convenient for validation, UI prompts, or filtering.
       ///
       /// # Example
       ///
       /// ```rust
       /// use demo_proc_macros::category_enum;
       ///
       /// category_enum! {}
       ///
       /// let categories = Category::all_categories();
       /// assert_eq!(categories, vec![
       ///     "ansi",
       ///     "ast",
       ///     "cli",
       ///     "concepts",
       ///     "dsl",
       ///     "repl",
       ///     "async",
       ///     "attribute_macros",
       ///     "attribute_parsing",
       ///     "automation",
       ///     "basic",
       ///     "benchmark",
       ///     "big_numbers",
       ///     "builder_pattern",
       ///     "caching",
       ///     "color",
       ///     "compile_time",
       ///     "configuration",
       ///     "crates",
       ///     "customization",
       ///     "debugging",
       ///     "demo",
       ///     "derive_macros",
       ///     "detection",
       ///     "diagnosis",
       ///     "documentation",
       ///     "environment",
       ///     "ergonomics",
       ///     "error_handling",
       ///     "examples",
       ///     "exploration",
       ///     "file_handling",
       ///     "filesystem",
       ///     "function_like_macros",
       ///     "gui",
       ///     "interactive",
       ///     "learning",
       ///     "linux",
       ///     "mac_os",
       ///     "macros",
       ///     "math",
       ///     "migration",
       ///     "mintty",
       ///     "performance",
       ///     "proc_macros",
       ///     "profiling",
       ///     "prototype",
       ///     "recreational",
       ///     "reference",
       ///     "resilience",
       ///     "styling",
       ///     "synchronization",
       ///     "technique",
       ///     "terminal",
       ///     "testing",
       ///     "thag_front_ends",
       ///     "theming",
       ///     "timing",
       ///     "tools",
       ///     "trait_implementation",
       ///     "type_identification",
       ///     "tui",
       ///     "unsafe",
       ///     "validation",
       ///     "windows",
       ///     "xterm",
       /// ]);
       /// ```
        pub fn all_categories() -> Vec<String> {
            let v = {
                use std::sync::OnceLock;
                static GENERIC_LAZY: OnceLock<Vec<String>> = OnceLock::new();
                GENERIC_LAZY.get_or_init(|| Category::iter()
                    .map(|variant| variant.to_string())
                    .collect::<Vec<String>>())
            };
            v.clone()
        }
    };
    TokenStream::from(expanded)
}
