//! ph-cli : A blazing-fast CLI & TUI for Product Hunt.
//!
//! # Usage
//!
//! ```bash
//! ph                  # Launch TUI mode
//! ph today            # Show today's launches
//! ph search "AI"      # Search products
//! ph post <id>        # View post details
//! ph login            # Authenticate
//! ph --json today     # JSON output for scripts
//! ```

use color_eyre::eyre::Result;
use ph_cli_core::Error as PhError;

mod cli;
mod commands;
mod tui;

use cli::{Cli, Commands};

#[tokio::main]
async fn main() -> Result<()> {
    color_eyre::install()?;

    let cli = Cli::parse_args();
    let is_tui = cli
        .command
        .as_ref()
        .is_none_or(|c| matches!(c, Commands::Tui));

    // Only initialize tracing for non-TUI commands.
    // TUI mode uses raw terminal, log output corrupts the display.
    if !is_tui {
        let log_level = match cli.verbose {
            0 => "ph=info,ph_cli_core=info",
            1 => "ph=debug,ph_cli_core=debug",
            _ => "ph=trace,ph_cli_core=trace",
        };
        tracing_subscriber::fmt()
            .with_env_filter(log_level)
            .with_writer(std::io::stderr)
            .init();
    }

    let mut client = ph_cli_core::Client::new().await?;

    let command = cli.command.unwrap_or(Commands::Tui);

    let result: std::result::Result<(), PhError> = match command {
        Commands::Tui => tui::run(client)
            .await
            .map_err(|e| PhError::Other(e.to_string())),
        Commands::Login => commands::login::execute(&mut client).await,
        Commands::Logout => commands::login::logout(&mut client).await,
        Commands::Today => commands::today::execute(&mut client, cli.limit, cli.json).await,
        Commands::Search { query } => {
            commands::search::execute(&mut client, &query, cli.limit, cli.json).await
        }
        Commands::Post { id } => commands::post::execute(&mut client, &id, cli.json).await,
        Commands::Status => commands::status::execute(&client).await,
    };

    if let Err(e) = result {
        eprintln!("Error: {}", e);
        std::process::exit(e.exit_code());
    }

    Ok(())
}
