use serde::{Deserialize, Serialize};
use tokio_postgres::Row;

use crate::riback::{CurrencyId, ExchangeId, TypeId};

#[derive(Serialize, Deserialize, Debug)]
pub struct Symbol {
    pub id: i64,
    pub currency_id: CurrencyId,
    pub description: String,
    pub display_symbol: String,
    pub figi: String,
    pub isin: String,
    pub mic: String,
    pub share_class_figi: String,
    pub symbol: String,
    pub symbol2: String,
    pub type_id: TypeId,
    pub exchange_id: ExchangeId,
}

impl TryFrom<&Row> for Symbol {
    type Error = crate::Error;

    fn try_from(value: &Row) -> Result<Self, Self::Error> {
        let id: i64 = value.try_get("id")?;
        let currency_id: i64 = value.try_get("currency_id")?;
        let description: String = value.try_get("description")?;
        let display_symbol: String = value.try_get("display_symbol")?;
        let figi: String = value.try_get("figi")?;
        let isin: String = value.try_get("isin")?;
        let mic: String = value.try_get("mic")?;
        let share_class_figi: String = value.try_get("share_class_figi")?;
        let symbol: String = value.try_get("symbol")?;
        let symbol2: String = value.try_get("symbol2")?;
        let type_id: i64 = value.try_get("type_id")?;
        let exchange_id: i64 = value.try_get("exchange_id")?;

        let currency_id: CurrencyId = currency_id.try_into()?;
        let type_id: TypeId = type_id.try_into()?;
        let exchange_id: ExchangeId = exchange_id.try_into()?;

        Ok(Symbol {
            id,
            currency_id,
            description,
            display_symbol,
            figi,
            isin,
            mic,
            share_class_figi,
            symbol,
            symbol2,
            type_id,
            exchange_id,
        })
    }
}
