use std::path::PathBuf;

#[derive(Debug, Clone)]
pub struct AttachmentMetadata {
    pub attribution_info: Option<AttributionInfo>,
}

#[derive(Debug, Clone)]
pub struct AttributionInfo {
    pub width: Option<u32>,
    pub height: Option<u32>,
}

#[derive(Debug, Clone)]
pub struct Attachment {
    pub guid: String,
    pub base_path: PathBuf,
    pub metadata: Option<AttachmentMetadata>,
}

impl Attachment {
    pub fn get_path(&self) -> PathBuf {
        self.get_path_for_preview_scratch(false, false)
    }

    pub fn get_path_for_preview(&self, preview: bool) -> PathBuf {
        self.get_path_for_preview_scratch(preview, false)
    }

    pub fn get_path_for_preview_scratch(&self, preview: bool, scratch: bool) -> PathBuf {
        let extension = if preview { "preview" } else { "full" };
        if scratch {
            self.base_path
                .with_extension(format!("{}.download", extension))
        } else {
            self.base_path.with_extension(extension)
        }
    }

    pub fn is_downloaded(&self, preview: bool) -> bool {
        std::fs::exists(&self.get_path_for_preview(preview)).expect(
            format!(
                "Wasn't able to check for the existence of an attachment file path at {}",
                &self.get_path_for_preview(preview).display()
            )
            .as_str(),
        )
    }
}

impl From<kordophone::model::message::AttachmentMetadata> for AttachmentMetadata {
    fn from(metadata: kordophone::model::message::AttachmentMetadata) -> Self {
        Self {
            attribution_info: metadata.attribution_info.map(|info| info.into()),
        }
    }
}

impl From<kordophone::model::message::AttributionInfo> for AttributionInfo {
    fn from(info: kordophone::model::message::AttributionInfo) -> Self {
        Self {
            width: info.width,
            height: info.height,
        }
    }
}

impl From<AttachmentMetadata> for kordophone::model::message::AttachmentMetadata {
    fn from(metadata: AttachmentMetadata) -> Self {
        Self {
            attribution_info: metadata.attribution_info.map(|info| info.into()),
        }
    }
}

impl From<AttributionInfo> for kordophone::model::message::AttributionInfo {
    fn from(info: AttributionInfo) -> Self {
        Self {
            width: info.width,
            height: info.height,
        }
    }
}
