use crate::{Packed, Required};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use ts_rs::TS;

use crate::types::user::PackUserBase;

use magnetar_sdk_macros::pack;

use crate::types::Id;

#[derive(Clone, Debug, Default, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct ImageMeta {
    pub width: Option<usize>,
    pub height: Option<usize>,
    pub orientation: Option<usize>,
    pub color: Option<String>,
}

#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct DriveFolderBase {
    pub name: String,
    pub created_at: DateTime<Utc>,
    pub comment: Option<String>,
    pub file_count: usize,
    pub folder_count: usize,
    pub parent_id: Option<String>,
    pub user_id: String,
}

pack!(PackDriveFolderBase, Required<Id> as id & Required<DriveFolderBase> as folder);

#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct DriveFolderParentExt {
    pub folder: Box<DriveFolderBase>,
}

pack!(
    PackDriveFolderWithParent,
    Required<Id> as id & Required<DriveFolderBase> as folder & Required<DriveFolderParentExt> as parent
);

#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct DriveFileBase {
    pub name: String,
    pub created_at: DateTime<Utc>,
    pub size: usize,
    pub hash: Option<String>,
    pub mime_type: String,
    pub media_metadata: ImageMeta,
    pub url: Option<String>,
    pub source_url: String,
    pub thumbnail_url: Option<String>,
    pub blurhash: Option<String>,
    pub sensitive: bool,
    pub comment: Option<String>,
    pub folder_id: Option<String>,
    pub user_id: Option<String>,
}

pack!(PackDriveFileBase, Required<Id> as id & Required<DriveFileBase> as file);

#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct DriveFileFolderExt {
    pub folder: Box<PackDriveFolderBase>,
}

pack!(
    PackDriveFileWithFolder,
    Required<Id> as id & Required<DriveFileBase> as file & Required<DriveFileFolderExt> as folder
);

#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct DriveFileUserExt {
    pub user: Box<PackUserBase>,
}

pack!(
    PackDriveFileWithUser,
    Required<Id> as id & Required<DriveFileBase> as file & Required<DriveFileUserExt> as user
);

pack!(
    PackDriveFileFull,
    Required<Id> as id & Required<DriveFileBase> as file & Required<DriveFileFolderExt> as folder & Required<DriveFileUserExt> as user
);
