use payabli_api::prelude::*;

mod wire_test_utils;

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_add_pay_link_from_invoice_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client.payment_link.add_pay_link_from_invoice(23548884, &AddPayLinkFromInvoiceRequest {
        mail_2: Some("jo@example.com; ceo@example.com".to_string()),
        body: PaymentPageRequestBody {
        contact_us: Some(ContactElement {
        email_label: Some("Email".to_string()),
        enabled: Some(Enabled(true)),
        header: Some("Contact Us".to_string()),
        order: Some(Order(0)),
        payment_icons: Some(true),
        phone_label: Some("Phone".to_string()),
        ..Default::default()
        }),
        invoices: Some(InvoiceElement {
        enabled: Some(Enabled(true)),
        invoice_link: Some(LabelElement {
        enabled: Some(Enabled(true)),
        label: Some("View Invoice".to_string()),
        order: Some(Order(0)),
        ..Default::default()
        }),
        order: Some(Order(0)),
        view_invoice_details: Some(LabelElement {
        enabled: Some(Enabled(true)),
        label: Some("Invoice Details".to_string()),
        order: Some(Order(0)),
        ..Default::default()
        }),
        ..Default::default()
        }),
        logo: Some(Element {
        enabled: Some(Enabled(true)),
        order: Some(Order(0)),
        ..Default::default()
        }),
        message_before_paying: Some(LabelElement {
        enabled: Some(Enabled(true)),
        label: Some("Please review your payment details".to_string()),
        order: Some(Order(0)),
        ..Default::default()
        }),
        notes: Some(NoteElement {
        enabled: Some(Enabled(true)),
        header: Some("Additional Notes".to_string()),
        order: Some(Order(0)),
        placeholder: Some("Enter any additional notes here".to_string()),
        value: Some("".to_string()),
        ..Default::default()
        }),
        page: Some(PageElement {
        description: Some("Complete your payment securely".to_string()),
        enabled: Some(Enabled(true)),
        header: Some("Payment Page".to_string()),
        order: Some(Order(0)),
        ..Default::default()
        }),
        payment_button: Some(LabelElement {
        enabled: Some(Enabled(true)),
        label: Some("Pay Now".to_string()),
        order: Some(Order(0)),
        ..Default::default()
        }),
        payment_methods: Some(MethodElement {
        all_methods_checked: Some(true),
        enabled: Some(Enabled(true)),
        header: Some("Payment Methods".to_string()),
        methods: Some(MethodsList {
        amex: Some(true),
        apple_pay: Some(true),
        discover: Some(true),
        e_check: Some(true),
        mastercard: Some(true),
        visa: Some(true),
        ..Default::default()
        }),
        order: Some(Order(0)),
        settings: Some(MethodElementSettings {
        apple_pay: Some(MethodElementSettingsApplePay {
        button_style: Some(MethodElementSettingsApplePayButtonStyle::Black),
        button_type: Some(MethodElementSettingsApplePayButtonType::Pay),
        language: Some(MethodElementSettingsApplePayLanguage::EnUs),
        ..Default::default()
        }),
        ..Default::default()
        }),
        ..Default::default()
        }),
        payor: Some(PayorElement {
        enabled: Some(Enabled(true)),
        fields: Some(vec![PayorFields {
        display: Some(true),
        fixed: Some(true),
        identifier: Some(true),
        label: Some("Full Name".to_string()),
        name: Some("fullName".to_string()),
        order: Some(Order(0)),
        required: Some(true),
        validation: Some("alpha".to_string()),
        value: Some("".to_string()),
        width: Some(0),
        ..Default::default()
        }]),
        header: Some("Payor Information".to_string()),
        order: Some(Order(0)),
        ..Default::default()
        }),
        review: Some(HeaderElement {
        enabled: Some(Enabled(true)),
        header: Some("Review Payment".to_string()),
        order: Some(Order(0)),
        ..Default::default()
        }),
        settings: Some(PagelinkSetting {
        color: Some("#000000".to_string()),
        custom_css_url: Some("https://example.com/custom.css".to_string()),
        language: Some("en".to_string()),
        page_logo: Some(FileContent {
        f_content: Some(" ".to_string()),
        filename: Some("logo.jpg".to_string()),
        ftype: Some(FileContentFtype::Jpg),
        furl: Some("".to_string()),
        ..Default::default()
        }),
        redirect_after_approve: Some(true),
        redirect_after_approve_url: Some("https://example.com/success".to_string()),
        ..Default::default()
        }),
        ..Default::default()
        },
        amount_fixed: None
        }, None).await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count(
        "POST",
        "/PaymentLink/23548884",
        Some(HashMap::from([(
            "mail2".to_string(),
            json!("jo@example.com; ceo@example.com"),
        )])),
        1,
    )
    .await
    .unwrap();
}

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_add_pay_link_from_bill_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client
        .payment_link
        .add_pay_link_from_bill(
            23548884,
            &AddPayLinkFromBillRequest {
                mail_2: Some("jo@example.com; ceo@example.com".to_string()),
                body: PaymentPageRequestBodyOut {
                    contact_us: Some(ContactElement {
                        email_label: Some("Email".to_string()),
                        enabled: Some(Enabled(true)),
                        header: Some("Contact Us".to_string()),
                        order: Some(Order(0)),
                        payment_icons: Some(true),
                        phone_label: Some("Phone".to_string()),
                        ..Default::default()
                    }),
                    logo: Some(Element {
                        enabled: Some(Enabled(true)),
                        order: Some(Order(0)),
                        ..Default::default()
                    }),
                    message_before_paying: Some(LabelElement {
                        enabled: Some(Enabled(true)),
                        label: Some("Please review your payment details".to_string()),
                        order: Some(Order(0)),
                        ..Default::default()
                    }),
                    notes: Some(NoteElement {
                        enabled: Some(Enabled(true)),
                        header: Some("Additional Notes".to_string()),
                        order: Some(Order(0)),
                        placeholder: Some("Enter any additional notes here".to_string()),
                        value: Some("".to_string()),
                        ..Default::default()
                    }),
                    page: Some(PageElement {
                        description: Some("Get paid securely".to_string()),
                        enabled: Some(Enabled(true)),
                        header: Some("Payment Page".to_string()),
                        order: Some(Order(0)),
                        ..Default::default()
                    }),
                    payment_button: Some(LabelElement {
                        enabled: Some(Enabled(true)),
                        label: Some("Pay Now".to_string()),
                        order: Some(Order(0)),
                        ..Default::default()
                    }),
                    payment_methods: Some(MethodElementOut {
                        all_methods_checked: Some(true),
                        allow_multiple_methods: Some(true),
                        default_method: Some("vcard".to_string()),
                        enabled: Some(true),
                        header: Some("Payment Methods".to_string()),
                        methods: Some(MethodsListOut {
                            ach: Some(true),
                            check: Some(true),
                            vcard: Some(true),
                            ..Default::default()
                        }),
                        order: Some(0),
                        show_preview_virtual_card: Some(true),
                        ..Default::default()
                    }),
                    review: Some(HeaderElement {
                        enabled: Some(Enabled(true)),
                        header: Some("Review Payment".to_string()),
                        order: Some(Order(0)),
                        ..Default::default()
                    }),
                    settings: Some(PagelinkSetting {
                        color: Some("#000000".to_string()),
                        language: Some("en".to_string()),
                        ..Default::default()
                    }),
                    ..Default::default()
                },
                amount_fixed: None,
            },
            None,
        )
        .await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count(
        "POST",
        "/PaymentLink/bill/23548884",
        Some(HashMap::from([(
            "mail2".to_string(),
            json!("jo@example.com; ceo@example.com"),
        )])),
        1,
    )
    .await
    .unwrap();
}

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_delete_pay_link_from_id_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client
        .payment_link
        .delete_pay_link_from_id(
            &"2325-XXXXXXX-90b1-4598-b6c7-44cdcbf495d7-1234".to_string(),
            None,
        )
        .await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count(
        "DELETE",
        "/PaymentLink/2325-XXXXXXX-90b1-4598-b6c7-44cdcbf495d7-1234",
        None,
        1,
    )
    .await
    .unwrap();
}

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_get_pay_link_from_id_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client
        .payment_link
        .get_pay_link_from_id(&"paylinkId".to_string(), None)
        .await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count("GET", "/PaymentLink/load/paylinkId", None, 1)
        .await
        .unwrap();
}

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_push_pay_link_from_id_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client
        .payment_link
        .push_pay_link_from_id(&"payLinkId".to_string(), &PushPayLinkRequest::sms(), None)
        .await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count("POST", "/PaymentLink/push/payLinkId", None, 1)
        .await
        .unwrap();
}

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_refresh_pay_link_from_id_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client
        .payment_link
        .refresh_pay_link_from_id(
            &"payLinkId".to_string(),
            &RefreshPayLinkFromIdQueryRequest {
                ..Default::default()
            },
            None,
        )
        .await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count("GET", "/PaymentLink/refresh/payLinkId", None, 1)
        .await
        .unwrap();
}

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_send_pay_link_from_id_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client
        .payment_link
        .send_pay_link_from_id(
            &"payLinkId".to_string(),
            &SendPayLinkFromIdQueryRequest {
                mail_2: Some("jo@example.com; ceo@example.com".to_string()),
                ..Default::default()
            },
            None,
        )
        .await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count(
        "GET",
        "/PaymentLink/send/payLinkId",
        Some(HashMap::from([(
            "mail2".to_string(),
            json!("jo@example.com; ceo@example.com"),
        )])),
        1,
    )
    .await
    .unwrap();
}

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_update_pay_link_from_id_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client
        .payment_link
        .update_pay_link_from_id(
            &"332-c277b704-1301".to_string(),
            &PayLinkUpdateData {
                notes: Some(NoteElement {
                    enabled: Some(Enabled(true)),
                    header: Some("Additional Notes".to_string()),
                    order: Some(Order(0)),
                    placeholder: Some("Enter any additional notes here".to_string()),
                    value: Some("".to_string()),
                    ..Default::default()
                }),
                payment_button: Some(LabelElement {
                    enabled: Some(Enabled(true)),
                    label: Some("Pay Now".to_string()),
                    order: Some(Order(0)),
                    ..Default::default()
                }),
                ..Default::default()
            },
            None,
        )
        .await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count("PUT", "/PaymentLink/update/332-c277b704-1301", None, 1)
        .await
        .unwrap();
}

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_add_pay_link_from_bill_lot_number_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client
        .payment_link
        .add_pay_link_from_bill_lot_number(
            &"LOT-2024-001".to_string(),
            &AddPayLinkFromBillLotNumberRequest {
                entry_point: Entry("billing".to_string()),
                vendor_number: "VENDOR-123".to_string(),
                mail_2: Some("customer@example.com; billing@example.com".to_string()),
                amount_fixed: Some("true".to_string()),
                body: PaymentPageRequestBodyOut {
                    contact_us: Some(ContactElement {
                        email_label: Some("Email".to_string()),
                        enabled: Some(Enabled(true)),
                        header: Some("Contact Us".to_string()),
                        order: Some(Order(0)),
                        payment_icons: Some(true),
                        phone_label: Some("Phone".to_string()),
                        ..Default::default()
                    }),
                    logo: Some(Element {
                        enabled: Some(Enabled(true)),
                        order: Some(Order(0)),
                        ..Default::default()
                    }),
                    message_before_paying: Some(LabelElement {
                        enabled: Some(Enabled(true)),
                        label: Some("Please review your payment details".to_string()),
                        order: Some(Order(0)),
                        ..Default::default()
                    }),
                    notes: Some(NoteElement {
                        enabled: Some(Enabled(true)),
                        header: Some("Additional Notes".to_string()),
                        order: Some(Order(0)),
                        placeholder: Some("Enter any additional notes here".to_string()),
                        value: Some("".to_string()),
                        ..Default::default()
                    }),
                    page: Some(PageElement {
                        description: Some("Get paid securely".to_string()),
                        enabled: Some(Enabled(true)),
                        header: Some("Payment Page".to_string()),
                        order: Some(Order(0)),
                        ..Default::default()
                    }),
                    payment_button: Some(LabelElement {
                        enabled: Some(Enabled(true)),
                        label: Some("Pay Now".to_string()),
                        order: Some(Order(0)),
                        ..Default::default()
                    }),
                    payment_methods: Some(MethodElementOut {
                        all_methods_checked: Some(true),
                        allow_multiple_methods: Some(true),
                        default_method: Some("vcard".to_string()),
                        enabled: Some(true),
                        header: Some("Payment Methods".to_string()),
                        methods: Some(MethodsListOut {
                            ach: Some(true),
                            check: Some(true),
                            vcard: Some(true),
                            ..Default::default()
                        }),
                        order: Some(0),
                        show_preview_virtual_card: Some(true),
                        ..Default::default()
                    }),
                    review: Some(HeaderElement {
                        enabled: Some(Enabled(true)),
                        header: Some("Review Payment".to_string()),
                        order: Some(Order(0)),
                        ..Default::default()
                    }),
                    settings: Some(PagelinkSetting {
                        color: Some("#000000".to_string()),
                        language: Some("en".to_string()),
                        ..Default::default()
                    }),
                    ..Default::default()
                },
            },
            None,
        )
        .await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count(
        "POST",
        "/PaymentLink/bill/lotNumber/LOT-2024-001",
        Some(HashMap::from([
            ("entryPoint".to_string(), json!("billing")),
            ("vendorNumber".to_string(), json!("VENDOR-123")),
            (
                "mail2".to_string(),
                json!("customer@example.com; billing@example.com"),
            ),
            ("amountFixed".to_string(), json!("true")),
        ])),
        1,
    )
    .await
    .unwrap();
}

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_patch_out_payment_link_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client
        .payment_link
        .patch_out_payment_link(
            &"2325-XXXXXXX-90b1-4598-b6c7-44cdcbf495d7-1234".to_string(),
            &PatchOutPaymentLinkRequest {
                expiration_date: Some("2026-06-01T00:00:00Z".to_string()),
                status: Some(PaymentLinkStatus::Active),
                ..Default::default()
            },
            None,
        )
        .await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count(
        "PATCH",
        "/PaymentLink/out/2325-XXXXXXX-90b1-4598-b6c7-44cdcbf495d7-1234",
        None,
        1,
    )
    .await
    .unwrap();
}

#[tokio::test]
#[allow(unused_variables, unreachable_code)]
async fn test_payment_link_update_pay_link_out_from_id_with_wiremock() {
    wire_test_utils::reset_wiremock_requests().await.unwrap();
    let wiremock_base_url = wire_test_utils::get_wiremock_base_url();

    let mut config = ClientConfig {
        api_key: Some("<value>".to_string()),
        ..Default::default()
    };
    config.base_url = wiremock_base_url.to_string();
    let client = ApiClient::new(config).expect("Failed to build client");

    let result = client
        .payment_link
        .update_pay_link_out_from_id(
            &"2325-XXXXXXX-90b1-4598-b6c7-44cdcbf495d7-1234".to_string(),
            &PaymentPageRequestBodyOut {
                contact_us: Some(ContactElement {
                    email_label: Some("Email".to_string()),
                    enabled: Some(Enabled(true)),
                    header: Some("Contact Us".to_string()),
                    order: Some(Order(0)),
                    payment_icons: Some(true),
                    phone_label: Some("Phone".to_string()),
                    ..Default::default()
                }),
                logo: Some(Element {
                    enabled: Some(Enabled(true)),
                    order: Some(Order(0)),
                    ..Default::default()
                }),
                message_before_paying: Some(LabelElement {
                    enabled: Some(Enabled(true)),
                    label: Some("Please review your payment details".to_string()),
                    order: Some(Order(0)),
                    ..Default::default()
                }),
                notes: Some(NoteElement {
                    enabled: Some(Enabled(true)),
                    header: Some("Additional Notes".to_string()),
                    order: Some(Order(0)),
                    placeholder: Some("Enter any additional notes here".to_string()),
                    value: Some("".to_string()),
                    ..Default::default()
                }),
                page: Some(PageElement {
                    description: Some("Get paid securely".to_string()),
                    enabled: Some(Enabled(true)),
                    header: Some("Payment Page".to_string()),
                    order: Some(Order(0)),
                    ..Default::default()
                }),
                payment_button: Some(LabelElement {
                    enabled: Some(Enabled(true)),
                    label: Some("Pay Now".to_string()),
                    order: Some(Order(0)),
                    ..Default::default()
                }),
                payment_methods: Some(MethodElementOut {
                    all_methods_checked: Some(true),
                    allow_multiple_methods: Some(true),
                    default_method: Some("vcard".to_string()),
                    enabled: Some(true),
                    header: Some("Payment Methods".to_string()),
                    methods: Some(MethodsListOut {
                        ach: Some(true),
                        check: Some(true),
                        vcard: Some(true),
                        ..Default::default()
                    }),
                    order: Some(0),
                    show_preview_virtual_card: Some(true),
                    ..Default::default()
                }),
                review: Some(HeaderElement {
                    enabled: Some(Enabled(true)),
                    header: Some("Review Payment".to_string()),
                    order: Some(Order(0)),
                    ..Default::default()
                }),
                settings: Some(PagelinkSetting {
                    color: Some("#000000".to_string()),
                    language: Some("en".to_string()),
                    ..Default::default()
                }),
                ..Default::default()
            },
            None,
        )
        .await;

    assert!(result.is_ok(), "Client method call should succeed");

    wire_test_utils::verify_request_count(
        "PATCH",
        "/PaymentLink/updateOut/2325-XXXXXXX-90b1-4598-b6c7-44cdcbf495d7-1234",
        None,
        1,
    )
    .await
    .unwrap();
}
