from datetime import datetime
from typing import Optional
import uuid

from sqlalchemy import Column, String, Integer, DateTime, Text, JSON, ForeignKey, Boolean
from sqlalchemy.orm import DeclarativeBase, relationship


class Base(DeclarativeBase):
    pass


class Project(Base):
    __tablename__ = "projects"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    name = Column(String(255), nullable=False)
    repo_path = Column(String(1024), nullable=False)
    description = Column(Text, default="")
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    tasks = relationship("Task", back_populates="project")


class Task(Base):
    __tablename__ = "tasks"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    project_id = Column(String(36), ForeignKey("projects.id"), nullable=True)
    user_request = Column(Text, nullable=False)
    repo_path = Column(String(1024), nullable=False)
    sandbox_path = Column(String(1024), default="")
    selected_executor = Column(String(50), default="claude")
    graph_type = Column(String(50), default="engineering")  # engineering | bugfix | review | release
    status = Column(String(50), default="pending")
    attempts = Column(Integer, default=0)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    completed_at = Column(DateTime, nullable=True)

    project = relationship("Project", back_populates="tasks")
    executions = relationship("Execution", back_populates="task")
    report = relationship("Report", back_populates="task", uselist=False)


class Execution(Base):
    __tablename__ = "executions"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    task_id = Column(String(36), ForeignKey("tasks.id"), nullable=False)
    agent = Column(String(50), nullable=False)  # supervisor | architect | developer | tester | reviewer
    executor = Column(String(50), default="")
    status = Column(String(50), default="pending")
    input_data = Column(JSON, default=dict)
    output_data = Column(JSON, default=dict)
    error = Column(Text, default="")
    started_at = Column(DateTime, default=datetime.utcnow)
    finished_at = Column(DateTime, nullable=True)
    duration_seconds = Column(Integer, default=0)

    task = relationship("Task", back_populates="executions")


class Report(Base):
    __tablename__ = "reports"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    task_id = Column(String(36), ForeignKey("tasks.id"), nullable=False, unique=True)
    content = Column(Text, default="")
    pr_description = Column(Text, default="")
    diff_summary = Column(JSON, default=dict)
    test_summary = Column(JSON, default=dict)
    review_summary = Column(JSON, default=dict)
    created_at = Column(DateTime, default=datetime.utcnow)

    task = relationship("Task", back_populates="report")
