use serde::{Deserialize, Serialize};

use crate::{
    SWIFTType, TDataT, TFormaPlatnosci, TKwotowy, TNaturalny, TNrRB, TRachunekWlasnyBanku,
    TZnakowy, TZnakowy512,
};

/// Informacje o rachunku bankowym (TRachunekBankowy).
///
/// Informacje o rachunku.
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BankAccountInfo {
    /// Pełny numer rachunku (NrRB).
    pub nr_rb: TNrRB,
    /// Kod SWIFT (SWIFT).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub swift: Option<SWIFTType>,
    /// Rachunek własny banku (RachunekWlasnyBanku).
    ///
    /// minOccurs="0". TRachunekWlasnyBanku.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub rachunek_wlasny_banku: Option<TRachunekWlasnyBanku>,
    /// Nazwa banku (NazwaBanku).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nazwa_banku: Option<TZnakowy>,
    /// Opis rachunku (OpisRachunku).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub opis_rachunku: Option<TZnakowy>,
}

/// Dane zapłaty częściowej (ZaplataCzesciowa).
///
/// Dane zapłat częściowych. maxOccurs="100".
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ZaplataCzesciowa {
    /// Kwota zapłaty częściowej (KwotaZaplatyCzesciowej).
    pub kwota_zaplaty_czesciowej: TKwotowy,
    /// Data zapłaty częściowej (DataZaplatyCzesciowej).
    ///
    /// Data zapłaty częściowej, jeśli do wystawienia faktury płatność
    /// częściowa została dokonana.
    pub data_zaplaty_czesciowej: TDataT,
    /// Forma płatności (FormaPlatnosci).
    ///
    /// TFormaPlatnosci. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub forma_platnosci: Option<TFormaPlatnosci>,
    /// Znacznik innej formy płatności (PlatnoscInna).
    ///
    /// Znacznik innej formy płatności: 1 - inna forma płatności.
    /// TWybor1. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub platnosc_inna: Option<u8>,
    /// Uszczegółowienie innej formy płatności (OpisPlatnosci).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub opis_platnosci: Option<TZnakowy>,
}

/// Opis terminu płatności (TerminOpis).
///
/// Opis terminu płatności w postaci: ilość + jednostka + zdarzenie początkowe.
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TerminOpis {
    /// Ilość jednostek czasu (Ilosc).
    pub ilosc: TNaturalny,
    /// Jednostka czasu (Jednostka).
    ///
    /// TZnakowy50.
    pub jednostka: TZnakowy,
    /// Zdarzenie początkowe (ZdarzeniePoczatkowe).
    pub zdarzenie_poczatkowe: TZnakowy,
}

/// Termin płatności (TerminPlatnosci).
///
/// maxOccurs="100".
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TerminPlatnosci {
    /// Termin płatności (Termin).
    ///
    /// Data terminu płatności. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub termin: Option<TDataT>,
    /// Opis terminu płatności (TerminOpis).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub termin_opis: Option<TerminOpis>,
}

/// Skonto (Skonto).
///
/// Informacje o skoncie na fakturze.
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Skonto {
    /// Warunki skonta (WarunkiSkonta).
    ///
    /// Warunki, które nabywca powinien spełnić, aby skorzystać ze skonta.
    pub warunki_skonta: TZnakowy,
    /// Wysokość skonta (WysokoscSkonta).
    pub wysokosc_skonta: TKwotowy,
}

/// Warunki płatności (Platnosc).
///
/// Sekcja Fa/Platnosc. minOccurs="0".
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Platnosc {
    /// Znacznik zapłaty (Zaplacono).
    ///
    /// Znacznik informujący, że należność wynikająca z faktury została zapłacona:
    /// 1 - zapłacono. TWybor1. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub zaplacono: Option<u8>,
    /// Data zapłaty (DataZaplaty).
    ///
    /// Data zapłaty, jeśli do wystawienia faktury płatność została dokonana.
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub data_zaplaty: Option<TDataT>,
    /// Znacznik zapłaty częściowej (ZnacznikZaplatyCzesciowej).
    ///
    /// 1 - zapłacono w części; 2 - zapłacono w całości (jeśli należność zapłacona
    /// w dwóch lub więcej częściach, a ostatnia płatność jest końcowa).
    /// TWybor1_2. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub znacznik_zaplaty_czesciowej: Option<u8>,
    /// Dane zapłat częściowych (ZaplataCzesciowa).
    ///
    /// maxOccurs="100".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub zaplata_czesciowa: Option<Vec<ZaplataCzesciowa>>,
    /// Terminy płatności (TerminPlatnosci).
    ///
    /// maxOccurs="100".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub termin_platnosci: Option<Vec<TerminPlatnosci>>,
    /// Forma płatności (FormaPlatnosci).
    ///
    /// TFormaPlatnosci. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub forma_platnosci: Option<TFormaPlatnosci>,
    /// Znacznik innej formy płatności (PlatnoscInna).
    ///
    /// Znacznik innej formy płatności: 1 - inna forma płatności.
    /// TWybor1. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub platnosc_inna: Option<u8>,
    /// Uszczegółowienie innej formy płatności (OpisPlatnosci).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub opis_platnosci: Option<TZnakowy>,
    /// Numery rachunków bankowych (RachunekBankowy).
    ///
    /// TRachunekBankowy. minOccurs="0", maxOccurs="100".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub rachunek_bankowy: Option<Vec<BankAccountInfo>>,
    /// Rachunki bankowe faktora (RachunekBankowyFaktora).
    ///
    /// TRachunekBankowy. minOccurs="0", maxOccurs="20".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub rachunek_bankowy_faktora: Option<Vec<BankAccountInfo>>,
    /// Skonto (Skonto).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub skonto: Option<Skonto>,
    /// Link do płatności bezgotówkowej (LinkDoPlatnosci).
    ///
    /// TZnakowy512 z wymaganiem parametru IPKSeF w URL. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub link_do_platnosci: Option<TZnakowy512>,
    /// Identyfikator płatności Krajowego Systemu e-Faktur (IPKSeF).
    ///
    /// Pattern: `[0-9]{3}[a-zA-Z0-9]{10}`. maxLength="13". minOccurs="0".
    #[serde(rename = "ipKSeF", skip_serializing_if = "Option::is_none")]
    pub ip_ksef: Option<u8>,
}
