use serde::{Deserialize, Serialize};

use crate::{TDataT, TIlosci, TKodWaluty, TRodzajTransportu, TZnakowy};

use super::common::{DaneIdentyfikacyjnePodmiot2, TAdres};

/// Umowa (Umowy).
///
/// Dane umowy w ramach warunków transakcji. maxOccurs="100".
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Umowa {
    /// Data umowy (DataUmowy).
    ///
    /// TDataU. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub data_umowy: Option<TDataT>,
    /// Numer umowy (NrUmowy).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nr_umowy: Option<TZnakowy>,
}

/// Zamówienie (Zamowienia).
///
/// Dane zamówienia w ramach warunków transakcji. maxOccurs="100".
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Zamowienie {
    /// Data zamówienia (DataZamowienia).
    ///
    /// TDataU. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub data_zamowienia: Option<TDataT>,
    /// Numer zamówienia (NrZamowienia).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nr_zamowienia: Option<TZnakowy>,
}

/// Przewoźnik (Przewoznik).
///
/// Dane identyfikacyjne i adresowe przewoźnika.
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Przewoznik {
    /// Dane identyfikacyjne przewoźnika (DaneIdentyfikacyjne).
    ///
    /// Typ TPodmiot2.
    pub dane_identyfikacyjne: DaneIdentyfikacyjnePodmiot2,
    /// Adres przewoźnika (AdresPrzewoznika).
    ///
    /// Typ TAdres.
    pub adres_przewoznika: TAdres,
}

/// Transport (Transport).
///
/// Dane transportu w ramach warunków transakcji. maxOccurs="20".
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Transport {
    /// Rodzaj transportu (RodzajTransportu).
    ///
    /// Rodzaj zastosowanego transportu w przypadku dokonanej dostawy towarów.
    /// TRodzajTransportu. minOccurs="0" (choice z TransportInny).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub rodzaj_transportu: Option<TRodzajTransportu>,
    /// Znacznik innego rodzaju transportu (TransportInny).
    ///
    /// Znacznik innego rodzaju transportu: 1 - inny rodzaj transportu.
    /// TWybor1. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub transport_inny: Option<u8>,
    /// Opis innego rodzaju transportu (OpisInnegoTransportu).
    ///
    /// TZnakowy50. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub opis_innego_transportu: Option<TZnakowy>,
    /// Dane przewoźnika (Przewoznik).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub przewoznik: Option<Przewoznik>,
    /// Numer zlecenia transportu (NrZleceniaTransportu).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nr_zlecenia_transportu: Option<TZnakowy>,
    /// Rodzaj ładunku (OpisLadunku).
    ///
    /// TLadunek. Alternatywa z LadunekInny. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub opis_ladunku: Option<TZnakowy>,
    /// Znacznik innego ładunku (LadunekInny).
    ///
    /// Znacznik innego ładunku: 1 - inny ładunek. TWybor1. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub ladunek_inny: Option<u8>,
    /// Opis innego ładunku (OpisInnegoLadunku).
    ///
    /// Opis innego ładunku, w tym ładunek mieszany. TZnakowy50. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub opis_innego_ladunku: Option<TZnakowy>,
    /// Jednostka opakowania (JednostkaOpakowania).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub jednostka_opakowania: Option<TZnakowy>,
    /// Data i godzina rozpoczęcia transportu (DataGodzRozpTransportu).
    ///
    /// TDataCzas. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub data_godz_rozp_transportu: Option<TDataT>,
    /// Data i godzina zakończenia transportu (DataGodzZakTransportu).
    ///
    /// TDataCzas. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub data_godz_zak_transportu: Option<TDataT>,
    /// Adres miejsca wysyłki (WysylkaZ).
    ///
    /// TAdres. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub wysylka_z: Option<TAdres>,
    /// Adresy pośrednie wysyłki (WysylkaPrzez).
    ///
    /// TAdres. minOccurs="0", maxOccurs="20".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub wysylka_przez: Option<Vec<TAdres>>,
    /// Adres miejsca docelowego (WysylkaDo).
    ///
    /// Adres miejsca docelowego, do którego został zlecony transport.
    /// TAdres. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub wysylka_do: Option<TAdres>,
}

/// Warunki transakcji (WarunkiTransakcji).
///
/// Sekcja Fa/WarunkiTransakcji. Warunki transakcji, o ile występują.
/// minOccurs="0".
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WarunkiTransakcji {
    /// Umowy (Umowy).
    ///
    /// maxOccurs="100". minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub umowy: Option<Vec<Umowa>>,
    /// Zamówienia (Zamowienia).
    ///
    /// maxOccurs="100". minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub zamowienia: Option<Vec<Zamowienie>>,
    /// Numery partii towaru (NrPartiiTowaru).
    ///
    /// maxOccurs="1000". minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nr_partii_towaru: Option<Vec<TZnakowy>>,
    /// Warunki dostawy (WarunkiDostawy).
    ///
    /// Warunki dostawy towarów - w przypadku istnienia pomiędzy stronami transakcji,
    /// umowy określającej warunki dostawy tzw. Incoterms. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub warunki_dostawy: Option<TZnakowy>,
    /// Kurs umowny (KursUmowny).
    ///
    /// Kurs umowny - w przypadkach, gdy na fakturze znajduje się informacja o kursie,
    /// po którym zostały przeliczone kwoty wykazane na fakturze w złotych.
    /// Nie dotyczy przypadków, o których mowa w dziale VI ustawy.
    /// TIlosci. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub kurs_umowny: Option<TIlosci>,
    /// Waluta umowna (WalutaUmowna).
    ///
    /// Kod waluty (ISO-4217) w przypadkach gdy na fakturze znajduje się informacja
    /// o kursie. Nie dotyczy przypadków, o których mowa w dziale VI ustawy.
    /// TKodWaluty. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub waluta_umowna: Option<TKodWaluty>,
    /// Dane transportu (Transport).
    ///
    /// maxOccurs="20". minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub transport: Option<Vec<Transport>>,
    /// Podmiot pośredniczący (PodmiotPosredniczacy).
    ///
    /// Wartość "1" oznacza dostawę dokonaną przez podmiot, o którym mowa
    /// w art. 22 ust. 2d ustawy. Dotyczy transakcji łańcuchowej innej niż
    /// procedura trójstronna uproszczona (art. 135 ust. 1 pkt 4 ustawy).
    /// TWybor1. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub podmiot_posredniczacy: Option<u8>,
}
