# Auto-generated by DjangoCFG - see CLAUDE.md

from __future__ import annotations
import datetime
from typing import Any

from pydantic import BaseModel, ConfigDict, Field

from ..enums import ArchiveJobStatusStatus, DataSourceCrawlStatus, DataSourceSourceType


class DataSourceCreateRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    source_type: DataSourceSourceType | None = Field(
    None,
    description='* `github_repo` - GitHub Repository',
)
    url: str = Field(
    description='GitHub repository URL, e.g. http...',
    min_length=1,
    max_length=500,
)
    branch: str | None = Field(
    None,
    description='Branch, tag or commit SHA to crawl',
    min_length=1,
    max_length=100,
)
    path_filter: str | None = Field(
    None,
    description='Optional path prefix filter, e.g...',
    max_length=255,
)
    crawl_interval_hours: int | None = Field(
    None,
    description='How often to re-crawl this sourc...',
    ge=-2147483648,
    le=2147483647,
)



class PatchedDataSourceRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    source_type: DataSourceSourceType | None = Field(
    None,
    description='* `github_repo` - GitHub Repository',
)
    url: str | None = Field(
    None,
    description='GitHub repository URL, e.g. http...',
    min_length=1,
    max_length=500,
)
    branch: str | None = Field(
    None,
    description='Branch, tag or commit SHA to crawl',
    min_length=1,
    max_length=100,
)
    path_filter: str | None = Field(
    None,
    description='Optional path prefix filter, e.g...',
    max_length=255,
)
    crawl_interval_hours: int | None = Field(
    None,
    description='How often to re-crawl this sourc...',
    ge=-2147483648,
    le=2147483647,
)
    is_active: bool | None = None



class PublicProjectList(BaseModel):
    """
    Compact serializer for public project listing.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    id: str = ...
    name: Any = ...
    slug: Any = Field(pattern='^[-a-zA-Z0-9_]+$')
    description: Any = ...
    total_documents: int = ...
    total_chunks: int = ...
    public_url: Any = ...
    created_at: datetime.datetime = ...
    updated_at: datetime.datetime = ...



class PaginatedPublicProjectListList(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    count: int = Field(description='Total number of items across all...')
    page: int = Field(description='Current page number (1-based)')
    pages: int = Field(description='Total number of pages')
    page_size: int = Field(description='Number of items per page')
    has_next: bool = Field(description='Whether there is a next page')
    has_previous: bool = Field(description='Whether there is a previous page')
    next_page: int | None = Field(None, description='Next page number (null if no nex...')
    previous_page: int | None = Field(None, description='Previous page number (null if no...')
    results: list[PublicProjectList] = Field(description='Array of items for current page')



class PublicSearchRequestRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    query: str = Field(min_length=1, max_length=2000)
    limit: int | None = Field(None, ge=1, le=50)
    threshold: float | None = Field(None, ge=0.0, le=1.0)



class Project(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    id: str = ...
    name: str = Field(max_length=255)
    slug: str = Field(max_length=100, pattern='^[-a-zA-Z0-9_]+$')
    description: str | None = None
    is_public: bool | None = Field(None, description='Public projects are accessible v...')
    embedding_model: str | None = Field(None, max_length=100)
    similarity_threshold: float | None = None
    max_search_results: int | None = Field(None, ge=-2147483648, le=2147483647)
    total_documents: int = ...
    total_chunks: int = ...
    total_tokens: int = ...
    total_cost_usd: Any = Field(pattern='^-?\\d{0,4}(?:\\.\\d{0,6})?$')
    metadata: dict[str, Any] | None = None
    public_url: Any = ...
    created_at: datetime.datetime = ...
    updated_at: datetime.datetime = ...



class PublicDocumentDetail(BaseModel):
    """
    Full public document with content for reading.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    id: str = ...
    title: Any = ...
    source_url: str = Field(description='Original URL (e.g. GitHub file URL)')
    source_path: Any = Field(description='Relative path in repo, e.g. docs...')
    file_type: Any = Field(description='Programming language or format (...')
    language: Any = ...
    processing_status: DataSourceCrawlStatus = Field(
    description='* `pending` - Pending * `process...',
)
    chunks_count: int = ...
    raw_content: Any = Field(description='Original source file content bef...')
    public_url: Any = ...
    created_at: datetime.datetime = ...
    updated_at: datetime.datetime = ...



class ArchiveBulkCreateResponse(BaseModel):
    """
    Response from POST /documents/bulk/ — archive ingestion job queued.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    job_id: str = Field(description='RQ job ID for polling status')
    message: str = Field(description='Human-readable status message')



class ProjectCreateRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    name: str = Field(min_length=1, max_length=255)
    slug: str = Field(min_length=1, max_length=100, pattern='^[-a-zA-Z0-9_]+$')
    description: str | None = None
    is_public: bool | None = Field(None, description='Public projects are accessible v...')
    embedding_model: str | None = Field(None, min_length=1, max_length=100)
    similarity_threshold: float | None = None
    max_search_results: int | None = Field(None, ge=-2147483648, le=2147483647)



class PublicSearchResultItem(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    chunk_id: str = ...
    document_id: str = ...
    document_title: str = ...
    source_url: str = ...
    content: str = ...
    similarity: float = ...



class PublicSearchResponse(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    results: list[PublicSearchResultItem] = ...
    total: int = ...
    query_tokens: int = ...
    search_time_ms: float = ...



class Document(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    id: str = ...
    title: Any = ...
    source_url: str = Field(description='Original URL (e.g. GitHub file URL)')
    source_path: Any = Field(description='Relative path in repo, e.g. docs...')
    file_type: Any = Field(description='Programming language or format (...')
    language: Any = ...
    processing_status: DataSourceCrawlStatus = Field(
    description='* `pending` - Pending * `process...',
)
    processing_error: Any = ...
    processing_started_at: datetime.datetime | None = None
    processing_completed_at: datetime.datetime | None = None
    chunks_count: int = ...
    total_tokens: int = ...
    total_cost_usd: Any = Field(pattern='^-?\\d{0,4}(?:\\.\\d{0,6})?$')
    metadata: dict[str, Any] = ...
    raw_content: Any = Field(description='Original source file content bef...')
    public_url: Any = ...
    created_at: datetime.datetime = ...
    updated_at: datetime.datetime = ...



class PaginatedDocumentList(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    count: int = Field(description='Total number of items across all...')
    page: int = Field(description='Current page number (1-based)')
    pages: int = Field(description='Total number of pages')
    page_size: int = Field(description='Number of items per page')
    has_next: bool = Field(description='Whether there is a next page')
    has_previous: bool = Field(description='Whether there is a previous page')
    next_page: int | None = Field(None, description='Next page number (null if no nex...')
    previous_page: int | None = Field(None, description='Previous page number (null if no...')
    results: list[Document] = Field(description='Array of items for current page')



class ArchiveJobStatus(BaseModel):
    """
    Response from GET /documents/bulk/{job_id}/status/

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    job_id: str = Field(description='RQ job ID')
    status: ArchiveJobStatusStatus = Field(description='Current job status  * `queued` -...')
    error: str | None = Field(None, description='Error message if status=error, n...')
    result: dict[str, Any] | None = Field(None, description='IngestStats result dict when sta...')



class PublicProject(BaseModel):
    """
    Full serializer for public project detail.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    id: str = ...
    name: Any = ...
    slug: Any = Field(pattern='^[-a-zA-Z0-9_]+$')
    description: Any = ...
    similarity_threshold: float = ...
    max_search_results: int = ...
    total_documents: int = ...
    total_chunks: int = ...
    total_tokens: int = ...
    public_url: Any = ...
    created_at: datetime.datetime = ...
    updated_at: datetime.datetime = ...



class PatchedProjectRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    name: str | None = Field(None, min_length=1, max_length=255)
    slug: str | None = Field(None, min_length=1, max_length=100, pattern='^[-a-zA-Z0-9_]+$')
    description: str | None = None
    is_public: bool | None = Field(None, description='Public projects are accessible v...')
    embedding_model: str | None = Field(None, min_length=1, max_length=100)
    similarity_threshold: float | None = None
    max_search_results: int | None = Field(None, ge=-2147483648, le=2147483647)
    metadata: dict[str, Any] | None = None



class ProjectRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    name: str = Field(min_length=1, max_length=255)
    slug: str = Field(min_length=1, max_length=100, pattern='^[-a-zA-Z0-9_]+$')
    description: str | None = None
    is_public: bool | None = Field(None, description='Public projects are accessible v...')
    embedding_model: str | None = Field(None, min_length=1, max_length=100)
    similarity_threshold: float | None = None
    max_search_results: int | None = Field(None, ge=-2147483648, le=2147483647)
    metadata: dict[str, Any] | None = None



class DocumentUploadRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    title: str = Field(min_length=1, max_length=500)
    content: str = Field(description='Raw Markdown or plain text content', min_length=1)
    source_url: str | None = Field(None, min_length=1)



class DataSource(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    id: str = ...
    source_type: DataSourceSourceType | None = Field(
    None,
    description='* `github_repo` - GitHub Repository',
)
    url: str = Field(description='GitHub repository URL, e.g. http...', max_length=500)
    branch: str | None = Field(
    None,
    description='Branch, tag or commit SHA to crawl',
    max_length=100,
)
    path_filter: str | None = Field(
    None,
    description='Optional path prefix filter, e.g...',
    max_length=255,
)
    crawl_interval_hours: int | None = Field(
    None,
    description='How often to re-crawl this sourc...',
    ge=-2147483648,
    le=2147483647,
)
    is_active: bool | None = None
    crawl_status: DataSourceCrawlStatus = Field(description='* `pending` - Pending * `process...')
    last_crawled_at: datetime.datetime | None = None
    next_crawl_at: datetime.datetime | None = None
    crawl_error: Any = ...
    documents_added: int = ...
    documents_updated: int = ...
    documents_total: int = ...
    created_at: datetime.datetime = ...
    updated_at: datetime.datetime = ...



class ProjectCreate(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    name: str = Field(max_length=255)
    slug: str = Field(max_length=100, pattern='^[-a-zA-Z0-9_]+$')
    description: str | None = None
    is_public: bool | None = Field(None, description='Public projects are accessible v...')
    embedding_model: str | None = Field(None, max_length=100)
    similarity_threshold: float | None = None
    max_search_results: int | None = Field(None, ge=-2147483648, le=2147483647)



class SearchRequestRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    query: str = Field(min_length=1, max_length=2000)
    limit: int | None = Field(None, ge=1, le=50)
    threshold: float | None = Field(None, ge=0.0, le=1.0)



class KnowbaseProjectsChatSettingsPartialUpdateRequest(BaseModel):
    """
    Unspecified request body

    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    pass



class DataSourceRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    source_type: DataSourceSourceType | None = Field(
    None,
    description='* `github_repo` - GitHub Repository',
)
    url: str = Field(
    description='GitHub repository URL, e.g. http...',
    min_length=1,
    max_length=500,
)
    branch: str | None = Field(
    None,
    description='Branch, tag or commit SHA to crawl',
    min_length=1,
    max_length=100,
)
    path_filter: str | None = Field(
    None,
    description='Optional path prefix filter, e.g...',
    max_length=255,
)
    crawl_interval_hours: int | None = Field(
    None,
    description='How often to re-crawl this sourc...',
    ge=-2147483648,
    le=2147483647,
)
    is_active: bool | None = None



class KnowbaseProjectsDocumentsBulkCreateRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    archive: Any | None = None



class PublicDocument(BaseModel):
    """
    Read-only serializer for public document listing. No raw_content, no
    metadata.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    id: str = ...
    title: Any = ...
    source_url: str = Field(description='Original URL (e.g. GitHub file URL)')
    file_type: Any = Field(description='Programming language or format (...')
    language: Any = ...
    processing_status: DataSourceCrawlStatus = Field(
    description='* `pending` - Pending * `process...',
)
    chunks_count: int = ...
    public_url: Any = ...
    created_at: datetime.datetime = ...



class PaginatedPublicDocumentList(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    count: int = Field(description='Total number of items across all...')
    page: int = Field(description='Current page number (1-based)')
    pages: int = Field(description='Total number of pages')
    page_size: int = Field(description='Number of items per page')
    has_next: bool = Field(description='Whether there is a next page')
    has_previous: bool = Field(description='Whether there is a previous page')
    next_page: int | None = Field(None, description='Next page number (null if no nex...')
    previous_page: int | None = Field(None, description='Previous page number (null if no...')
    results: list[PublicDocument] = Field(description='Array of items for current page')



class DocumentFileUploadRequestRequest(BaseModel):
    """
    
    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    file: Any = Field(description='File to upload (PDF, MD, TXT, HT...')
    title: str | None = Field(
    None,
    description='Document title (defaults to file...',
    min_length=1,
)



class KBSearchResultItem(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    chunk_id: str = ...
    document_id: str = ...
    document_title: str = ...
    source_url: str = ...
    content: str = ...
    similarity: float = ...
    metadata: dict[str, Any] = ...



class KBSearchResponse(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    results: list[KBSearchResultItem] = ...
    total: int = ...
    query_tokens: int = ...
    search_time_ms: float = ...



class PaginatedDataSourceList(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    count: int = Field(description='Total number of items across all...')
    page: int = Field(description='Current page number (1-based)')
    pages: int = Field(description='Total number of pages')
    page_size: int = Field(description='Number of items per page')
    has_next: bool = Field(description='Whether there is a next page')
    has_previous: bool = Field(description='Whether there is a previous page')
    next_page: int | None = Field(None, description='Next page number (null if no nex...')
    previous_page: int | None = Field(None, description='Previous page number (null if no...')
    results: list[DataSource] = Field(description='Array of items for current page')



class PaginatedProjectList(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    count: int = Field(description='Total number of items across all...')
    page: int = Field(description='Current page number (1-based)')
    pages: int = Field(description='Total number of pages')
    page_size: int = Field(description='Number of items per page')
    has_next: bool = Field(description='Whether there is a next page')
    has_previous: bool = Field(description='Whether there is a previous page')
    next_page: int | None = Field(None, description='Next page number (null if no nex...')
    previous_page: int | None = Field(None, description='Previous page number (null if no...')
    results: list[Project] = Field(description='Array of items for current page')



