"""pending_imports — two-step import staging (M4; alembic 0004).

The parsed CSV lives here between upload and commit: the resolver page
reads it, commit consumes it, cancel deletes it. Rows are ephemeral —
`expires_at` is enforced (purged on upload, not-found on read;
T-IMP-031), and `tenant_id` deliberately carries no FK so the nightly
rebuild-from-legacy transforms can keep truncating the entity tables
(see the 0004 migration docstring / ADR #005).
"""

import uuid
from datetime import datetime

from sqlalchemy import CheckConstraint, DateTime, ForeignKey, Index, Integer, Text, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column

from app.models.base import Base, PortableJSON


class PendingImport(Base):
    __tablename__ = "pending_imports"
    __table_args__ = (
        CheckConstraint("source IN ('clockify')", name="ck_pending_imports_source"),
        Index("ix_pending_imports_uploaded_by", "uploaded_by"),
        Index("ix_pending_imports_expires_at", "expires_at"),
    )

    id: Mapped[uuid.UUID] = mapped_column(Uuid(), primary_key=True, default=uuid.uuid4)
    # no FK — the nightly transforms rebuild (truncate) tenants
    tenant_id: Mapped[uuid.UUID] = mapped_column(Uuid())
    # attribution uses the EFFECTIVE user (ADR #033 carry-over)
    uploaded_by: Mapped[uuid.UUID] = mapped_column(
        ForeignKey("users.id", ondelete="CASCADE")
    )
    uploaded_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now()
    )
    expires_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        server_default=func.now(),  # real default (+24h) set by the app/migration
    )
    filename: Mapped[str | None] = mapped_column(Text())
    batch_name: Mapped[str | None] = mapped_column(Text())
    notes: Mapped[str | None] = mapped_column(Text())
    source: Mapped[str] = mapped_column(Text(), default="clockify")
    date_format: Mapped[str | None] = mapped_column(Text())
    parsed_entries: Mapped[list] = mapped_column(PortableJSON)
    parse_errors: Mapped[list] = mapped_column(PortableJSON, default=list)
    parse_warnings: Mapped[list] = mapped_column(PortableJSON, default=list)
    total_rows: Mapped[int] = mapped_column(Integer(), default=0)
