from datetime import datetime
from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, Float, Enum as SAEnum
from sqlalchemy.orm import relationship
import enum

from app.core.database import Base


class ProjectStatus(str, enum.Enum):
    CREATED = "created"
    SCANNING = "scanning"
    ASSIGNING = "assigning"
    LABELING = "labeling"
    REVIEWING = "reviewing"
    ACCEPTING = "accepting"
    PUBLISHED = "published"


class TaskStatus(str, enum.Enum):
    PENDING = "pending"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    REJECTED = "rejected"


class ResultStatus(str, enum.Enum):
    AUTO = "auto"
    MANUAL = "manual"
    REVIEWED = "reviewed"
    PUBLISHED = "published"
    CONFLICT = "conflict"


class ClassificationProject(Base):
    __tablename__ = "classification_project"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(200), nullable=False)
    template_id = Column(Integer, ForeignKey("classification_template.id"))
    description = Column(Text)
    status = Column(String(20), default=ProjectStatus.CREATED.value)
    target_source_ids = Column(Text)  # comma separated source ids
    target_database_ids = Column(Text)
    target_table_ids = Column(Text)
    planned_start = Column(DateTime)
    planned_end = Column(DateTime)
    created_by = Column(Integer, ForeignKey("sys_user.id"), nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    # Async classification tracking
    celery_task_id = Column(String(100), nullable=True)
    scan_progress = Column(Text, nullable=True)  # JSON: {"scanned": 0, "matched": 0, "total": 0}

    template = relationship("ClassificationTemplate")
    tasks = relationship("ClassificationTask", back_populates="project", cascade="all, delete-orphan")
    results = relationship("ClassificationResult", back_populates="project", cascade="all, delete-orphan")


class ClassificationTask(Base):
    __tablename__ = "classification_task"

    id = Column(Integer, primary_key=True, index=True)
    project_id = Column(Integer, ForeignKey("classification_project.id"), nullable=False)
    name = Column(String(200))
    assigner_id = Column(Integer, ForeignKey("sys_user.id"))
    assignee_id = Column(Integer, ForeignKey("sys_user.id"))
    target_type = Column(String(20), default="table")  # table, column, file
    target_ids = Column(Text)  # comma separated ids
    status = Column(String(20), default=TaskStatus.PENDING.value)
    deadline = Column(DateTime)
    completed_at = Column(DateTime)
    created_at = Column(DateTime, default=datetime.utcnow)

    project = relationship("ClassificationProject", back_populates="tasks")
    assigner = relationship("User", foreign_keys=[assigner_id])
    assignee = relationship("User", foreign_keys=[assignee_id])


class ClassificationResult(Base):
    __tablename__ = "classification_result"

    id = Column(Integer, primary_key=True, index=True)
    project_id = Column(Integer, ForeignKey("classification_project.id"), nullable=False)
    column_id = Column(Integer, ForeignKey("meta_column.id"), nullable=True)
    file_id = Column(Integer, ForeignKey("unstructured_file.id"), nullable=True)
    category_id = Column(Integer, ForeignKey("category.id"))
    level_id = Column(Integer, ForeignKey("data_level.id"))
    source = Column(String(20), default="auto")  # auto, manual, ml
    confidence = Column(Float, default=0.0)  # 0-1
    labeler_id = Column(Integer, ForeignKey("sys_user.id"))
    reviewer_id = Column(Integer, ForeignKey("sys_user.id"))
    status = Column(String(20), default=ResultStatus.AUTO.value)
    label_time = Column(DateTime)
    review_time = Column(DateTime)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    project = relationship("ClassificationProject", back_populates="results")
    column = relationship("DataColumn")
    category = relationship("Category")
    level = relationship("DataLevel")


class ClassificationChange(Base):
    __tablename__ = "classification_change"

    id = Column(Integer, primary_key=True, index=True)
    result_id = Column(Integer, ForeignKey("classification_result.id"), nullable=False)
    change_type = Column(String(20), nullable=False)  # category, level, both
    old_category_id = Column(Integer, ForeignKey("category.id"))
    new_category_id = Column(Integer, ForeignKey("category.id"))
    old_level_id = Column(Integer, ForeignKey("data_level.id"))
    new_level_id = Column(Integer, ForeignKey("data_level.id"))
    reason = Column(Text)
    applicant_id = Column(Integer, ForeignKey("sys_user.id"))
    approver_id = Column(Integer, ForeignKey("sys_user.id"))
    approval_status = Column(String(20), default="pending")  # pending, approved, rejected
    approval_comment = Column(Text)
    created_at = Column(DateTime, default=datetime.utcnow)
