use crate::nats_types::PublishFixRequest;

#[allow(dead_code)]
#[derive(Debug)]
pub enum PublishError{
	Get(rbx_asset::cookie::GetError),
	Json(serde_json::Error),
	Upload(rbx_asset::cookie::UploadError),
	ApiActionSubmissionUploaded(submissions_api::Error),
}
impl std::fmt::Display for PublishError{
	fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
		write!(f,"{self:?}")
	}
}
impl std::error::Error for PublishError{}

pub struct Publisher{
	roblox_cookie:rbx_asset::cookie::CookieContext,
	group_id:Option<u64>,
	api_internal:submissions_api::internal::Context,
}
impl Publisher{
	pub const fn new(
		roblox_cookie:rbx_asset::cookie::CookieContext,
		group_id:Option<u64>,
		api_internal:submissions_api::internal::Context,
	)->Self{
		Self{
			roblox_cookie,
			group_id,
			api_internal,
		}
	}
	pub async fn publish(&self,publish_info:PublishFixRequest)->Result<(),PublishError>{
		// download the map model version
		let model_data=self.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
			asset_id:publish_info.ModelID,
			version:Some(publish_info.ModelVersion),
		}).await.map_err(PublishError::Get)?;

		// upload the map to the strafesnet group
		let _upload_response=self.roblox_cookie.upload(rbx_asset::cookie::UploadRequest{
			assetid:publish_info.TargetAssetID,
			groupId:self.group_id,
			name:None,
			description:None,
			ispublic:None,
			allowComments:None,
		},model_data).await.map_err(PublishError::Upload)?;

		// that's it, the database entry does not need to be changed.

		// mark submission as uploaded, TargetAssetID is unchanged
		self.api_internal.action_submission_uploaded(submissions_api::types::ActionSubmissionUploadedRequest{
			SubmissionID:publish_info.SubmissionID,
			TargetAssetID:None,
		}).await.map_err(PublishError::ApiActionSubmissionUploaded)?;

		Ok(())
	}
}