from enum import Enum
from sqlalchemy import Column, ForeignKey, Enum as SQLAEnum
from sqlalchemy.orm import relationship
from sqlalchemy.types import BigInteger
from sqlalchemy.schema import Sequence
from sqlalchemy.dialects.postgresql import UUID

from atst.models import Base, mixins
from atst.models.types import Id


class RequestStatus(Enum):
    STARTED = "Started"
    SUBMITTED = "Submitted"
    PENDING_FINANCIAL_VERIFICATION = "Pending Financial Verification"
    PENDING_CCPO_ACCEPTANCE = "Pending CCPO Acceptance"
    PENDING_CCPO_APPROVAL = "Pending CCPO Approval"
    CHANGES_REQUESTED = "Changes Requested"
    CHANGES_REQUESTED_TO_FINVER = "Change Requested to Financial Verification"
    APPROVED = "Approved"
    EXPIRED = "Expired"
    DELETED = "Deleted"


class RequestStatusEvent(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
    __tablename__ = "request_status_events"

    id = Id()
    new_status = Column(SQLAEnum(RequestStatus, native_enum=False))
    request_id = Column(
        UUID(as_uuid=True),
        ForeignKey("requests.id", ondelete="CASCADE"),
        nullable=False,
    )
    sequence = Column(
        BigInteger, Sequence("request_status_events_sequence_seq"), nullable=False
    )
    request_revision_id = Column(ForeignKey("request_revisions.id"), nullable=False)
    revision = relationship("RequestRevision")

    request_review_id = Column(ForeignKey("request_reviews.id"), nullable=True)
    review = relationship("RequestReview", back_populates="status")

    @property
    def displayname(self):
        return self.new_status.value

    @property
    def log_name(self):
        if self.new_status == RequestStatus.CHANGES_REQUESTED:
            return "Denied"
        if self.new_status == RequestStatus.CHANGES_REQUESTED_TO_FINVER:
            return "Denied"
        elif self.new_status == RequestStatus.PENDING_FINANCIAL_VERIFICATION:
            return "Accepted"
        else:
            return self.displayname

    def __repr__(self):
        return "<RequestStatusEvent(log_name='{}', request='{}', id='{}')>".format(
            self.log_name, self.request_id, self.id
        )
