from datetime import datetime
from typing import Optional

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

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

class ResourceModel(Base):
    __tablename__ = 'resource'
    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))
    url = Column(String(200))
    path = Column(String(200))
    perms = Column(String(150))
    description = Column(String(200))
    icon = Column(String(100))
    seq = Column(Integer)
    target = Column(String(100))
    canbdeeleted = Column(Integer)
    resource_type_id = Column(String(36), ForeignKey('resource_type.id'))
    resource_id = Column(String(36), ForeignKey('resource.id'))
    parent = relationship('ResourceModel', remote_side=[id], backref='resources', uselist=False)
    children = relationship('ResourceModel')
    status = Column(String(10), default="1")
    hidden = Column(Integer, default=0)
    def get_id(self):
        return str(self.ID)

    def to_json(self):
        return {
            'menuId': self.id,
            'createTime': self.created_at,
            'updateTime': self.updated_at,
            'menuName': self.name,
            'component': self.url,
            'description': self.description,
            'icon': self.icon,
            'orderNum': self.seq,
            'target': self.target,
            'parentId': self.get_pid(),
            'parentName': self.get_pName(),
            'syresourcetype': self.get_type_json(),
            'status': self.status,
            'path': self.path,
            'perms': self.perms,
            # 类型（0目录 1菜单 2按钮）
            'menuType': self.resource_type_id,
        }

    def to_tree_select_json(self):
        return {
            'menuId': self.id,
            'menuName': self.name,
            'menuType': self.resource_type_id,
            'parentId': self.get_pid(),
            'status': self.status,
            'parentName': self.get_pName(),
            'children': [res.to_tree_select_json() for res in self.children if res if res.status != RESOURCE_STATUS_DELETE]
        }

    def to_router_json(self):
        router = {
            'name': self.path.capitalize() if self.path else '',
            'path': self.path,
            'hidden': bool(self.hidden),
            'redirect': 'noRedirect',
            'component': self.url,
            'alwaysShow': True,
            'meta': {
                'title': self.name,
                'icon': self.icon,
                'noCache': False,
                'link': ''
            },
            'children': [
                res.to_router_json() for res in self.children if res.type.id == '3' or res.type.id == '0'
            ]
        }

        if not router['children']:
            del router['children']
            del router['redirect']
            del router['alwaysShow']
        if not router['component']:
            router['component'] = 'Layout'

        return router


    def to_router_dict(self):
        router = {
            'id': self.id,
            'name': self.path.capitalize() if self.path else '',
            # 'name': self.name,
            'path': self.path,
            'hidden': bool(self.hidden),
            'redirect': 'noRedirect',
            'component': self.url,
            'alwaysShow': True,
            'perms': self.perms,
            'resourceType': self.get_type_json(),
            'seq': self.seq,
            'meta': {
                'title': self.name,
                'icon': self.icon,
                'noCache': False,
                'link': ''
            },
            'parentId': self.get_pid(),
        }

        if not router['component']:
            router['component'] = 'Layout'
        return router


    def to_menu_json(self):
        return {
            'id': self.id,
            'iconCls': self.icon,
            'pid': self.get_pid(),
            'state': 'open',
            'checked': False,
            'attributes': {
                'target': self.target,
                'url': self.url
            },
            'text': self.name
        }

    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_type_json(self):
        if self.type:
            return self.type.to_json()
        return {}

    def __repr__(self):
        return '<ResourceModel name:%r url:%r>\n' % (self.NAME, self.URL)


class ResourceTypeModel(Base):
    __tablename__ = 'resource_type'
    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(128))
    description = Column(String(255))

    resources = relationship('ResourceModel', backref='type', lazy='dynamic')

    def to_json(self):
        return {
            'id': self.id,
            # 'createdatetime': self.created_at,
            # 'updatedatetime': self.updated_at,
            'name': self.name,
            'description': self.description
        }

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

class MenuInfo(BaseModel):
    menuId: Optional[str] = ""
    menuName: Optional[str] = ""
    component: Optional[str] = ""
    path: Optional[str] = ""
    orderNum: int
    perms: Optional[str] = ""
    menuType: Optional[str] = ""
    description: Optional[str] = ""
    icon: Optional[str] = ""
    parentId: str
    status: str
    # roles: list
    # groups: Optional[list] = []


class MenuStatus(BaseModel):
    menuId: str
    status: str