from datetime import UTC, date, datetime
from enum import StrEnum

from sqlalchemy import JSON, Boolean, Column, Date, DateTime, Index, Integer, String
from sqlalchemy import Enum as SQLEnum

from .database import Base  # Assuming a shared Base in models/database.py


class TaskState(StrEnum):
    LATER = "LATER"
    NEXT = "NEXT"
    NOW = "NOW"
    DONE = "DONE"
    DEFERRED = "DEFERRED"  # Task pushed to tomorrow


class TaskCertainty(StrEnum):
    FUZZY = "FUZZY"  # An intention without a time
    SOFT = "SOFT"  # A flexible task with a time
    HARD = "HARD"  # A fixed meeting/appointment


class Task(Base):
    __tablename__ = "tasks"

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String(255), nullable=False)
    description = Column(String(1000), nullable=True)

    state = Column(SQLEnum(TaskState), default=TaskState.LATER, nullable=False, index=True)
    certainty = Column(SQLEnum(TaskCertainty), default=TaskCertainty.SOFT, nullable=False)
    is_mit = Column(Boolean, default=False, nullable=False)  # 1-3 per day

    sort_order = Column(Integer, default=0, nullable=False)

    # Time tracking
    started_at = Column(DateTime, nullable=True)
    completed_at = Column(DateTime, nullable=True)
    deferred_at = Column(DateTime, nullable=True)

    # Timestamps
    created_at = Column(DateTime, default=lambda: datetime.now(UTC), nullable=False)
    updated_at = Column(
        DateTime,
        default=lambda: datetime.now(UTC),
        onupdate=lambda: datetime.now(UTC),
        nullable=False,
    )

    __table_args__ = (Index("ix_task_state_order", "state", "sort_order"),)


class JournalEntry(Base):
    __tablename__ = "journal_entries"

    id = Column(Integer, primary_key=True, index=True)
    entry_date = Column(Date, unique=True, nullable=False, index=True, default=date.today)

    # Relationships to the 1-3 MITs for the day
    mit_task_ids = Column(JSON, nullable=True)

    evening_reflection = Column(String(2000), nullable=True)
    gratitude = Column(String(500), nullable=True)
    energy_level = Column(Integer, nullable=True)  # User-reported, 1-10

    created_at = Column(DateTime, default=lambda: datetime.now(UTC), nullable=False)
