// Code generated by oagen. DO NOT EDIT.

use crate::client::Retab;
#[allow(unused_imports)]
use crate::enums::*;
use crate::error::Error;
#[allow(unused_imports)]
use crate::models::*;
use serde::Serialize;

pub struct JobsApi<'a> {
    pub(crate) client: &'a Retab,
}

#[derive(Debug, Clone, Serialize)]
pub struct ListParams {
    /// First job ID from the current page, used to fetch the previous page
    #[serde(skip_serializing_if = "Option::is_none")]
    pub before: Option<String>,
    /// Last job ID from the previous page, used to fetch the next page
    #[serde(skip_serializing_if = "Option::is_none")]
    pub after: Option<String>,
    /// Number of jobs to return
    ///
    /// Defaults to `20`.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub limit: Option<i64>,
    /// Sort order by created_at
    ///
    /// Defaults to `desc`.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub order: Option<JobsOrder>,
    /// Filter by job ID
    #[serde(skip_serializing_if = "Option::is_none")]
    pub job_id: Option<String>,
    /// Filter by status
    #[serde(skip_serializing_if = "Option::is_none")]
    pub status: Option<JobsStatus>,
    /// Filter by endpoint
    #[serde(skip_serializing_if = "Option::is_none")]
    pub endpoint: Option<JobsEndpoint>,
    /// High-level source filter. Use api/project/workflow.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub source: Option<JobsSource>,
    /// Filter by request.project_id
    #[serde(skip_serializing_if = "Option::is_none")]
    pub project_id: Option<String>,
    /// Filter by metadata.workflow_id
    #[serde(skip_serializing_if = "Option::is_none")]
    pub workflow_id: Option<String>,
    /// Filter by metadata.workflow_block_id or metadata.block_id
    #[serde(skip_serializing_if = "Option::is_none")]
    pub workflow_block_id: Option<String>,
    /// Filter by request.model
    #[serde(skip_serializing_if = "Option::is_none")]
    pub model: Option<String>,
    /// Regex or plain text pattern applied to request filenames.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub filename_regex: Option<String>,
    /// Plain text substring applied to request filenames.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub filename_contains: Option<String>,
    /// Filter by document type. Can be repeated. Accepted values: bmp, csv, doc, docm, docx, dotm, dotx, eml, gif, heic, heif, htm, html, jpeg, jpg, json, md, mhtml, msg, odp, ods, odt, ots, ott, pdf, png, ppt, pptx, rtf, svg, tif, tiff, tsv, txt, webp, xlam, xls, xlsb, xlsm, xlsx, xltm, xltx, xml, yaml, yml.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub document_type: Option<Vec<String>>,
    /// Filter jobs created on or after this date (YYYY-MM-DD)
    #[serde(skip_serializing_if = "Option::is_none")]
    pub from_date: Option<String>,
    /// Filter jobs created on or before this date (YYYY-MM-DD)
    #[serde(skip_serializing_if = "Option::is_none")]
    pub to_date: Option<String>,
    /// JSON object string to filter metadata key/value pairs.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub metadata: Option<String>,
    /// Whether to include the full original request body in each listed job.
    ///
    /// Defaults to `false`.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub include_request: Option<bool>,
    /// Whether to include full response payloads in each listed job.
    ///
    /// Defaults to `false`.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub include_response: Option<bool>,
}

impl Default for ListParams {
    #[allow(deprecated)]
    fn default() -> Self {
        Self {
            before: Default::default(),
            after: Default::default(),
            limit: Some(20),
            order: Some(JobsOrder::Desc),
            job_id: Default::default(),
            status: Default::default(),
            endpoint: Default::default(),
            source: Default::default(),
            project_id: Default::default(),
            workflow_id: Default::default(),
            workflow_block_id: Default::default(),
            model: Default::default(),
            filename_regex: Default::default(),
            filename_contains: Default::default(),
            document_type: Default::default(),
            from_date: Default::default(),
            to_date: Default::default(),
            metadata: Default::default(),
            include_request: Some(false),
            include_response: Some(false),
        }
    }
}

#[derive(Debug, Clone, Serialize)]
pub struct CreateParams {
    /// Request body sent with this call.
    ///
    /// Required.
    #[serde(skip)]
    pub body: CreateJobRequest,
}

impl CreateParams {
    /// Construct a new `CreateParams` with the required fields set.
    #[allow(deprecated)]
    pub fn new(body: CreateJobRequest) -> Self {
        Self { body }
    }
}

#[derive(Debug, Clone, Serialize)]
pub struct GetParams {
    /// Include the original request payload in the response.
    ///
    /// Defaults to `false`.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub include_request: Option<bool>,
    /// Include the job response payload in the response.
    ///
    /// Defaults to `false`.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub include_response: Option<bool>,
}

impl Default for GetParams {
    #[allow(deprecated)]
    fn default() -> Self {
        Self {
            include_request: Some(false),
            include_response: Some(false),
        }
    }
}

impl<'a> JobsApi<'a> {
    /// List Jobs
    ///
    /// List jobs with pagination and optional status filtering.
    pub async fn list(&self, params: ListParams) -> Result<JobList, Error> {
        self.list_with_options(params, None).await
    }

    /// Variant of [`Self::list`] that accepts per-request [`crate::RequestOptions`].
    pub async fn list_with_options(
        &self,
        params: ListParams,
        options: Option<&crate::RequestOptions>,
    ) -> Result<JobList, Error> {
        let path = "/v1/jobs".to_string();
        let method = http::Method::GET;
        self.client
            .request_with_query_opts(method, &path, &params, options)
            .await
    }

    /// Returns an async [`futures_util::Stream`] that yields every `Job`
    /// across all pages, advancing the `after` cursor under the hood.
    ///
    /// ```ignore
    /// use futures_util::TryStreamExt;
    /// let all: Vec<Job> = self
    ///     .list_auto_paging(params)
    ///     .try_collect()
    ///     .await?;
    /// ```
    pub fn list_auto_paging(
        &self,
        params: ListParams,
    ) -> impl futures_util::Stream<Item = Result<Job, Error>> + '_ {
        crate::pagination::auto_paginate_pages(move |after| {
            let mut params = params.clone();
            params.after = after;
            async move {
                let page = self.list(params).await?;
                Ok((page.data, page.list_metadata.after))
            }
        })
    }

    /// Create Job
    ///
    /// Create a new asynchronous job.
    ///
    /// The job will be queued for processing and can be polled for status
    /// using the retrieve endpoint.
    pub async fn create(&self, params: CreateParams) -> Result<Job, Error> {
        self.create_with_options(params, None).await
    }

    /// Variant of [`Self::create`] that accepts per-request [`crate::RequestOptions`].
    pub async fn create_with_options(
        &self,
        params: CreateParams,
        options: Option<&crate::RequestOptions>,
    ) -> Result<Job, Error> {
        let path = "/v1/jobs".to_string();
        let method = http::Method::POST;
        self.client
            .request_with_body_opts(method, &path, &params, Some(&params.body), options)
            .await
    }

    /// Retrieve Job
    pub async fn get(&self, job_id: &str, params: GetParams) -> Result<Job, Error> {
        self.get_with_options(job_id, params, None).await
    }

    /// Variant of [`Self::get`] that accepts per-request [`crate::RequestOptions`].
    pub async fn get_with_options(
        &self,
        job_id: &str,
        params: GetParams,
        options: Option<&crate::RequestOptions>,
    ) -> Result<Job, Error> {
        let job_id = crate::client::path_segment(job_id);
        let path = format!("/v1/jobs/{job_id}");
        let method = http::Method::GET;
        self.client
            .request_with_query_opts(method, &path, &params, options)
            .await
    }

    /// Cancel Job
    ///
    /// Cancel an in-progress or queued job.
    ///
    /// Returns the updated job with status 'cancelled'.
    pub async fn cancel(&self, job_id: &str) -> Result<Job, Error> {
        self.cancel_with_options(job_id, None).await
    }

    /// Variant of [`Self::cancel`] that accepts per-request [`crate::RequestOptions`].
    pub async fn cancel_with_options(
        &self,
        job_id: &str,
        options: Option<&crate::RequestOptions>,
    ) -> Result<Job, Error> {
        let job_id = crate::client::path_segment(job_id);
        let path = format!("/v1/jobs/{job_id}/cancel");
        let method = http::Method::POST;
        self.client
            .request_with_query_opts(method, &path, &(), options)
            .await
    }

    /// Retry Job
    ///
    /// Retry a failed/cancelled/expired job in-place (same job ID).
    ///
    /// The job is reset to queued and processed again.
    pub async fn retry(&self, job_id: &str) -> Result<Job, Error> {
        self.retry_with_options(job_id, None).await
    }

    /// Variant of [`Self::retry`] that accepts per-request [`crate::RequestOptions`].
    pub async fn retry_with_options(
        &self,
        job_id: &str,
        options: Option<&crate::RequestOptions>,
    ) -> Result<Job, Error> {
        let job_id = crate::client::path_segment(job_id);
        let path = format!("/v1/jobs/{job_id}/retry");
        let method = http::Method::POST;
        self.client
            .request_with_query_opts(method, &path, &(), options)
            .await
    }
}
