import uuid
from datetime import datetime
from typing import Optional

from sqlalchemy import Column
from sqlalchemy.dialects.postgresql import JSON
from sqlmodel import Field, Relationship

from api.db.models.base import BaseModel, BaseTable


class OutOfBandBase(BaseModel):
    msg_type: str = Field(nullable=False)
    msg: dict = Field(default={}, sa_column=Column(JSON))
    sender_id: uuid.UUID = None
    recipient_id: uuid.UUID = None
    sandbox_id: uuid.UUID = None
    action: Optional[str] = Field(nullable=True)


class OutOfBand(OutOfBandBase, BaseTable, table=True):
    __tablename__ = "out_of_band"

    # optional else, required on save
    sender_id: uuid.UUID = Field(foreign_key="line_of_business.id")
    recipient_id: uuid.UUID = Field(foreign_key="line_of_business.id")
    sandbox_id: uuid.UUID = Field(foreign_key="sandbox.id")

    # relationships
    sender: Optional["Lob"] = Relationship(  # noqa: F821
        sa_relationship_kwargs={
            "primaryjoin": "OutOfBand.sender_id==Lob.id",
            "lazy": "joined",
        }
    )
    recipient: Optional["Lob"] = Relationship(  # noqa: F821
        sa_relationship_kwargs={
            "primaryjoin": "OutOfBand.recipient_id==Lob.id",
            "lazy": "joined",
        }
    )

    class Config:
        arbitrary_types_allowed = True


class OutOfBandCreate(OutOfBandBase):
    pass


class OutOfBandRead(OutOfBandBase):
    id: uuid.UUID
    created_at: datetime
    updated_at: datetime


class OutOfBandUpdate(BaseModel):
    id: uuid.UUID
    name: Optional[str] = None
    action: Optional[str] = None

sqlmodel.Relationship sqlalchemy.Column sqlmodel.Field
[((297, 318), 'sqlmodel.Field', 'Field', ([], {'nullable': '(False)'}), '(nullable=False)\n', (302, 318), False, 'from sqlmodel import Field, Relationship\n'), ((505, 525), 'sqlmodel.Field', 'Field', ([], {'nullable': '(True)'}), '(nullable=True)\n', (510, 525), False, 'from sqlmodel import Field, Relationship\n'), ((683, 723), 'sqlmodel.Field', 'Field', ([], {'foreign_key': '"""line_of_business.id"""'}), "(foreign_key='line_of_business.id')\n", (688, 723), False, 'from sqlmodel import Field, Relationship\n'), ((754, 794), 'sqlmodel.Field', 'Field', ([], {'foreign_key': '"""line_of_business.id"""'}), "(foreign_key='line_of_business.id')\n", (759, 794), False, 'from sqlmodel import Field, Relationship\n'), ((823, 854), 'sqlmodel.Field', 'Field', ([], {'foreign_key': '"""sandbox.id"""'}), "(foreign_key='sandbox.id')\n", (828, 854), False, 'from sqlmodel import Field, Relationship\n'), ((906, 1011), 'sqlmodel.Relationship', 'Relationship', ([], {'sa_relationship_kwargs': "{'primaryjoin': 'OutOfBand.sender_id==Lob.id', 'lazy': 'joined'}"}), "(sa_relationship_kwargs={'primaryjoin':\n    'OutOfBand.sender_id==Lob.id', 'lazy': 'joined'})\n", (918, 1011), False, 'from sqlmodel import Field, Relationship\n'), ((1104, 1212), 'sqlmodel.Relationship', 'Relationship', ([], {'sa_relationship_kwargs': "{'primaryjoin': 'OutOfBand.recipient_id==Lob.id', 'lazy': 'joined'}"}), "(sa_relationship_kwargs={'primaryjoin':\n    'OutOfBand.recipient_id==Lob.id', 'lazy': 'joined'})\n", (1116, 1212), False, 'from sqlmodel import Field, Relationship\n'), ((363, 375), 'sqlalchemy.Column', 'Column', (['JSON'], {}), '(JSON)\n', (369, 375), False, 'from sqlalchemy import Column\n')]