use std::collections::HashMap;

use serde::{Deserialize, Serialize};

/// Frontend request payload for slash-command execution.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ExecuteTerminalCommandRequest {
    /// Workspace that originated the command.
    pub workspace_id: String,
    /// Raw slash-command input exactly as entered by the user.
    pub input: String,
}

/// Parsed slash command used internally by the backend command service.
#[derive(Debug, Clone, PartialEq)]
pub struct ChatCommandRequest {
    /// Normalized command verb such as `/search`.
    pub command: String,
    /// Positional command arguments.
    pub args: Vec<String>,
    /// Original raw input for debugging or future auditing.
    pub raw_input: String,
}

/// Backend response envelope for slash-command execution.
#[derive(Debug, Clone, Serialize, PartialEq)]
#[serde(tag = "kind", rename_all = "camelCase")]
pub enum TerminalCommandResponse {
    /// Plain text response rendered directly in the terminal.
    Text { content: String },
    /// Structured payload rendered by an existing terminal panel.
    Panel { panel: PanelPayload },
}

/// Serializable panel variants shared between Rust and React.
#[derive(Debug, Clone, Serialize, PartialEq)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum PanelPayload {
    Company {
        data: Company,
    },
    Portfolio {
        data: Portfolio,
    },
    News {
        data: Vec<NewsItem>,
        ticker: Option<String>,
    },
    Analysis {
        data: StockAnalysis,
    },
}

/// Company snapshot used by the company panel.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Company {
    pub symbol: String,
    pub name: String,
    pub price: f64,
    pub change: f64,
    pub change_percent: f64,
    pub market_cap: f64,
    pub volume: u64,
    pub pe: Option<f64>,
    pub eps: Option<f64>,
    pub high52_week: Option<f64>,
    pub low52_week: Option<f64>,
}

/// Portfolio holding row.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Holding {
    pub symbol: String,
    pub name: String,
    pub quantity: u64,
    pub avg_cost: f64,
    pub current_price: f64,
    pub current_value: f64,
    pub gain_loss: f64,
    pub gain_loss_percent: f64,
}

/// Portfolio summary and holdings data.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Portfolio {
    pub holdings: Vec<Holding>,
    pub total_value: f64,
    pub day_change: f64,
    pub day_change_percent: f64,
    pub total_gain: f64,
    pub total_gain_percent: f64,
}

/// News item serialized with an ISO timestamp for transport safety.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct NewsItem {
    pub id: String,
    pub source: String,
    pub headline: String,
    pub timestamp: String,
    pub snippet: String,
    pub url: Option<String>,
    pub related_tickers: Vec<String>,
}

/// Structured analysis payload for the analysis panel.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct StockAnalysis {
    pub symbol: String,
    pub summary: String,
    pub sentiment: String,
    pub key_points: Vec<String>,
    pub risks: Vec<String>,
    pub opportunities: Vec<String>,
    pub recommendation: String,
    pub target_price: Option<f64>,
}

/// Shared mock financial fixture loaded by both the frontend and backend.
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MockFinancialData {
    #[allow(dead_code)]
    pub companies: Vec<Company>,
    pub portfolio: Portfolio,
    pub news_items: Vec<NewsItem>,
    pub analyses: HashMap<String, StockAnalysis>,
}
