"""
Project model for individual projects and engagements.

Tracks client projects, internal products, infrastructure work, and development tools.
"""

from datetime import date, datetime
from typing import TYPE_CHECKING, Optional

from sqlalchemy import DATE, ForeignKey, Index, Numeric, String, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship

from .base import Base, TimestampMixin, UUIDMixin

if TYPE_CHECKING:
    from .client import Client
    from .pending_task import PendingTask
    from .session import Session


class Project(Base, UUIDMixin, TimestampMixin):
    """
    Project model representing individual projects and engagements.

    Tracks client projects, internal products, infrastructure work,
    websites, development tools, and documentation projects. Each project
    belongs to a client and has status, priority, and time tracking.

    Attributes:
        client_id: Foreign key to clients table
        name: Project name
        slug: URL-safe slug (directory name)
        category: Project category
        status: Current status (complete, working, blocked, pending, critical, deferred)
        priority: Priority level (critical, high, medium, low)
        description: Project description
        started_date: Date project started
        target_completion_date: Target completion date
        completed_date: Actual completion date
        estimated_hours: Estimated hours for completion
        actual_hours: Actual hours spent
        gitea_repo_url: Gitea repository URL if applicable
        notes: Additional notes about the project
        client: Relationship to Client model
    """

    __tablename__ = "projects"

    # Foreign keys
    client_id: Mapped[str] = mapped_column(
        String(36),
        ForeignKey("clients.id", ondelete="CASCADE"),
        nullable=False,
        doc="Foreign key to clients table"
    )

    # Project identification
    name: Mapped[str] = mapped_column(
        String(255),
        nullable=False,
        doc="Project name"
    )

    slug: Mapped[Optional[str]] = mapped_column(
        String(255),
        unique=True,
        doc="URL-safe slug (directory name like 'dataforth-dos')"
    )

    # Categorization
    category: Mapped[Optional[str]] = mapped_column(
        String(50),
        doc="Project category: client_project, internal_product, infrastructure, website, development_tool, documentation"
    )

    status: Mapped[str] = mapped_column(
        String(50),
        default="working",
        server_default="working",
        doc="Status: complete, working, blocked, pending, critical, deferred"
    )

    priority: Mapped[Optional[str]] = mapped_column(
        String(20),
        doc="Priority level: critical, high, medium, low"
    )

    # Description
    description: Mapped[Optional[str]] = mapped_column(
        Text,
        doc="Project description"
    )

    # Timeline
    started_date: Mapped[Optional[date]] = mapped_column(
        DATE,
        doc="Date project started"
    )

    target_completion_date: Mapped[Optional[date]] = mapped_column(
        DATE,
        doc="Target completion date"
    )

    completed_date: Mapped[Optional[date]] = mapped_column(
        DATE,
        doc="Actual completion date"
    )

    # Time tracking
    estimated_hours: Mapped[Optional[float]] = mapped_column(
        Numeric(10, 2),
        doc="Estimated hours for completion"
    )

    actual_hours: Mapped[Optional[float]] = mapped_column(
        Numeric(10, 2),
        doc="Actual hours spent"
    )

    # Repository
    gitea_repo_url: Mapped[Optional[str]] = mapped_column(
        String(500),
        doc="Gitea repository URL if applicable"
    )

    # Notes
    notes: Mapped[Optional[str]] = mapped_column(
        Text,
        doc="Additional notes about the project"
    )

    # Relationships
    client: Mapped["Client"] = relationship(
        "Client",
        back_populates="projects",
        doc="Relationship to Client model"
    )

    sessions: Mapped[list["Session"]] = relationship(
        "Session",
        back_populates="project",
        doc="Sessions associated with this project"
    )

    pending_tasks: Mapped[list["PendingTask"]] = relationship(
        "PendingTask",
        back_populates="project",
        doc="Pending tasks associated with this project"
    )

    # Indexes
    __table_args__ = (
        Index("idx_projects_client", "client_id"),
        Index("idx_projects_status", "status"),
        Index("idx_projects_slug", "slug"),
    )

    def __repr__(self) -> str:
        """String representation of the project."""
        return f"<Project(name='{self.name}', slug='{self.slug}', status='{self.status}')>"
