from .base import BaseModel, TimestampedModelMixin
from sqlalchemy import (
    Column,
    ForeignKey,
    types,
)
from sqlalchemy.orm import relationship, backref

from watcher import enums


class Interval(TimestampedModelMixin, BaseModel):
    __tablename__ = 'interval'

    id = Column(types.Integer, primary_key=True, index=True)
    name = Column(types.String)
    schedule_id = Column(types.Integer, ForeignKey('schedule.id', ondelete='CASCADE'), nullable=False)
    schedule = relationship('Schedule', backref=backref('intervals', remote_side=[schedule_id], cascade='all,delete'))

    # непосредственные настройки
    duration = Column(types.Interval, nullable=False, info={'verbose_name': 'Длительность интервала'},)
    type_employment = Column(
        types.Enum(enums.IntervalTypeEmployment),
        nullable=False,
        default=enums.IntervalTypeEmployment.full,
        info={
            'verbose_name': 'Тип занятости в интервале'
        },
    )
    unexpected_holidays = Column(
        types.Enum(enums.IntervalUnexpectedHolidays),
        nullable=False,
        default=enums.IntervalUnexpectedHolidays.ignoring,
        info={
            'verbose_name': 'Поведение интервала во время внезапных праздников'
        },
    )
    weekend_behaviour = Column(
        types.Enum(enums.IntervalWeekendsBehaviour),
        nullable=False,
        default=enums.IntervalWeekendsBehaviour.ignoring,
        info={
            'verbose_name': 'Поведение интервала во время субботы и воскресенья'
        },
    )
    revision_id = Column(types.Integer, ForeignKey('revision.id', ondelete="CASCADE"), nullable=False)
    revision = relationship(
        'Revision',
        backref=backref(
            'intervals',
            remote_side=revision_id,
            cascade='all, delete',
            order_by='Interval.order'
        )
    )
    primary_rotation = Column(types.Boolean, default=False)
    backup_takes_primary_shift = Column(types.Boolean, default=False)

    # технические поля
    order = Column(types.Integer, nullable=False, info={'verbose_name': 'Порядок интервала внутри графика'},)


class Revision(TimestampedModelMixin, BaseModel):
    __tablename__ = 'revision'

    id = Column(types.Integer, primary_key=True, index=True)
    schedule_id = Column(types.Integer, ForeignKey('schedule.id', ondelete='CASCADE'), nullable=False, )
    schedule = relationship('Schedule')
    apply_datetime = Column(types.DateTime(timezone=True), nullable=False,)
    state = Column(
        types.Enum(enums.RevisionState),
        nullable=False,
        default=enums.RevisionState.active,
    )

    # технические поля
    next_id = Column(
        types.Integer,
        ForeignKey('revision.id'),
        nullable=True,
        info={
            'verbose_name': 'Следующая ревизия внутри графика',
        }
    )
    next = relationship(
        'Revision',
        uselist=False,
        foreign_keys=[next_id],
        backref=backref('prev', uselist=False),
        remote_side=[id]
    )
