import enum
from typing import Optional
from datetime import datetime
from uuid import UUID, uuid4

from sqlalchemy import Column, Enum
from sqlmodel import SQLModel, Field, Relationship


class SourceEnum(enum.Enum):  # TODO: move to domain?
    PORTFOLIO = "portfolio_id"
    HUBSPOT_DEAL = "hubspot_deal_id"


class Task(SQLModel, table=True):
    __tablename__ = "tasks"

    id: UUID = Field(
        default_factory=uuid4,
        primary_key=True,
        index=True,
    )
    task_source: str
    job_started: Optional[datetime] = None
    job_completed: Optional[datetime] = None
    status: str = Field(default="In Progress")
    service: Optional[str] = None
    updated_at: datetime = Field(default_factory=datetime.utcnow)

    # source: Mapped[Optional[SourceEnum]] = mapped_column(Enum(SourceEnum)) <- SQLAlchemy not SQLModel

    source: Optional[SourceEnum] = Field(
        default=None,
        sa_column=Column(
            Enum(
                SourceEnum,
                name="source",
                values_callable=lambda e: [m.value for m in e],
            ),
            nullable=True,
        ),
    )
    source_id: Optional[str] = None

    sub_tasks: list["SubTask"] = Relationship(back_populates="task")


class SubTask(SQLModel, table=True):
    __tablename__ = "sub_task"

    id: UUID = Field(
        default_factory=uuid4,
        primary_key=True,
        index=True,
    )

    task_id: UUID = Field(foreign_key="tasks.id")
    job_started: Optional[datetime] = None
    job_completed: Optional[datetime] = None
    status: str = Field(default="In Progress")
    inputs: Optional[str] = None
    outputs: Optional[str] = None
    cloud_logs_url: Optional[str] = None
    updated_at: datetime = Field(default_factory=datetime.utcnow)

    task: Optional["Task"] = Relationship(back_populates="sub_tasks")
