// file: kb_lib/src/db/dtos/local_dex_corpus_search.rs

//! DTOs for local DEX corpus searches used by Demo3.

/// Search request for local DEX corpus discovery.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct LocalDexCorpusSearchRequestDto {
    /// Optional DEX code or decoded protocol name.
    pub dex_code: std::option::Option<std::string::String>,
    /// Optional Solana program id.
    pub program_id: std::option::Option<std::string::String>,
    /// Optional local pair id.
    pub pair_id: std::option::Option<i64>,
    /// Optional pool account/address.
    pub pool_address: std::option::Option<std::string::String>,
    /// Optional token mint to match as base, quote or decoded mint.
    pub token_mint: std::option::Option<std::string::String>,
    /// Optional transaction signature.
    pub signature: std::option::Option<std::string::String>,
    /// Maximum number of rows to return per sample category.
    pub limit: u32,
}

/// Result of a local DEX corpus search.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct LocalDexCorpusSearchResultDto {
    /// Normalized request used for the search.
    pub request: crate::LocalDexCorpusSearchRequestDto,
    /// Aggregate counts for matching local data.
    pub summary: crate::LocalDexCorpusSearchSummaryDto,
    /// Matching transaction samples.
    pub transaction_samples: std::vec::Vec<crate::LocalDexCorpusTransactionSampleDto>,
    /// Matching pool/pair samples.
    pub pool_pair_samples: std::vec::Vec<crate::LocalDexCorpusPoolPairSampleDto>,
    /// Matching decoded event samples.
    pub decoded_event_samples: std::vec::Vec<crate::LocalDexCorpusDecodedEventSampleDto>,
}

/// Aggregate counts for a local DEX corpus search.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct LocalDexCorpusSearchSummaryDto {
    /// Number of distinct matching transactions.
    pub transaction_count: i64,
    /// Number of distinct matching instructions.
    pub instruction_count: i64,
    /// Number of distinct matching decoded DEX events.
    pub decoded_event_count: i64,
    /// Number of distinct matching pools.
    pub pool_count: i64,
    /// Number of distinct matching pairs.
    pub pair_count: i64,
    /// Number of distinct matching trade events.
    pub trade_event_count: i64,
    /// Number of distinct matching candle rows.
    pub pair_candle_count: i64,
    /// Number of distinct matching protocol-candidate rows.
    pub protocol_candidate_count: i64,
}

/// Matching transaction sample for corpus discovery.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct LocalDexCorpusTransactionSampleDto {
    /// Transaction id.
    pub transaction_id: i64,
    /// Transaction signature.
    pub signature: std::string::String,
    /// Optional Solana slot.
    pub slot: std::option::Option<i64>,
    /// Whether the transaction has a non-null error payload.
    pub failed: bool,
    /// Number of persisted instructions for the transaction.
    pub instruction_count: i64,
    /// Number of persisted decoded DEX events for the transaction.
    pub decoded_event_count: i64,
    /// Number of persisted trade events for the transaction.
    pub trade_event_count: i64,
    /// Comma-separated distinct program ids seen in the transaction.
    pub program_ids_csv: std::string::String,
}

/// Matching pool/pair sample for corpus discovery.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct LocalDexCorpusPoolPairSampleDto {
    /// Optional pool id.
    pub pool_id: std::option::Option<i64>,
    /// Optional pool address.
    pub pool_address: std::option::Option<std::string::String>,
    /// Optional pair id.
    pub pair_id: std::option::Option<i64>,
    /// Optional DEX code.
    pub dex_code: std::option::Option<std::string::String>,
    /// Optional pair symbol.
    pub pair_symbol: std::option::Option<std::string::String>,
    /// Optional base token mint.
    pub base_mint: std::option::Option<std::string::String>,
    /// Optional base token symbol.
    pub base_symbol: std::option::Option<std::string::String>,
    /// Optional quote token mint.
    pub quote_mint: std::option::Option<std::string::String>,
    /// Optional quote token symbol.
    pub quote_symbol: std::option::Option<std::string::String>,
    /// Number of decoded events attached to the pool.
    pub decoded_event_count: i64,
    /// Number of trade events attached to the pair.
    pub trade_event_count: i64,
    /// Number of candle rows attached to the pair.
    pub pair_candle_count: i64,
    /// Latest known founding or activity signature for the pool/pair.
    pub latest_signature: std::option::Option<std::string::String>,
}

/// Matching decoded event sample for corpus discovery.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct LocalDexCorpusDecodedEventSampleDto {
    /// Decoded event id.
    pub decoded_event_id: i64,
    /// Transaction id.
    pub transaction_id: i64,
    /// Transaction signature.
    pub signature: std::string::String,
    /// Optional Solana slot.
    pub slot: std::option::Option<i64>,
    /// Protocol name stored on the decoded event.
    pub protocol_name: std::string::String,
    /// Program id stored on the decoded event.
    pub program_id: std::string::String,
    /// Event kind.
    pub event_kind: std::string::String,
    /// Optional pool account.
    pub pool_account: std::option::Option<std::string::String>,
    /// Optional token A mint.
    pub token_a_mint: std::option::Option<std::string::String>,
    /// Optional token B mint.
    pub token_b_mint: std::option::Option<std::string::String>,
    /// Decoded event category extracted from payload JSON.
    pub event_category: std::option::Option<std::string::String>,
    /// Decoded event lifecycle kind extracted from payload JSON.
    pub event_lifecycle_kind: std::option::Option<std::string::String>,
    /// Decoded event actionability extracted from payload JSON.
    pub event_actionability: std::option::Option<std::string::String>,
    /// Whether the decoded event is a trade candidate.
    pub trade_candidate: bool,
    /// Whether the decoded event is a candle candidate.
    pub candle_candidate: bool,
}

/// SQL row for aggregate counts of a local DEX corpus search.
#[derive(Debug, Clone, sqlx::FromRow)]
pub(crate) struct LocalDexCorpusSearchSummaryRow {
    pub(crate) transaction_count: i64,
    pub(crate) instruction_count: i64,
    pub(crate) decoded_event_count: i64,
    pub(crate) pool_count: i64,
    pub(crate) pair_count: i64,
    pub(crate) trade_event_count: i64,
    pub(crate) pair_candle_count: i64,
    pub(crate) protocol_candidate_count: i64,
}

/// SQL row for a matching transaction sample.
#[derive(Debug, Clone, sqlx::FromRow)]
pub(crate) struct LocalDexCorpusTransactionSampleRow {
    pub(crate) transaction_id: i64,
    pub(crate) signature: std::string::String,
    pub(crate) slot: std::option::Option<i64>,
    pub(crate) failed: i64,
    pub(crate) instruction_count: i64,
    pub(crate) decoded_event_count: i64,
    pub(crate) trade_event_count: i64,
    pub(crate) program_ids_csv: std::string::String,
}

/// SQL row for a matching pool/pair sample.
#[derive(Debug, Clone, sqlx::FromRow)]
pub(crate) struct LocalDexCorpusPoolPairSampleRow {
    pub(crate) pool_id: std::option::Option<i64>,
    pub(crate) pool_address: std::option::Option<std::string::String>,
    pub(crate) pair_id: std::option::Option<i64>,
    pub(crate) dex_code: std::option::Option<std::string::String>,
    pub(crate) pair_symbol: std::option::Option<std::string::String>,
    pub(crate) base_mint: std::option::Option<std::string::String>,
    pub(crate) base_symbol: std::option::Option<std::string::String>,
    pub(crate) quote_mint: std::option::Option<std::string::String>,
    pub(crate) quote_symbol: std::option::Option<std::string::String>,
    pub(crate) decoded_event_count: i64,
    pub(crate) trade_event_count: i64,
    pub(crate) pair_candle_count: i64,
    pub(crate) latest_signature: std::option::Option<std::string::String>,
}

/// SQL row for a matching decoded event sample.
#[derive(Debug, Clone, sqlx::FromRow)]
pub(crate) struct LocalDexCorpusDecodedEventSampleRow {
    pub(crate) decoded_event_id: i64,
    pub(crate) transaction_id: i64,
    pub(crate) signature: std::string::String,
    pub(crate) slot: std::option::Option<i64>,
    pub(crate) protocol_name: std::string::String,
    pub(crate) program_id: std::string::String,
    pub(crate) event_kind: std::string::String,
    pub(crate) pool_account: std::option::Option<std::string::String>,
    pub(crate) token_a_mint: std::option::Option<std::string::String>,
    pub(crate) token_b_mint: std::option::Option<std::string::String>,
    pub(crate) event_category: std::option::Option<std::string::String>,
    pub(crate) event_lifecycle_kind: std::option::Option<std::string::String>,
    pub(crate) event_actionability: std::option::Option<std::string::String>,
    pub(crate) trade_candidate: std::option::Option<i64>,
    pub(crate) candle_candidate: std::option::Option<i64>,
}

impl From<LocalDexCorpusSearchSummaryRow> for LocalDexCorpusSearchSummaryDto {
    fn from(row: LocalDexCorpusSearchSummaryRow) -> Self {
        return Self {
            transaction_count: row.transaction_count,
            instruction_count: row.instruction_count,
            decoded_event_count: row.decoded_event_count,
            pool_count: row.pool_count,
            pair_count: row.pair_count,
            trade_event_count: row.trade_event_count,
            pair_candle_count: row.pair_candle_count,
            protocol_candidate_count: row.protocol_candidate_count,
        };
    }
}

impl From<LocalDexCorpusTransactionSampleRow> for LocalDexCorpusTransactionSampleDto {
    fn from(row: LocalDexCorpusTransactionSampleRow) -> Self {
        return Self {
            transaction_id: row.transaction_id,
            signature: row.signature,
            slot: row.slot,
            failed: row.failed != 0,
            instruction_count: row.instruction_count,
            decoded_event_count: row.decoded_event_count,
            trade_event_count: row.trade_event_count,
            program_ids_csv: row.program_ids_csv,
        };
    }
}

impl From<LocalDexCorpusPoolPairSampleRow> for LocalDexCorpusPoolPairSampleDto {
    fn from(row: LocalDexCorpusPoolPairSampleRow) -> Self {
        return Self {
            pool_id: row.pool_id,
            pool_address: row.pool_address,
            pair_id: row.pair_id,
            dex_code: row.dex_code,
            pair_symbol: row.pair_symbol,
            base_mint: row.base_mint,
            base_symbol: row.base_symbol,
            quote_mint: row.quote_mint,
            quote_symbol: row.quote_symbol,
            decoded_event_count: row.decoded_event_count,
            trade_event_count: row.trade_event_count,
            pair_candle_count: row.pair_candle_count,
            latest_signature: row.latest_signature,
        };
    }
}

impl From<LocalDexCorpusDecodedEventSampleRow> for LocalDexCorpusDecodedEventSampleDto {
    fn from(row: LocalDexCorpusDecodedEventSampleRow) -> Self {
        return Self {
            decoded_event_id: row.decoded_event_id,
            transaction_id: row.transaction_id,
            signature: row.signature,
            slot: row.slot,
            protocol_name: row.protocol_name,
            program_id: row.program_id,
            event_kind: row.event_kind,
            pool_account: row.pool_account,
            token_a_mint: row.token_a_mint,
            token_b_mint: row.token_b_mint,
            event_category: row.event_category,
            event_lifecycle_kind: row.event_lifecycle_kind,
            event_actionability: row.event_actionability,
            trade_candidate: row.trade_candidate.unwrap_or(0) != 0,
            candle_candidate: row.candle_candidate.unwrap_or(0) != 0,
        };
    }
}
