"""Introduce concepts

Revision ID: feffd3c5b806
Revises: a7c43f3fbc76
Create Date: 2023-12-08 12:33:32.190952

"""

from alembic import op
import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.ext.declarative import declarative_base
from zou.migrations.utils.base import BaseMixin
from sqlalchemy_utils import UUIDType
from sqlalchemy.sql import expression


# revision identifiers, used by Alembic.
revision = "feffd3c5b806"
down_revision = "5b9fd9ddfe43"
branch_labels = None
depends_on = None

base = declarative_base()


class TaskStatus(base, BaseMixin):
    """
    Describe the state of a task. A status marked as reviewable expects a
    preview file linked to relate comment.
    """

    __tablename__ = "task_status"
    name = sa.Column(sa.String(40), nullable=False)
    archived = sa.Column(sa.Boolean(), default=False)
    short_name = sa.Column(
        sa.String(10), unique=True, nullable=False, index=True
    )
    color = sa.Column(sa.String(7), nullable=False)

    is_done = sa.Column(sa.Boolean(), default=False, index=True)
    is_artist_allowed = sa.Column(sa.Boolean(), default=True)
    is_client_allowed = sa.Column(sa.Boolean(), default=True)
    is_retake = sa.Column(sa.Boolean(), default=False)
    is_feedback_request = sa.Column(sa.Boolean(), default=False, index=True)
    is_default = sa.Column(sa.Boolean(), default=False, index=True)
    shotgun_id = sa.Column(sa.Integer)
    for_concept = sa.Column(
        sa.Boolean(), server_default=expression.false(), default=False
    )


class TaskType(base, BaseMixin):
    """
    Categorize tasks in domain areas: modeling, animation, etc.
    """

    __tablename__ = "task_type"
    name = sa.Column(sa.String(40), nullable=False)
    short_name = sa.Column(sa.String(20))
    color = sa.Column(sa.String(7), default="#FFFFFF")
    priority = sa.Column(sa.Integer, default=1)
    for_entity = sa.Column(sa.String(30), default="Asset")
    allow_timelog = sa.Column(sa.Boolean, default=True)
    archived = sa.Column(sa.Boolean(), default=False)
    shotgun_id = sa.Column(sa.Integer, index=True)

    department_id = sa.Column(
        UUIDType(binary=False), sa.ForeignKey("department.id"), index=True
    )

    __table_args__ = (
        sa.UniqueConstraint(
            "name", "for_entity", "department_id", name="task_type_uc"
        ),
    )


class Department(base, BaseMixin):
    """
    Studio department like modeling, animation, etc.
    """

    __tablename__ = "department"
    name = sa.Column(sa.String(80), unique=True, nullable=False)
    color = sa.Column(sa.String(7), nullable=False)
    archived = sa.Column(sa.Boolean(), default=False)


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table("task_status", schema=None) as batch_op:
        batch_op.add_column(
            sa.Column(
                "for_concept",
                sa.Boolean(),
                server_default=sa.text("false"),
                nullable=True,
            )
        )

    bind = op.get_bind()
    session = orm.Session(bind=bind)
    neutral_status = TaskStatus(
        name="Neutral",
        short_name="neutral",
        color="#CCCCCC",
        is_default=True,
        for_concept=True,
        is_artist_allowed=False,
        is_client_allowed=False,
    )
    approved_status = TaskStatus(
        name="Approved",
        short_name="approved",
        color="#66BB6A",
        for_concept=True,
        is_artist_allowed=False,
        is_client_allowed=False,
    )
    rejected_status = TaskStatus(
        name="Rejected",
        short_name="rejected",
        color="#E81123",
        for_concept=True,
        is_artist_allowed=False,
        is_client_allowed=False,
    )
    session.merge(neutral_status)
    session.merge(approved_status)
    session.merge(rejected_status)

    concept_department = (
        session.query(Department).filter_by(name="Concept").one_or_none()
    )

    task_type_concept = TaskType(
        name="Concept",
        color="#8D6E63",
        short_name="",
        department_id=(
            concept_department.id if concept_department is not None else None
        ),
        for_entity="Concept",
    )
    session.merge(task_type_concept)
    session.commit()

    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    bind = op.get_bind()
    session = orm.Session(bind=bind)
    session.query(TaskStatus).filter_by(for_concept=True).delete()
    session.query(TaskType).filter_by(for_entity="Concept").delete()
    session.commit()
    with op.batch_alter_table("task_status", schema=None) as batch_op:
        batch_op.drop_column("for_concept")

    # ### end Alembic commands ###
