from utils.db_connect import BaseModelForTable
from sqlalchemy import (
    Column,
    Integer,
    String,
    Text,
    ForeignKey,
    Enum as SQLEnum,
    Date,
    UUID
)
from sqlalchemy.dialects.postgresql import ARRAY

from sqlalchemy.orm import relationship
from enum import Enum


# Ticket Type
class TicketType(str, Enum):
    BUG = "BUG"
    FEATURE = "FEATURE"
    TASK = "TASK"
    STORY = "STORY"


# Ticket Status
class TicketStatus(str, Enum):
    BACKLOG = "BACKLOG"
    TODO = "TODO"
    IN_PROGRESS = "IN_PROGRESS"
    IN_REVIEW = "IN_REVIEW"
    DONE = "DONE"


# Priority
class TicketPriority(str, Enum):
    CRITICAL = "CRITICAL"
    HIGH = "HIGH"
    MEDIUM = "MEDIUM"
    LOW = "LOW"


# Environment
class EnvironmentType(str, Enum):
    DEV = "DEV"
    STAGING = "STAGING"
    PRODUCTION = "PRODUCTION"


# Deployment Status
class DeploymentStatus(str, Enum):
    NOT_DEPLOYED = "NOT_DEPLOYED"
    IN_PROGRESS = "IN_PROGRESS"
    DEPLOYED = "DEPLOYED"
    FAILED = "FAILED"


class Ticket(BaseModelForTable):
    __tablename__ = "tickets"

    # Relations
    project_id = Column(
        UUID(as_uuid=True),
        ForeignKey("projects.id"),
        nullable=False
    )

    parent_ticket_id = Column(
        UUID(as_uuid=True),
        ForeignKey("tickets.id"),
        nullable=True
    )

    assignee_ids = Column(
        ARRAY(UUID(as_uuid=True)),
        nullable=True
    )

    reporter_id = Column(
        UUID(as_uuid=True),
        ForeignKey("users.id"),
        nullable=False
    )

    # Basic Details
    ticket_number = Column(
        String(100),
        nullable=False
    )

    title = Column(
        String(255),
        nullable=False
    )

    description = Column(
        Text,
        nullable=True
    )

    # Ticket Meta
    type = Column(
        SQLEnum(TicketType),
        nullable=False
    )

    status = Column(
        String(50),
        default="BACKLOG",
        nullable=False
    )

    priority = Column(
        SQLEnum(TicketPriority),
        default=TicketPriority.MEDIUM,
        nullable=False
    )

    story_points = Column(
        Integer,
        nullable=True
    )

    due_date = Column(
        Date,
        nullable=True
    )

    # Deployment
    environment = Column(
        SQLEnum(EnvironmentType),
        nullable=True
    )

    deployment_status = Column(
        SQLEnum(DeploymentStatus),
        default=DeploymentStatus.NOT_DEPLOYED,
        nullable=False
    )

    deployment_url = Column(
        String(500),
        nullable=True
    )

    deployment_notes = Column(
        Text,
        nullable=True
    )

    @property
    def assignee_id(self):
        if self.assignee_ids and len(self.assignee_ids) > 0:
            return self.assignee_ids[0]
        return None

    @assignee_id.setter
    def assignee_id(self, value):
        if value:
            self.assignee_ids = [value]
        else:
            self.assignee_ids = []

    # Relationships
    project = relationship(
        "Project",
        back_populates="tickets"
    )

    reporter = relationship(
        "User",
        foreign_keys=[reporter_id],
        back_populates="reported_tickets"
    )


    parent_ticket = relationship(
        "Ticket",
        remote_side="Ticket.id",
        backref="sub_tickets"
    )


    ticket_labels = relationship(
        "TicketLabel",
        back_populates="ticket",
        cascade="all, delete-orphan"
    )

    ticket_releases = relationship(
        "TicketRelease",
        back_populates="ticket",
        cascade="all, delete-orphan"
    )

    releases = relationship(
        "Release",
        secondary="ticket_releases",
        viewonly=True
    )

    comments = relationship(
        "Comment",
        back_populates="ticket",
        cascade="all, delete-orphan"
    )

    activity_logs = relationship(
        "ActivityLog",
        back_populates="ticket",
        cascade="all, delete-orphan"
    )