from datetime import datetime
from typing import Optional

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

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

# organization_group_table = Table('organization_group', Base.metadata,
#                                        Column('group_id', Integer, ForeignKey('group.id')),
#                                        Column('organization_id', String(36), ForeignKey('organization.id')))

# #构建对role表的关系
organization_role_table = Table('organization_role', Base.metadata,
                                   Column('role_id', String(36), ForeignKey('role.id', ondelete='CASCADE')),
                                   Column('organization_id', String(36), ForeignKey('organization.id', ondelete='CASCADE')))

class OrganizationModel(Base):
    __tablename__ = 'organization'
    id = Column(String(36), primary_key=True)
    created_at = Column(DateTime, default=datetime.now())
    updated_at = Column(DateTime, default=datetime.now(), onupdate=datetime.now())
    name = Column(String(200))
    address = Column(String(200))
    code = Column(String(200))
    iconcls = Column(String(255))
    seq = Column(Integer)
    leader = Column(String(255))
    phone = Column(String(32))
    email = Column(String(64))
    status = Column(String(10), nullable=False, default="1")

    # groups = relationship('GroupModel',
    #                             secondary=organization_group_table,
    #                             backref=backref('organizations', lazy='dynamic'))

    roles = relationship('RoleModel',
                            secondary=organization_role_table,
                            backref=backref('organizations', lazy='dynamic'))


    organization_id = Column(String(36), ForeignKey('organization.id'))

    parent = relationship('OrganizationModel', remote_side=[id], backref='childrens', uselist=False)

    children = relationship('OrganizationModel')

    def to_json(self):
        json = {
            'deptId': self.id,
            'createTime': self.created_at,
            'updateTime': self.updated_at,
            'deptName': self.name,
            'address': self.address,
            'code': self.code,
            'iconCls': self.iconcls,
            'orderNum': self.seq,
            'parentId': self.get_pid(),
            'parentName': self.get_pName(),
            'leader': self.leader,
            'phone': self.phone,
            'email': self.email,
            'status': self.status,
            'roles': [self.role_json(role) for role in self.roles],
            # 'groups': [self.group_json(group) for group in self.groups],
            'children': [
                org.to_json() for org in self.children if org.status != DEPT_STATUS_DELETE
            ]
        }

        return json

    def to_dict(self):
        json = {
            'deptId': self.id,
            'createTime': self.created_at,
            'updateTime': self.updated_at,
            'deptName': self.name,
            'address': self.address,
            'code': self.code,
            'iconCls': self.iconcls,
            'orderNum': self.seq,
            'parentId': self.get_pid(),
            'parentName': self.get_pName(),
            'leader': self.leader,
            'phone': self.phone,
            'email': self.email,
            'status': self.status,
            'roles': [self.role_json(role) for role in self.roles],
        }

        return json

    def to_base_json(self):
        json = {
            'deptId': self.id,
            'deptName': self.name,
            'address': self.address,
            'code': self.code,
            'iconCls': self.iconcls,
            'orderNum': self.seq,
            'leader': self.leader,
            'phone': self.phone,
            'email': self.email,
            'status': self.status
        }

        return json


    def role_json(self, role):
        return {
            'roleId': role.id,
            'roleName': role.name,
            'deptId': self.id,
        }

    def group_json(self, group):
        return {
            'groupId': group.id,
            'groupName': group.name,
            'deptId': self.id,
        }

    def to_tree_select_json(self):
        return {
            'id': self.id,
            'label': self.name,
            'children': [org.to_tree_select_json() for org in self.children]
        }

    def to_parent_select_json(self):
        return {
            'id': self.id,
            'label': self.name,
            'parent': [org.to_parent_select_json() for org in self.parent]
        }

    def get_pid(self):
        if self.parent:
            return self.parent.id
        return ''

    def get_pName(self):
        if self.parent:
            return self.parent.name
        return ''



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

    def __repr__(self):
        return '<Organization %r>\n' %(self.name)


class DeptList(BaseModel):
    deptName: Optional[str] = ""


class DeptInfo(BaseModel):
    deptId: Optional[str] = ""
    deptName: Optional[str] = ""
    leader: Optional[str] = ""
    phone: Optional[str] = ""
    orderNum: int
    address: Optional[str] = ""
    parentId: Optional[str] = ""
    status:  Optional[str|int] = ""
    roles: Optional[list] = []
    groups: Optional[list] = []


class DeptParent(BaseModel):
    deptId: str
    parentId: str
    orderNum: int


class DeptStatus(BaseModel):
    deptId: str
    status: str