use crate::{
    chaindef::{OutPointHash, ScriptHash},
    store::{db_decode, db_encode, Row},
};
use bitcoin_hashes::Hash;

use super::DBRow;

const UNSPENTINDEX_CF: &str = "unspent";

/// This is a database in rostrum that is NOT write-only.
/// This only contains utxos at the chain tip.

#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct UnspentIndexKey {
    pub scripthash: [u8; 32],
    pub outpointhash: [u8; 32],
}

#[derive(Debug)]
pub struct UnspentIndexRow {
    pub key: UnspentIndexKey,
    pub has_token: bool,
}

impl UnspentIndexRow {
    pub fn new(scripthash: &ScriptHash, o: &OutPointHash, has_token: bool) -> Self {
        Self {
            key: UnspentIndexKey {
                scripthash: scripthash.into_inner(),
                outpointhash: o.into_inner(),
            },
            has_token,
        }
    }

    pub fn to_key(scripthash: &ScriptHash, oph: &OutPointHash) -> Vec<u8> {
        db_encode(&UnspentIndexKey {
            outpointhash: *oph.as_inner(),
            scripthash: *scripthash.as_inner(),
        })
        .unwrap()
    }

    pub fn scripthash_filter(scripthash: &ScriptHash) -> Vec<u8> {
        scripthash.as_inner().to_vec()
    }

    pub fn has_token(&self) -> bool {
        self.has_token
    }

    pub fn outpointhash(&self) -> OutPointHash {
        OutPointHash::from_inner(self.key.outpointhash)
    }

    /// Get a reference to the inner outpointhash bytes
    pub fn outpointhash_inner(&self) -> &[u8; 32] {
        &self.key.outpointhash
    }
}

impl DBRow for UnspentIndexRow {
    const CF: &'static str = UNSPENTINDEX_CF;
    fn to_row(&self) -> Row {
        Row {
            key: db_encode(&self.key).unwrap().into_boxed_slice(),
            value: db_encode(&self.has_token).unwrap().into_boxed_slice(),
        }
    }

    fn from_row(row: &Row) -> Self {
        Self {
            key: db_decode(&row.key).expect("failed to parse UnspentIndexRow"),
            has_token: db_decode(&row.value).expect("failed to parse UnspentIndexRow value"),
        }
    }
}
