use serde::{Deserialize, Serialize};

use crate::{TDataT, TIlosci, TKodyKrajowUE, TKwotowy, TNumerKSeF, TTypKorekty, TZnakowy};

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

/// Dane faktury korygowanej (DaneFaKorygowanej).
///
/// Dane faktury korygowanej. maxOccurs="50000".
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DaneFaKorygowanej {
    /// Data wystawienia faktury korygowanej (DataWystFaKorygowanej).
    pub data_wyst_fa_korygowanej: TDataT,
    /// Numer faktury korygowanej (NrFaKorygowanej).
    pub nr_fa_korygowanej: TZnakowy,
    /// Znacznik numeru KSeF faktury korygowanej (NrKSeF).
    ///
    /// Znacznik numeru KSeF faktury korygowanej. TWybor1.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nr_ksef: Option<TNumerKSeF>,
    /// Numer identyfikujący fakturę korygowaną w KSeF (NrKSeFFaKorygowanej).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nr_ksef_fa_korygowanej: Option<TNumerKSeF>,
    /// Znacznik faktury korygowanej wystawionej poza KSeF (NrKSeFN).
    ///
    /// Znacznik faktury korygowanej wystawionej poza KSeF. TWybor1.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nr_ksef_n: Option<TNumerKSeF>,
}

/// Okres faktury korygowanej (OkresFaKorygowanej).
///
/// Dla faktury korygującej, o której mowa w art. 106j ust. 3 ustawy -
/// okres, do którego odnosi się udzielany opust lub udzielana obniżka,
/// w przypadku gdy podatnik udziela opustu lub obniżki ceny w odniesieniu
/// do dostaw towarów lub usług dokonanych lub świadczonych na rzecz
/// jednego odbiorcy w danym okresie.
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OkresFaKorygowanej {
    /// Data początkowa okresu korygowanego (P_6_OdKor).
    pub p_6_od_kor: TDataT,
    /// Data końcowa okresu korygowanego (P_6_DoKor).
    pub p_6_do_kor: TDataT,
}

/// Dane sprzedawcy na fakturze korygowanej (Podmiot1K).
///
/// W przypadku korekty danych sprzedawcy należy podać pełne dane sprzedawcy
/// występujące na fakturze korygowanej. Pole nie dotyczy przypadku korekty
/// błędnego NIP występującego na fakturze pierwotnej - wówczas wymagana jest
/// korekta faktury do wartości zerowych. minOccurs="0".
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Podmiot1K {
    /// Kod (prefiks) podatnika VAT UE (PrefiksPodatnika).
    ///
    /// Kod (prefiks) podatnika VAT UE dla przypadków określonych w art. 97
    /// ust. 10 pkt 2 i 3 ustawy oraz w przypadku, o którym mowa w art. 136
    /// ust. 1 pkt 3 ustawy. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub prefiks_podatnika: Option<TKodyKrajowUE>,
    /// Dane identyfikujące podatnika (DaneIdentyfikacyjne).
    ///
    /// Typ TPodmiot1.
    pub dane_identyfikacyjne: DaneIdentyfikacyjnePodmiot1,
    /// Adres podatnika (Adres).
    ///
    /// Typ TAdres.
    pub adres: TAdres,
}

/// Dane nabywcy na fakturze korygowanej (Podmiot2K).
///
/// W przypadku korekty danych nabywcy występującego jako Podmiot2 lub dodatkowego
/// nabywcy występującego jako Podmiot3 należy podać pełne dane tego podmiotu
/// występujące na fakturze korygowanej. Korekcie nie podlegają błędne numery NIP.
/// minOccurs="0", maxOccurs="101".
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Podmiot2K {
    /// Dane identyfikujące nabywcę (DaneIdentyfikacyjne).
    ///
    /// Typ TPodmiot2.
    pub dane_identyfikacyjne: DaneIdentyfikacyjnePodmiot2,
    /// Adres nabywcy (Adres).
    ///
    /// Adres nabywcy. Pola opcjonalne dla przypadków określonych
    /// w art. 106e ust. 5 pkt 3 ustawy. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub adres: Option<TAdres>,
    /// Unikalny klucz powiązania danych nabywcy (IDNabywcy).
    ///
    /// Unikalny klucz powiązania danych nabywcy na fakturach korygujących,
    /// w przypadku gdy dane nabywcy na fakturze korygującej zmieniły się
    /// w stosunku do danych na fakturze korygowanej. minOccurs="0". maxLength="32".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id_nabywcy: Option<TZnakowy>,
}

/// Zagregowane dane korekty na fakturze (CorrectionData).
///
/// Dane dla przypadków, gdy pole RodzajFaktury przyjmuje wartości
/// KOR, KOR_ZAL lub KOR_ROZ.
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CorrectionData {
    /// Przyczyna korekty (PrzyczynaKorekty).
    ///
    /// Przyczyna korekty dla faktur korygujących. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub przyczyna_korekty: Option<TZnakowy>,
    /// Typ korekty (TypKorekty).
    ///
    /// Typ skutku korekty w ewidencji dla podatku od towarów i usług.
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub typ_korekty: Option<TTypKorekty>,
    /// Dane faktur korygowanych (DaneFaKorygowanej).
    ///
    /// maxOccurs="50000".
    pub dane_fa_korygowanej: Vec<DaneFaKorygowanej>,
    /// Okres faktury korygowanej (OkresFaKorygowanej).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub okres_fa_korygowanej: Option<OkresFaKorygowanej>,
    /// Poprawny numer faktury korygowanej (NrFaKorygowany).
    ///
    /// Poprawny numer faktury korygowanej w przypadku, gdy przyczyną korekty
    /// jest błędny numer faktury korygowanej. W takim przypadku błędny numer
    /// faktury należy wskazać w polu NrFaKorygowanej. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nr_fa_korygowany: Option<TZnakowy>,
    /// Dane sprzedawcy na fakturze korygowanej (Podmiot1K).
    ///
    /// minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub podmiot1k: Option<Podmiot1K>,
    /// Dane nabywcy na fakturze korygowanej (Podmiot2K).
    ///
    /// minOccurs="0", maxOccurs="101".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub podmiot2k: Option<Vec<Podmiot2K>>,
    /// Kwota zapłaty przed korektą (P_15ZK).
    ///
    /// W przypadku korekt faktur zaliczkowych - kwota zapłaty przed korektą.
    /// W przypadku korekt faktur, o których mowa w art. 106f ust. 3 ustawy -
    /// kwota pozostała do zapłaty przed korektą. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub p_15zk: Option<TKwotowy>,
    /// Kurs waluty przed korektą (KursWalutyZK).
    ///
    /// Kurs waluty stosowany do wyliczenia kwoty podatku w przypadkach,
    /// o których mowa w dziale VI ustawy przed korektą. minOccurs="0".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub kurs_waluty_zk: Option<TIlosci>,
}
