use crate::db::model_utils::Period;
use diesel::sql_types::Binary;
use serde::{Deserialize, Serialize};

use super::schema::*;
use crate::types::EmgauwaUid;

#[derive(Debug, Serialize, Identifiable, Queryable)]
pub struct Relay {
    #[serde(skip)]
    pub id: i32,
    // TODO
}

#[derive(Debug, Serialize, Identifiable, Queryable, Clone)]
pub struct Schedule {
    #[serde(skip)]
    pub id: i32,
    #[serde(rename(serialize = "id"))]
    pub uid: EmgauwaUid,
    pub name: String,
    pub periods: Periods,
}

#[derive(Insertable)]
#[table_name = "schedules"]
pub struct NewSchedule<'a> {
    pub uid: &'a EmgauwaUid,
    pub name: &'a str,
    pub periods: &'a Periods,
}

#[derive(Debug, Serialize, Deserialize, AsExpression, FromSqlRow, PartialEq, Clone)]
#[sql_type = "Binary"]
pub struct Periods(pub(crate) Vec<Period>);

#[derive(Debug, Serialize, Identifiable, Queryable, Clone)]
pub struct Tag {
    pub id: i32,
    pub tag: String,
}

#[derive(Insertable)]
#[table_name = "tags"]
pub struct NewTag<'a> {
    pub tag: &'a str,
}

#[derive(Queryable, Associations, Identifiable)]
#[belongs_to(Relay)]
#[belongs_to(Schedule)]
#[belongs_to(Tag)]
#[table_name = "junction_tag"]
pub struct JunctionTag {
    pub id: i32,
    pub tag_id: i32,
    pub relay_id: Option<i32>,
    pub schedule_id: Option<i32>,
}

#[derive(Insertable)]
#[table_name = "junction_tag"]
pub struct NewJunctionTag {
    pub tag_id: i32,
    pub relay_id: Option<i32>,
    pub schedule_id: Option<i32>,
}