//! Derive macros for the gilt terminal formatting library.
//!
//! This crate provides the `#[derive(Table)]`, `#[derive(Panel)]`, `#[derive(Tree)]`,
//! `#[derive(Columns)]`, `#[derive(Rule)]`, `#[derive(Inspect)]`, and `#[derive(Renderable)]` macros that generate widget
//! conversion methods and trait implementations for structs.
//!
//! # Table Example
//!
//! ```ignore
//! use gilt::Table;
//!
//! #[derive(Table)]
//! #[table(title = "Employees", box_style = "ROUNDED", header_style = "bold cyan")]
//! struct Employee {
//!     #[column(header = "Full Name", style = "bold")]
//!     name: String,
//!     #[column(justify = "right")]
//!     age: u32,
//!     #[column(skip)]
//!     internal_id: u64,
//!     #[column(header = "Dept", style = "green", min_width = 10)]
//!     department: String,
//! }
//!
//! let employees = vec![
//!     Employee {
//!         name: "Alice".into(),
//!         age: 30,
//!         internal_id: 1001,
//!         department: "Engineering".into(),
//!     },
//!     Employee {
//!         name: "Bob".into(),
//!         age: 25,
//!         internal_id: 1002,
//!         department: "Marketing".into(),
//!     },
//! ];
//! let table = Employee::to_table(&employees);
//! ```
//!
//! # Panel Example
//!
//! ```ignore
//! use gilt::Panel;
//!
//! #[derive(Panel)]
//! #[panel(title = "Server Status", box_style = "ROUNDED", border_style = "blue")]
//! struct ServerStatus {
//!     #[field(label = "Host", style = "bold cyan")]
//!     name: String,
//!     #[field(label = "CPU %", style = "yellow")]
//!     cpu: f32,
//!     #[field(skip)]
//!     internal_id: u64,
//!     #[field(label = "Memory", style = "green")]
//!     memory: f32,
//! }
//!
//! let status = ServerStatus {
//!     name: "web-01".into(),
//!     cpu: 42.5,
//!     internal_id: 1001,
//!     memory: 67.3,
//! };
//! let panel = status.to_panel();
//! ```

mod columns;
mod inspect;
mod panel;
mod renderable;
mod rule;
mod shared;
mod table;
mod tree;

use proc_macro::TokenStream;
#[cfg(test)]
use proc_macro2::Span;
use syn::{parse_macro_input, DeriveInput};

// ===========================================================================
// Tree derive entry point (impl moved to crate::tree in v0.11.4)
// ===========================================================================

/// Derive macro generating `to_tree(&self) -> gilt::tree::Tree`.
/// See [`crate::tree`] for full attribute schema.
#[proc_macro_derive(Tree, attributes(tree))]
pub fn derive_tree(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    match tree::derive_tree_impl(&input) {
        Ok(ts) => ts.into(),
        Err(e) => e.to_compile_error().into(),
    }
}

// ===========================================================================
// Renderable derive entry point (impl moved to crates::renderable in v0.11.4)
// ===========================================================================

/// Derive macro that generates a `gilt::console::Renderable` implementation
/// for a struct, delegating to one of the existing widget derives.
///
/// See [`crate::renderable`] for full attribute schema and behaviour.
#[proc_macro_derive(Renderable, attributes(renderable))]
pub fn derive_renderable(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    match renderable::derive_renderable_impl(&input) {
        Ok(ts) => ts.into(),
        Err(e) => e.to_compile_error().into(),
    }
}

// ===========================================================================
// Inspect derive entry point (impl moved to crate::inspect in v0.11.4)
// ===========================================================================

/// Derive macro that generates a `to_inspect(&self) -> gilt::inspect::Inspect`
/// method for structs implementing `Debug`. See [`crate::inspect`] for the
/// full attribute schema.
#[proc_macro_derive(Inspect, attributes(inspect))]
pub fn derive_inspect(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    match inspect::derive_inspect_impl(&input) {
        Ok(ts) => ts.into(),
        Err(e) => e.to_compile_error().into(),
    }
}

// ===========================================================================
// Rule derive entry point (impl moved to crate::rule in v0.11.4)
// ===========================================================================

/// Derive macro that generates a `to_rule(&self) -> gilt::rule::Rule` method.
/// See [`crate::rule`] for the full attribute schema.
#[proc_macro_derive(Rule, attributes(rule))]
pub fn derive_rule(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    match rule::derive_rule_impl(&input) {
        Ok(ts) => ts.into(),
        Err(e) => e.to_compile_error().into(),
    }
}

// ===========================================================================
// Columns derive entry point (impl moved to crate::columns in v0.11.4)
// ===========================================================================

/// Derive macro generating `to_columns(items: &[Self]) -> gilt::columns::Columns`.
/// See [`crate::columns`] for full attribute schema.
#[proc_macro_derive(Columns, attributes(columns, field))]
pub fn derive_columns(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    match columns::derive_columns_impl(&input) {
        Ok(ts) => ts.into(),
        Err(e) => e.to_compile_error().into(),
    }
}

// ===========================================================================
// Panel derive entry point (impl moved to crate::panel in v0.11.4)
// ===========================================================================

/// Derive macro generating `to_panel(&self) -> gilt::panel::Panel`.
/// See [`crate::panel`] for full attribute schema.
#[proc_macro_derive(Panel, attributes(panel, field))]
pub fn derive_panel(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    match panel::derive_panel_impl(&input) {
        Ok(ts) => ts.into(),
        Err(e) => e.to_compile_error().into(),
    }
}

// ===========================================================================
// Table derive entry point (impl moved to crate::table in v0.11.4)
// ===========================================================================

/// Derive macro generating `to_table(items: &[Self]) -> gilt::table::Table`.
/// See [`crate::table`] for full attribute schema.
#[proc_macro_derive(Table, attributes(table, column))]
pub fn derive_table(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    match table::derive_table_impl(&input) {
        Ok(ts) => ts.into(),
        Err(e) => e.to_compile_error().into(),
    }
}

// ---------------------------------------------------------------------------
// Tests (extracted to tests.rs in v1.2 cleanup)
// ---------------------------------------------------------------------------

#[cfg(test)]
mod tests;
