#![allow(dead_code)]
#![allow(unused_imports)]
use futures::stream::TryStreamExt;
use mongodb::{bson::oid::ObjectId, Collection};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LabResult {
    #[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
    pub id: Option<ObjectId>,
    #[serde(rename = "labResultId")]
    pub lab_result_id: String,
    #[serde(rename = "userId")]
    pub user_id: String,
    #[serde(rename = "profileId")]
    pub profile_id: String,
    #[serde(rename = "testType")]
    pub test_type: String,
    #[serde(rename = "testName")]
    pub test_name: String,
    pub results: serde_json::Value,
    #[serde(rename = "referenceRange")]
    pub reference_range: Option<String>,
    #[serde(rename = "isAbnormal")]
    pub is_abnormal: bool,
    #[serde(rename = "testedAt")]
    pub tested_at: chrono::DateTime<chrono::Utc>,
    #[serde(rename = "notes")]
    pub notes: Option<String>,
    #[serde(rename = "createdAt")]
    pub created_at: chrono::DateTime<chrono::Utc>,
    #[serde(rename = "updatedAt")]
    pub updated_at: chrono::DateTime<chrono::Utc>,
}

#[derive(Clone)]
pub struct LabResultRepository {
    pub collection: Collection<LabResult>,
}

impl LabResultRepository {
    pub fn new(collection: Collection<LabResult>) -> Self {
        Self { collection }
    }

    pub async fn create(
        &self,
        lab_result: LabResult,
    ) -> Result<LabResult, Box<dyn std::error::Error>> {
        self.collection.insert_one(lab_result.clone(), None).await?;
        Ok(lab_result)
    }

    pub async fn list_by_user(
        &self,
        user_id: &str,
    ) -> Result<Vec<LabResult>, Box<dyn std::error::Error>> {
        let filter = mongodb::bson::doc! {
            "userId": user_id
        };
        let cursor = self.collection.find(filter, None).await?;
        let results: Vec<_> = cursor.try_collect().await?;
        Ok(results)
    }
}
