// 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::{EmailAddress, Name};
use pib_service_core_types::{BodyId, Entity, PersonId};
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 Person {
    pub name: Name,
    pub family_name: Option<Name>,
    pub given_name: Option<Name>,
    pub form_of_address: Option<String>,
    pub affix: Option<String>,
    pub title: Vec<String>,
    pub gender: Option<String>,
    pub phone: Vec<String>,
    pub email: Vec<EmailAddress>,
}

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

impl Entity<PersonParentId, PersonId> for Person {}

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

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

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

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

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

    #[serde(skip_serializing_if = "Option::is_none")]
    pub title: Option<Vec<String>>,

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

    #[serde(skip_serializing_if = "Option::is_none")]
    pub phone: Option<Vec<String>>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub email: Option<Vec<EmailAddress>>,
}

impl Updatable for Person {
    type Update = UpdatePerson;

    fn build_update_from(
        &self,
        Self {
            name,
            family_name,
            given_name,
            form_of_address,
            affix,
            title,
            gender,
            phone,
            email,
        }: &Self,
    ) -> Self::Update {
        let name = self.name.build_update_from(name);
        let family_name = self.family_name.build_update_from(family_name);
        let given_name = self.given_name.build_update_from(given_name);
        let form_of_address = self.form_of_address.build_update_from(form_of_address);
        let affix = self.affix.build_update_from(affix);
        let title = self.title.build_update_from(title);
        let gender = self.gender.build_update_from(gender);
        let phone = self.phone.build_update_from(phone);
        let email = self.email.build_update_from(email);

        Self::Update {
            name,
            family_name,
            given_name,
            form_of_address,
            affix,
            title,
            gender,
            phone,
            email,
        }
    }
}
