// SPDX-FileCopyrightText: Politik im Blick developers
// SPDX-FileCopyrightText: Wolfgang Silbermayr <wolfgang@silbermayr.at>
//
// SPDX-License-Identifier: AGPL-3.0-or-later OR EUPL-1.2

use oparl_types::{Date, Name, OrganizationClassification, Url};
use pib_oparl_extensions::Color;
use pib_service_core_types::{BodyId, Entity, OrganizationId};
use serde::{Deserialize, Serialize};

use crate::Updatable;

pub mod get;
pub mod post;

pub mod by_id;

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Organization {
    pub name: Name,
    pub short_name: Option<Name>,
    pub classification: Option<OrganizationClassification>,
    pub start_date: Option<Date>,
    pub end_date: Option<Date>,
    pub website: Option<Url>,
    pub color: Option<Color>,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
pub struct OrganizationParentId {
    pub body_id: BodyId,
}

impl Entity<OrganizationParentId, OrganizationId> for Organization {}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct UpdateOrganization {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<Name>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub short_name: Option<Option<Name>>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub classification: Option<Option<OrganizationClassification>>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub start_date: Option<Option<Date>>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub end_date: Option<Option<Date>>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub website: Option<Option<Url>>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub color: Option<Option<Color>>,
}

impl Updatable for Organization {
    type Update = UpdateOrganization;

    fn build_update_from(
        &self,
        Self {
            name,
            short_name,
            classification,
            start_date,
            end_date,
            website,
            color,
        }: &Self,
    ) -> Self::Update {
        let name = self.name.build_update_from(name);
        let short_name = self.short_name.build_update_from(short_name);
        let classification = self.classification.build_update_from(classification);
        let start_date = self.start_date.build_update_from(start_date);
        let end_date = self.end_date.build_update_from(end_date);
        let website = self.website.build_update_from(website);
        let color = self.color.build_update_from(color);

        Self::Update {
            name,
            short_name,
            classification,
            start_date,
            end_date,
            website,
            color,
        }
    }
}
