#![allow(dead_code)]
#![allow(unused_imports)]
use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum InteractionSeverity {
    Mild,
    Moderate,
    Severe,
    Unknown,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DrugInteraction {
    pub drug1: String,
    pub drug2: String,
    pub severity: InteractionSeverity,
    pub description: String,
}

pub struct OpenFDAService {
    client: Client,
    base_url: String,
}

impl OpenFDAService {
    pub fn new() -> Self {
        Self {
            client: Client::new(),
            base_url: "https://api.fda.gov/drug/event.json".to_string(),
        }
    }

    /// Check for interactions between multiple drugs
    pub async fn check_interactions(
        &self,
        drugs: &[String],
    ) -> Result<Vec<DrugInteraction>, Box<dyn std::error::Error>> {
        let mut interactions = Vec::new();

        // Check each pair of drugs
        for i in 0..drugs.len() {
            for j in (i + 1)..drugs.len() {
                if let Some(interaction) = self.check_pair(&drugs[i], &drugs[j]).await {
                    interactions.push(interaction);
                }
            }
        }

        Ok(interactions)
    }

    /// Check for interaction between a specific pair of drugs
    async fn check_pair(&self, drug1: &str, drug2: &str) -> Option<DrugInteraction> {
        // For MVP, use a hardcoded database of known interactions
        // In production, you would:
        // 1. Query OpenFDA drug event endpoint
        // 2. Use a professional interaction database
        // 3. Integrate with user-provided data

        let pair = format!("{}+{}", drug1.to_lowercase(), drug2.to_lowercase());

        // Known severe interactions (for demonstration)
        let known_interactions = vec![
            (
                "warfarin+aspirin",
                InteractionSeverity::Severe,
                "Increased risk of bleeding",
            ),
            (
                "warfarin+ibuprofen",
                InteractionSeverity::Severe,
                "Increased risk of bleeding",
            ),
            (
                "acetaminophen+alcohol",
                InteractionSeverity::Severe,
                "Increased risk of liver damage",
            ),
            (
                "ssri+maoi",
                InteractionSeverity::Severe,
                "Serotonin syndrome risk",
            ),
            (
                "digoxin+verapamil",
                InteractionSeverity::Moderate,
                "Increased digoxin levels",
            ),
            (
                "acei+arb",
                InteractionSeverity::Moderate,
                "Increased risk of hyperkalemia",
            ),
        ];

        for (known_pair, severity, desc) in known_interactions {
            if pair.contains(known_pair) || known_pair.contains(&pair) {
                return Some(DrugInteraction {
                    drug1: drug1.to_string(),
                    drug2: drug2.to_string(),
                    severity: severity.clone(),
                    description: desc.to_string(),
                });
            }
        }

        None
    }

    /// Query OpenFDA for drug event reports
    async fn query_drug_events(
        &self,
        drug_name: &str,
    ) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
        let query = format!(
            "{}?search=patient.drug.medicinalproduct:{}&limit=10",
            self.base_url, drug_name
        );

        let response = self
            .client
            .get(&query)
            .send()
            .await?
            .json::<serde_json::Value>()
            .await?;

        Ok(response)
    }
}

impl Default for OpenFDAService {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_check_warfarin_aspirin() {
        let service = OpenFDAService::new();
        let interactions = service
            .check_interactions(&["warfarin".to_string(), "aspirin".to_string()])
            .await
            .unwrap();

        assert!(!interactions.is_empty());
        assert_eq!(interactions[0].severity, InteractionSeverity::Severe);
    }
}
