from datetime import date, datetime
from enum import Enum as PyEnum

from sqlalchemy import JSON, Boolean, Column, Date, DateTime
from sqlalchemy import Enum as SQLEnum
from sqlalchemy import ForeignKey, Index, Integer, String
from sqlalchemy.orm import relationship

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


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


class TaskCertainty(str, PyEnum):
    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=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, 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=datetime.utcnow, nullable=False)
