use serde::{Deserialize, Serialize};

/// Field-level filters applied to an invoice export.
///
/// Default (`ExportFilters::default()`) is the "no extra filters" value and
/// is the serde default during deserialization, so omitting any/all fields
/// on the wire is safe. Wire shape is camelCase.
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct ExportFilters {
    pub invoice_kinds: Vec<String>,
    pub annotation_split_payment: Option<bool>,
    pub annotation_reverse_charge: Option<bool>,
    pub annotation_self_billing: Option<bool>,
    pub annotation_cash_method: Option<bool>,
    pub counterparty_nip: Option<String>,
    pub gross_amount_min: Option<f64>,
    pub gross_amount_max: Option<f64>,
    pub currency: Option<String>,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn empty_object_deserialises_to_default() {
        let f: ExportFilters = serde_json::from_str("{}").unwrap();
        assert_eq!(f, ExportFilters::default());
    }

    #[test]
    fn camel_case_round_trip() {
        let f = ExportFilters {
            invoice_kinds: vec!["KOR".into(), "KOR_ZAL".into()],
            annotation_self_billing: Some(true),
            counterparty_nip: Some("5252345678".into()),
            gross_amount_min: Some(100.0),
            gross_amount_max: Some(5000.0),
            currency: Some("EUR".into()),
            ..Default::default()
        };
        let s = serde_json::to_string(&f).unwrap();
        assert!(s.contains(r#""invoiceKinds":["KOR","KOR_ZAL"]"#));
        assert!(s.contains(r#""annotationSelfBilling":true"#));
        assert!(s.contains(r#""counterpartyNip":"5252345678""#));
        assert!(s.contains(r#""grossAmountMin":100.0"#));
        assert!(s.contains(r#""grossAmountMax":5000.0"#));
        assert!(s.contains(r#""currency":"EUR""#));
        let back: ExportFilters = serde_json::from_str(&s).unwrap();
        assert_eq!(back, f);
    }

    #[test]
    fn unknown_fields_are_tolerated() {
        let raw = r#"{"invoiceKinds":[],"unknown":"value"}"#;
        let _f: ExportFilters = serde_json::from_str(raw).unwrap();
    }
}
