"""Import job models for bulk/legacy data ingestion."""

from datetime import datetime
from enum import Enum
from typing import Any
from uuid import UUID

from pydantic import BaseModel, Field


class ImportJobStatus(str, Enum):
    """Import job status values."""

    UPLOADING = "uploading"
    PROCESSING = "processing"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"


class ImportFormat(str, Enum):
    """Supported import data formats."""

    JSONL = "jsonl"
    PARQUET = "parquet"


class BulkTelemetryRecord(BaseModel):
    """A single telemetry record for bulk import.

    This is the format to transform legacy data into before importing.
    Matches the per-tenant TimescaleDB telemetry table schema.

    Example:
        ```python
        record = BulkTelemetryRecord(
            time=datetime(2020, 6, 15, 14, 30, tzinfo=UTC),
            vessel_id=UUID("550e8400-e29b-41d4-a716-446655440000"),
            data_type="position",
            data={"latitude": 64.1466, "longitude": -21.9426, "speed": 12.5},
        )
        ```
    """

    time: datetime = Field(..., description="Timestamp in ISO 8601 format (required)")
    vessel_id: UUID | None = Field(default=None, description="Vessel UUID (if known)")
    source_id: str | None = Field(
        default=None, max_length=255, description="Source device identifier"
    )
    data_type: str | None = Field(
        default=None, max_length=50, description="Data type (position, engine, etc.)"
    )
    data: dict[str, Any] = Field(
        default_factory=dict, description="Telemetry payload"
    )
    ingress_metadata: dict[str, Any] = Field(
        default_factory=dict, description="Optional metadata about the data source"
    )


class ImportJob(BaseModel):
    """Import job details."""

    id: UUID
    tenant_id: UUID
    created_by: UUID
    name: str
    description: str | None = None
    status: ImportJobStatus
    format: ImportFormat
    total_parts: int
    parts_uploaded: int
    parts_processed: int
    total_rows: int
    rows_to_hot: int
    rows_to_cold: int
    rows_failed: int
    total_size_bytes: int
    hot_cold_cutoff: datetime
    enable_domain_processing: bool
    processing_started_at: datetime | None = None
    processing_completed_at: datetime | None = None
    error_message: str | None = None
    created_at: datetime
    updated_at: datetime


class ImportJobPart(BaseModel):
    """Individual upload part within an import job."""

    id: UUID
    job_id: UUID
    part_number: int
    status: str
    storage_key: str
    upload_url: str | None = None
    upload_url_expires_at: datetime | None = None
    size_bytes: int
    checksum: str | None = None
    row_count: int
    rows_to_hot: int
    rows_to_cold: int
    rows_failed: int
    data_start_time: datetime | None = None
    data_end_time: datetime | None = None
    error_message: str | None = None
    processing_started_at: datetime | None = None
    processing_completed_at: datetime | None = None
    created_at: datetime


class CreateImportJobResponse(BaseModel):
    """Response from creating an import job."""

    job: ImportJob
    parts: list[ImportJobPart]


class ImportJobListResponse(BaseModel):
    """Paginated list of import jobs."""

    items: list[ImportJob]
    total: int
    limit: int
    offset: int


class BulkImportResponse(BaseModel):
    """Response from a direct batch import."""

    rows_inserted: int
    rows_to_hot: int
    rows_to_cold: int
    rows_failed: int
    errors: list[dict[str, Any]] | None = None


class ImportSchemaResponse(BaseModel):
    """Describes the expected data format for import files."""

    jsonl_format: dict[str, Any]
    parquet_format: dict[str, Any]
    data_types: list[str]
    examples: list[dict[str, Any]]
