from sqlalchemy import Boolean, Column, Integer, String, DateTime,ForeignKey,Table
from sqlalchemy.orm import Mapped,relationship,as_declarative,mapped_column
from datetime import datetime,timezone
from app.db  import Base
from app.core.security import chacha20Decrypt

@as_declarative()
class Base:
    id = Column(Integer, primary_key=True, index=True)
    create_time = Column(DateTime, default=datetime.now(timezone.utc))
    update_time = Column(DateTime, default=datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))


userrole = Table(
    "userrole",
    Base.metadata,
    Column("userid",Integer,ForeignKey("user.id")),
    Column("roleid",Integer,ForeignKey("role.id")),
)

rolepermission = Table(
    "rolepermission",
    Base.metadata,
    Column("roleid",Integer,ForeignKey("role.id")),
    Column("permissionid",Integer,ForeignKey("permission.id")),
)

class User(Base):
    __tablename__ = "user"

    email = mapped_column(String(50), unique=True, index=True, nullable=False)
    first_name = mapped_column(String(100))
    last_name = mapped_column(String(100))
    hashed_password = mapped_column(String(200), nullable=False)
    is_active = mapped_column(Boolean, default=True)
    is_superuser = mapped_column(Boolean, default=False)
    tenantid = mapped_column(String(100))
    createuserid = mapped_column(Integer,ForeignKey("user.id"))
    updateuserid = mapped_column(Integer,ForeignKey("user.id"))
    createuser = relationship('User',foreign_keys=[createuserid]) 
    updateuser = relationship('User',foreign_keys=[updateuserid]) 
    roles = relationship("Role",secondary=userrole,back_populates="users")


class Role(Base):
    __tablename__ = "role"

    name = mapped_column(String(100))
    description = mapped_column(String(255))
    level = mapped_column(Integer)
    users = relationship("User",secondary=userrole,back_populates="roles")
    permissions = relationship("Permission",secondary=rolepermission,back_populates="roles")

class Permission(Base):
    __tablename__ = "permission"

    menu = mapped_column(String(100))
    function = mapped_column(String(255))
    link = mapped_column(String(100))
    privilege = mapped_column(String(100))
    roles = relationship("Role",secondary=rolepermission,back_populates="permissions")


class App(Base):
    __tablename__ = "app"

    domainurl = mapped_column(String(200), nullable=False) 
    appname = mapped_column(String(200), nullable=False)
    appid = mapped_column(String(100), index=True, nullable=False)
    version = mapped_column(Integer)
    versionname = mapped_column(String(200), nullable=False)
    is_saved = mapped_column(Boolean, default=False)
    createuserid = mapped_column(Integer,ForeignKey("user.id"))
    updateuserid = mapped_column(Integer,ForeignKey("user.id"))
    createuser = relationship('User',foreign_keys=[createuserid]) 
    updateuser = relationship('User',foreign_keys=[updateuserid]) 

class AppVersion(Base):
    __tablename__ = "appversion"

    domainurl = mapped_column(String(200), nullable=False) 
    appname = mapped_column(String(200), nullable=False)
    appid = mapped_column(String(100), index=True, nullable=False)
    version = mapped_column(Integer)
    versionname = mapped_column(String(200), nullable=False)
    comment = mapped_column(String(200), nullable=False)
    createuserid = mapped_column(Integer,ForeignKey("user.id"))
    updateuserid = mapped_column(Integer,ForeignKey("user.id"))
    createuser = relationship('User',foreign_keys=[createuserid]) 
    updateuser = relationship('User',foreign_keys=[updateuserid]) 



class AppSetting(Base):
    __tablename__ = "appsetting"

    appid = mapped_column(String(100), index=True, nullable=False)
    setting = mapped_column(String(1000))   

class Kintone(Base):
    __tablename__ = "kintone"

    type = mapped_column(Integer, index=True, nullable=False)
    name = mapped_column(String(100), nullable=False)   
    desc = mapped_column(String)
    content = mapped_column(String)

class Action(Base):
    __tablename__ = "action"

    name = mapped_column(String(100), index=True, nullable=False)
    title = mapped_column(String(200))   
    subtitle = mapped_column(String(500))   
    outputpoints = mapped_column(String)
    property =  mapped_column(String)
    categoryid = mapped_column(Integer,ForeignKey("category.id"))
    nosort = mapped_column(Integer)

class Flow(Base):
    __tablename__ = "flow"

    flowid = mapped_column(String(100), index=True, nullable=False)
    appid = mapped_column(String(100), index=True, nullable=False)
    eventid = mapped_column(String(100), index=True, nullable=False)
    domainurl = mapped_column(String(200)) 
    name = mapped_column(String(200))   
    content = mapped_column(String) 
    createuserid = mapped_column(Integer,ForeignKey("user.id"))
    updateuserid = mapped_column(Integer,ForeignKey("user.id"))
    createuser = relationship('User',foreign_keys=[createuserid]) 
    updateuser = relationship('User',foreign_keys=[updateuserid]) 

class FlowHistory(Base):
    __tablename__ = "flowhistory"

    flowid = mapped_column(String(100), index=True, nullable=False)
    appid = mapped_column(String(100), index=True, nullable=False)
    eventid = mapped_column(String(100), index=True, nullable=False)
    domainurl = mapped_column(String(200)) 
    name = mapped_column(String(200))   
    content = mapped_column(String)  
    version = mapped_column(Integer)
    createuserid = mapped_column(Integer,ForeignKey("user.id"))
    updateuserid = mapped_column(Integer,ForeignKey("user.id"))
    createuser = relationship('User',foreign_keys=[createuserid]) 
    updateuser = relationship('User',foreign_keys=[updateuserid]) 

class Tenant(Base):
    __tablename__ = "tenant"

    tenantid =  mapped_column(String(100), index=True, nullable=False)
    name = mapped_column(String(200)) 
    licence  = mapped_column(String(200)) 
    startdate = mapped_column(DateTime)
    enddate = mapped_column(DateTime) 
    db = mapped_column(String(200))


class Domain(Base):
    __tablename__ = "domain"

    tenantid =  mapped_column(String(100), index=True, nullable=False)
    name = mapped_column(String(100), nullable=False)   
    url = mapped_column(String(200), nullable=False)
    kintoneuser = mapped_column(String(100), nullable=False)
    kintonepwd = mapped_column(String(100), nullable=False)
    is_active = mapped_column(Boolean, default=True)
    def decrypt_kintonepwd(self):
        decrypted_pwd = chacha20Decrypt(self.kintonepwd)
        return decrypted_pwd
    createuserid = mapped_column(Integer,ForeignKey("user.id"))
    updateuserid = mapped_column(Integer,ForeignKey("user.id"))
    ownerid = mapped_column(Integer,ForeignKey("user.id"))
    createuser = relationship('User',foreign_keys=[createuserid]) 
    updateuser = relationship('User',foreign_keys=[updateuserid]) 
    owner = relationship('User',foreign_keys=[ownerid]) 


class UserDomain(Base):
    __tablename__ = "userdomain"

    userid = mapped_column(Integer,ForeignKey("user.id"))
    domainid = mapped_column(Integer,ForeignKey("domain.id"))
    is_default = mapped_column(Boolean, default=False)
    createuserid = mapped_column(Integer,ForeignKey("user.id"))
    updateuserid = mapped_column(Integer,ForeignKey("user.id"))
    domain = relationship("Domain")
    user = relationship("User",foreign_keys=[userid])
    createuser = relationship('User',foreign_keys=[createuserid]) 
    updateuser = relationship('User',foreign_keys=[updateuserid]) 

class ManageDomain(Base):
    __tablename__ = "managedomain"

    userid = mapped_column(Integer,ForeignKey("user.id"))
    domainid = mapped_column(Integer,ForeignKey("domain.id"))
    createuserid = mapped_column(Integer,ForeignKey("user.id"))
    updateuserid = mapped_column(Integer,ForeignKey("user.id"))
    domain = relationship("Domain")
    user = relationship("User",foreign_keys=[userid])
    createuser = relationship('User',foreign_keys=[createuserid]) 
    updateuser = relationship('User',foreign_keys=[updateuserid]) 

class Event(Base):
    __tablename__ = "event"

    category = mapped_column(String(100), nullable=False)
    type = mapped_column(String(100), nullable=False)
    eventid= mapped_column(String(100), nullable=False)
    function = mapped_column(String(500), nullable=False)   
    mobile = mapped_column(Boolean, default=False)
    eventgroup = mapped_column(Boolean, default=False)

class EventAction(Base):
    __tablename__ = "eventaction"

    eventid = mapped_column(String(100),ForeignKey("event.eventid"))
    actionid = mapped_column(Integer,ForeignKey("action.id"))


class ErrorLog(Base):
       __tablename__ = "errorlog"

       title = mapped_column(String(50))
       location = mapped_column(String(500))
       content = mapped_column(String(5000))

class OperationLog(Base):
       __tablename__ = "operationlog"

       tenantid =  mapped_column(String(100))
       clientip = mapped_column(String(200))
       useragent = mapped_column(String(200))
       userid = mapped_column(Integer,ForeignKey("user.id"))
       operation = mapped_column(String(200))
       function = mapped_column(String(200))
       parameters = mapped_column(String)
       response = mapped_column(String(200))
       user = relationship('User')

class KintoneFormat(Base):
      __tablename__ = "kintoneformat"

      name = mapped_column(String(50))
      startrow =mapped_column(Integer)
      startcolumn =mapped_column(Integer)
      typecolumn =mapped_column(Integer)
      codecolumn =mapped_column(Integer)
      field = mapped_column(String(5000))
      trueformat = mapped_column(String(10))

class Category(Base):
    __tablename__ = "category"

    categoryname = mapped_column(String(20))
    nosort = mapped_column(Integer)