from typing import Optional, List


class Message:
    def __init__(self, role: str, content: str):
        self.role = role
        self.content = content

    def to_dict(self) -> dict:
        return {"role": self.role, "content": self.content}


class Choice:
    def __init__(self, index: int, message: Message, finish_reason: Optional[str] = None):
        self.index = index
        self.message = message
        self.finish_reason = finish_reason


class Usage:
    def __init__(self, prompt_tokens: int, completion_tokens: int, total_tokens: int):
        self.prompt_tokens = prompt_tokens
        self.completion_tokens = completion_tokens
        self.total_tokens = total_tokens


class ChatCompletionResponse:
    def __init__(self, id: str, model: str, choices: List[Choice], usage: Optional[Usage] = None):
        self.id = id
        self.model = model
        self.choices = choices
        self.usage = usage


# --- Streaming Types ---

class StreamDelta:
    def __init__(self, content: Optional[str] = None, role: Optional[str] = None):
        self.content = content
        self.role = role


class StreamChoice:
    def __init__(self, index: int, delta: StreamDelta, finish_reason: Optional[str] = None):
        self.index = index
        self.delta = delta
        self.finish_reason = finish_reason


class ChatCompletionChunk:
    def __init__(self, id: str, model: str, choices: List[StreamChoice]):
        self.id = id
        self.model = model
        self.choices = choices


# --- Images Types ---

class ImageData:
    def __init__(self, url: Optional[str] = None, b64_json: Optional[str] = None):
        self.url = url
        self.b64_json = b64_json


class ImageResponse:
    def __init__(self, data: List[ImageData], created: int):
        self.data = data
        self.created = created


# --- Embeddings Types ---

class EmbeddingData:
    def __init__(self, index: int, embedding: List[float]):
        self.index = index
        self.embedding = embedding


class EmbeddingResponse:
    def __init__(self, data: List[EmbeddingData], model: str, usage: Usage):
        self.data = data
        self.model = model
        self.usage = usage
