use chrono::NaiveDateTime;
use hyper::HeaderMap;
use schedulelib::remote::public_schedule_remote::{get_public_class_schedule};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::dto::content_group_response::ContentGroupResponse;
use crate::dto::device_response::DeviceResponse;
use crate::dto::notice_schedule_response::NoticeScheduleResponse;
use crate::enums::content_type::ContentType;
use crate::jsonb::content_item::ContentItem;
use crate::jsonb::content_item_details::ContentItemDetails;
use crate::jsonb::zone::Zone;
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CheckChangeResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub zones: Option<Vec<Zones>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub orientation: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Zones {
#[serde(skip_serializing_if = "Option::is_none")]
pub zone_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub related_schedule: Option<Vec<Schedules>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub z_index: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub width: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub height: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub x_offset: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub y_offset: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub opacity: Option<String>,
}
impl Zones {
pub fn to_zone(&self) -> Zone {
let mut schedules = vec![];
for schedule in self.clone().related_schedule.unwrap().iter() {
schedules.push(schedule.schedule_id.clone().unwrap())
}
Zone {
id: self.zone_id.clone(),
related_schedule: Option::from(schedules),
z_index: self.z_index.clone(),
width: self.width.clone(),
height: self.height.clone(),
x_offset: self.x_offset.clone(),
y_offset: self.y_offset.clone(),
opacity: self.opacity.clone(),
}
}
pub fn to_vec_zone(zones: Vec<Zones>) -> Vec<Zone> {
let mut _zone = vec![];
for zone in zones.iter() {
_zone.push(zone.to_zone())
}
_zone
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Schedules {
#[serde(skip_serializing_if = "Option::is_none")]
pub schedule_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub start_date: Option<NaiveDateTime>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_date: Option<NaiveDateTime>,
#[serde(skip_serializing_if = "Option::is_none")]
pub items: Option<Vec<Items>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub organization: Option<Uuid>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Items {
#[serde(skip_serializing_if = "Option::is_none")]
pub item_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub item_type: Option<ContentType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub details: Option<ContentItemDetails>,
#[serde(skip_serializing_if = "Option::is_none")]
pub duration: Option<i32>,
pub stretch_content: bool,
}
impl Items {
pub fn from_content_item(content_item: ContentItem) -> Items {
Items {
item_id: content_item.id.clone(),
name: content_item.name.clone(),
url: content_item.url.clone(),
item_type: content_item.item_type.clone(),
duration: content_item.duration.clone(),
details: match content_item.details {
Some(ci) => Some(ci),
None => None,
},
stretch_content: match content_item.stretch_content {
Some(sc) => sc,
None => false,
},
}
}
pub fn from_content_item_list(content_items: Vec<ContentItem>) -> Vec<Items> {
let mut items: Vec<Items> = vec![];
for ci in content_items.iter() {
items.push(Items::from_content_item(ci.clone()))
}
items
}
}
impl CheckChangeResponse {
pub fn build_response(
device: DeviceResponse,
schedules: Option<Vec<NoticeScheduleResponse>>,
content_groups: Option<Vec<ContentGroupResponse>>,
) -> CheckChangeResponse {
let mut device_zones = vec![];
if device.clone().zones.is_some() {
for zone in device.clone().zones.unwrap().iter() {
let mut related_schedules = vec![];
if zone.clone().related_schedule.is_some() {
for schedule_id in zone.clone().related_schedule.unwrap().iter() {
for schedule in schedules.clone().unwrap().iter() {
let mut real_schedule = Schedules {
schedule_id: None,
priority: None,
start_date: None,
end_date: None,
items: None,
organization: None,
};
if *schedule_id == schedule.id {
let mut content_items = vec![];
let content_group_ids = schedule.content_group_ids.clone().unwrap();
for content_group_id in content_group_ids.iter() {
for content_group in content_groups.clone().unwrap().iter() {
if content_group_id.id.unwrap() == content_group.id {
content_items =
content_group.clone().content_items.unwrap().clone()
}
let mut items = content_items.clone();
for i in 0..items.len() {
if items[i].item_type.is_some() &&
items[i].clone().item_type.unwrap() == ContentType::Timetable &&
items[i].details.is_some() {
let schedule = get_public_class_schedule(
HeaderMap::new(),
items[i].clone().details.unwrap().class_id.unwrap()
);
if schedule.is_ok() {
let old_details = content_items[0].clone().details.unwrap();
let new_details = ContentItemDetails{
id: old_details.id.clone(),
class_id: old_details.class_id.clone(),
academic_year: old_details.academic_year.clone(),
schedule: old_details.schedule.clone(),
timetable: Some(schedule.unwrap()),
};
let old_item = content_items[0].clone();
let new_item = ContentItem{
id: old_item.id.clone(),
name: old_item.name.clone(),
item_type: old_item.item_type.clone(),
url: old_item.url.clone(),
details: Some(new_details),
comment: old_item.comment.clone(),
stretch_content: old_item.stretch_content.clone(),
duration: old_item.duration.clone(),
order: old_item.order.clone(),
};
items[i] = new_item;
}
}
}
content_items = items.clone();
}
}
real_schedule = Schedules {
schedule_id: Option::from(schedule.id.clone()),
priority: schedule.priority.clone(),
start_date: schedule.start_date.clone(),
end_date: schedule.end_date.clone(),
items: Option::from(Items::from_content_item_list(
content_items.clone(),
)),
organization: Option::from(schedule.organization.clone()),
}
}
related_schedules.push(real_schedule)
}
}
}
device_zones.push(Zones {
zone_id: zone.id.clone(),
related_schedule: Option::from(related_schedules),
z_index: zone.z_index.clone(),
width: zone.width.clone(),
height: zone.height.clone(),
x_offset: zone.x_offset.clone(),
y_offset: zone.y_offset.clone(),
opacity: zone.opacity.clone(),
})
}
}
CheckChangeResponse {
id: Option::from(device.id.clone()),
zones: Option::from(device_zones),
orientation: device.orientation.clone(),
}
}
}