from typing import Optional
from sqlalchemy.orm import Session
from mooc.crud.crud_base import CRUDBase
from mooc.models.uni_account import (
    UniAccount, UniAccountExtraModules, 
    UniAccountGroup, UniAccountMenus, 
    UniAccountModules,
    UniAccountModulesShortcut,
    UniAccountUsers,
    UniGroup,
    UniLinkUniacid,
    UniModules,
    UniVerifycode,
    UniSettings
)
from mooc.schemas.uni_account import (
    UniAccountCreate, UniAccountUpdate,
    UniAccountExtraModulesCreate, UniAccountExtraModulesUpdate,
    UniAccountGroupCreate, UniAccountGroupUpdate,
    UniAccountMenusCreate, UniAccountMenusUpdate,
    UniAccountModulesCreate, UniAccountModulesUpdate,
    UniAccountModulesShortcutCreate, UniAccountModulesShortcutUpdate,
    UniAccountUsersCreate, UniAccountUsersUpdate,
    UniGroupCreate, UniGroupUpdate,
    UniLinkUniacidCreate, UniLinkUniacidUpdate,
    UniModulesCreate, UniModulesUpdate,
    UniVerifycodeCreate, UniVerifycodeUpdate,
    UniSettingsCreate, UniSettingsUpdate
)

class CRUDUniAccount(CRUDBase[UniAccount, UniAccountCreate, UniAccountUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniAccount]:
        return self.get_by_field(db, "uniacid", uniacid)

class CRUDUniAccountExtraModules(CRUDBase[UniAccountExtraModules, UniAccountExtraModulesCreate, UniAccountExtraModulesUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniAccountExtraModules]:
        return self.get_by_field(db, "uniacid", uniacid)

class CRUDUniAccountGroup(CRUDBase[UniAccountGroup, UniAccountGroupCreate, UniAccountGroupUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniAccountGroup]:
        return self.get_by_field(db, "uniacid", uniacid)

class CRUDUniAccountMenus(CRUDBase[UniAccountMenus, UniAccountMenusCreate, UniAccountMenusUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniAccountMenus]:
        return self.get_by_field(db, "uniacid", uniacid)

class CRUDUniAccountModules(CRUDBase[UniAccountModules, UniAccountModulesCreate, UniAccountModulesUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniAccountModules]:
        return self.get_by_field(db, "uniacid", uniacid)

class CRUDUniAccountModulesShortcut(CRUDBase[UniAccountModulesShortcut, UniAccountModulesShortcutCreate, UniAccountModulesShortcutUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniAccountModulesShortcut]:
        return self.get_by_field(db, "uniacid", uniacid)

class CRUDUniAccountUsers(CRUDBase[UniAccountUsers, UniAccountUsersCreate, UniAccountUsersUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniAccountUsers]:
        return self.get_by_field(db, "uniacid", uniacid)

    def get_by_uid(self, db: Session, *, uid: int) -> Optional[UniAccountUsers]:
        return self.get_by_field(db, "uid", uid)

class CRUDUniGroup(CRUDBase[UniGroup, UniGroupCreate, UniGroupUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniGroup]:
        return self.get_by_field(db, "uniacid", uniacid)

    def get_by_owner(self, db: Session, *, owner_uid: int) -> Optional[UniGroup]:
        return self.get_by_field(db, "owner_uid", owner_uid)

class CRUDUniLinkUniacid(CRUDBase[UniLinkUniacid, UniLinkUniacidCreate, UniLinkUniacidUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniLinkUniacid]:
        return self.get_by_field(db, "uniacid", uniacid)

class CRUDUniModules(CRUDBase[UniModules, UniModulesCreate, UniModulesUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniModules]:
        return self.get_by_field(db, "uniacid", uniacid)

class CRUDUniVerifycode(CRUDBase[UniVerifycode, UniVerifycodeCreate, UniVerifycodeUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniVerifycode]:
        return self.get_by_field(db, "uniacid", uniacid)

    def get_by_receiver(self, db: Session, *, receiver: str) -> Optional[UniVerifycode]:
        return self.get_by_field(db, "receiver", receiver)

class CRUDUniSettings(CRUDBase[UniSettings, UniSettingsCreate, UniSettingsUpdate]):
    def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[UniSettings]:
        return db.query(self.model).filter(self.model.uniacid == uniacid).first()

    def create_with_uniacid(
        self, db: Session, *, obj_in: UniSettingsCreate
    ) -> UniSettings:
        """创建设置时使用uniacid作为主键"""
        db_obj = UniSettings(**obj_in.dict())
        db.add(db_obj)
        db.commit()
        db.refresh(db_obj)
        return db_obj

# 创建实例
uni_account = CRUDUniAccount(UniAccount)
uni_account_extra_modules = CRUDUniAccountExtraModules(UniAccountExtraModules)
uni_account_group = CRUDUniAccountGroup(UniAccountGroup)
uni_account_menus = CRUDUniAccountMenus(UniAccountMenus)
uni_account_modules = CRUDUniAccountModules(UniAccountModules)
uni_account_modules_shortcut = CRUDUniAccountModulesShortcut(UniAccountModulesShortcut)
uni_account_users = CRUDUniAccountUsers(UniAccountUsers)
uni_group = CRUDUniGroup(UniGroup)
uni_link_uniacid = CRUDUniLinkUniacid(UniLinkUniacid)
uni_modules = CRUDUniModules(UniModules)
uni_verifycode = CRUDUniVerifycode(UniVerifycode)
uni_settings = CRUDUniSettings(UniSettings)