from datetime import datetime
from typing import Optional

from pydantic import BaseModel, constr
from sqlalchemy import Column, Integer, String, DateTime, Table, ForeignKey
from sqlalchemy.orm import relationship, backref

from app.config.const import RESOURCE_STATUS_DELETE, DEPT_STATUS_DELETE
from app.models.base_model import Base

# 角色资源关联表
role_resource_table = Table('role_resource', Base.metadata,
                            Column('role_id', String(36), ForeignKey('role.id', ondelete='CASCADE')),
                            Column('resource_id', String(36), ForeignKey('resource.id', ondelete='CASCADE')))



class RoleModel(Base):
    __tablename__ = 'role'
    id = Column(String(36), primary_key=True, index=True)
    created_at = Column(DateTime, default=datetime.now())
    updated_at = Column(DateTime, default=datetime.now(), onupdate=datetime.now())
    name = Column(String(128), unique=True, nullable=False, index=True)
    description = Column(String(255))
    iconCls = Column(String(100))
    seq = Column(Integer)
    roleKey = Column(String(100))
    dataScope = Column(Integer)
    status = Column(String(10), default="1")
    creator = Column(Integer)
    role_type = Column(Integer, default=1)

    # 包含资源
    resources = relationship('ResourceModel',
                             secondary=role_resource_table,
                             backref=backref('roles', lazy='dynamic'))  # 资源所属角色

    def get_id(self):
        return str(self.id)

    def to_dict(self):
        return dict([(k, getattr(self, k)) for k in self.__dict__.keys() if not k.startswith("_")])

    def __repr__(self):
        return '<Role name:%r description:%r iconCls:%r seq:%r>\n' \
            % (self.NAME, self.DESCRIPTION, self.ICONCLS, self.SEQ)

    def to_json(self):
        json = {
            'roleId': self.id,
            'createTime': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'updateTime': self.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
            'roleName': self.name,
            'remark': self.description,
            'iconCls': self.iconCls,
            'roleSort': self.seq,
            'status': self.status,
            'roleKey': self.roleKey,
            'dataScope': self.dataScope
        }

        # if len(self.resources) > 0:
        json['resources'] = [resource.to_json() for resource in self.resources if resource.status != DEPT_STATUS_DELETE]

        json['dept'] = [dept.to_base_json() for dept in self.organizations if dept.status != RESOURCE_STATUS_DELETE]

        return json


    def to_dict(self):
        json = {
            'roleId': self.id,
            'createTime': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'updateTime': self.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
            'roleName': self.name,
            'remark': self.description,
            'iconCls': self.iconCls,
            'roleSort': self.seq,
            'status': self.status,
            'roleKey': self.roleKey,
            'dataScope': self.dataScope
        }
        return json

class RoleData(BaseModel):
    remark: Optional[str] = ""
    roleName: str
    roleKey: Optional[str] = ""
    dataScope: Optional[int] = 0


class RoleStatus(BaseModel):
    roleId: str
    status: constr(min_length=1, max_length=1, pattern='^(0|1)$')


class RoleEdit(BaseModel):
    roleId: str
    remark: Optional[str] = ""
    roleName: Optional[str] = ""
    resources: Optional[list] = []
    roleKey: Optional[str] = ""
    dataScope: Optional[int] = 0
    editType: int
    depts: Optional[list] = []
