# This file was auto-generated by Fern from our API Definition.

import datetime as dt
import typing

from ..commons.types.phone_number import PhoneNumber
from ..commons.types.tools import Tools
from ..commons.types.voice_id import VoiceId
from ..commons.types.webhook import Webhook
from ..core.datetime_utils import serialize_datetime
from .dynamic_data import DynamicData
from .interruption_threshold import InterruptionThreshold
from .model_enum import ModelEnum
from .prounciation_guide import ProunciationGuide
from .temperature import Temperature
from .transfer_list import TransferList
from .voicemail_action import VoicemailAction

try:
    import pydantic.v1 as pydantic  # type: ignore
except ImportError:
    import pydantic  # type: ignore


class SendCall(pydantic.BaseModel):
    """
    from blandai import PronunciationObject, SendCall

    SendCall(
        phone_number="29382721828",
        task="Would love for you to check out our AI API!",
        temperature=0.5,
        transfer_list={
            "default": "+1234567890",
            "sales": "+1234567890",
            "support": "+1234567890",
            "billing": "+1234567890",
        },
        model="enhanced",
        pronunciation_guide=[
            PronunciationObject(
                word="API",
                pronunciation="A P I",
            ),
            PronunciationObject(
                word="AI",
                pronunciation="A I",
            ),
        ],
    )
    """

    phone_number: PhoneNumber = pydantic.Field()
    """
    The phone number to call. Country code defaults to `+1` (US) if not specified.
    
    Formatting is flexible, however for the most predictable results use the **[E.164](https://www.twilio.com/docs/glossary/what-e164#examples-of-e164-numbers)** format.
    """

    task: str = pydantic.Field()
    """
    Provide instructions, relevant information, and examples of the ideal conversation flow.
    """

    transfer_list: typing.Optional[TransferList] = pydantic.Field(default=None)
    """
    Give your agent the ability to transfer calls to a set of phone numbers.
    
    Overrides `transfer_phone_number` if a `transfer_list.default` is specified.
    
    Will default to `transfer_list.default`, or the chosen phone number.
    """

    model: typing.Optional[ModelEnum] = pydantic.Field(default=None)
    """
    Select a model to use for your call.
    
    In nearly all cases, `enhanced` is the best choice for now.
    """

    pronunciation_guide: typing.Optional[ProunciationGuide] = pydantic.Field(default=None)
    """
    The pronunciation guide is an `array` of `objects` that guides the LLM on how to say specific words. This is great for situations with complicated terms or names.
    """

    temperature: Temperature = pydantic.Field()
    """
    A value between 0 and 1 that controls the randomness of the LLM. 0 will cause more deterministic outputs while 1 will cause more random.
    """

    tools: Tools
    transfer_phone_number: typing.Optional[PhoneNumber] = pydantic.Field(default=None)
    """
    A phone number that the agent can transfer to under specific conditions - such as being asked to speak to a human or supervisor.
    """

    answered_by_enabled: typing.Optional[bool] = pydantic.Field(default=None)
    """
    Enables machine detection when the call starts to determine whether the call was answered by a person or a voicemail.
    
    Best Practices (when enabled) -
    
        - Since the determination is made at the beginning of the call, use `wait_for_greeting` to try and coax a human response.
    
        - If combined with first_sentence, try wording it so the person answering says something back - ex. `"Hello?"`
    
    Price - `$0.02` per call, however there is no charge for unanswered calls or calls that failed to send.
    """

    from_: typing.Optional[str] = pydantic.Field(alias="from", default=None)
    """
    Specify a purchased Outbound Number to call from. Country code is required, spaces or parentheses must be excluded.
    
    By default, calls are initiated from a separate pool of numbers owned by Bland.
    """

    reduce_latency: typing.Optional[bool] = pydantic.Field(default=None)
    """
    Reducing latency means that the agent will generate responses more quickly and have less of a delay. This must be set to `true` when using Voice Clones.
    """

    voice_id: typing.Optional[VoiceId] = pydantic.Field(default=None)
    """
    Determines the voice of the AI agent, in conjunction with `reduce_latency`.
    
    Use the `GET /v1/voices endpoint` to see a full list of your available voices.
    
    To create your own Voice Clone, visit our [Custom Voice Cloning page](https://app.bland.ai/home?page=voice-clone).
    """

    voice_preset_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    Use a voice preset instead of specifying individual voice settings.
    
    To create a voice preset, see [Create a Voice Preset](https://docs.bland.ai/api-v1/post/voices).
    """

    start_time: typing.Optional[str] = pydantic.Field(default=None)
    """
    The time you want the call to start. If you don't specify a time (or the time is in the past), the call will send immediately.
    
    Set your time in the format `YYYY-MM-DD HH:MM:SS -HH:MM` (ex. `2021-01-01 12:00:00 -05:00`).
    
    The timezone is optional, and defaults to `UTC` if not specified.
    
    Note - Scheduled calls can be cancelled with the `POST /v1/calls/:call_id/stop` endpoint.
    """

    webhook: typing.Optional[Webhook] = pydantic.Field(default=None)
    """
    The webhook should be a http / https callback url. We will send the call_id and transcript to this URL after the call completes. This can be useful if you want to have real time notifications when calls finish.
    """

    wait_for_greeting: typing.Optional[bool] = pydantic.Field(default=None)
    """
    Should the AI speak first or wait for someone else to talk?
    
    Creates more realistic conversations when answered with “Hello?”, “This is {name} speaking.” and so on.
    
        - When `false`, The AI starts speaking shortly after the call is answered.
    
        - When `true`, The AI will wait for the answerer to speak.
    """

    first_sentence: typing.Optional[str] = pydantic.Field(default=None)
    """
    A phrase that your call will start with instead of a generating one on the fly. This works both with and without `wait_for_greeting`. Can be more than one sentence, but must be less than 200 characters.
    """

    record: typing.Optional[bool] = pydantic.Field(default=None)
    """
    To record your phone call, set `record` to true. When your call completes, you can access through the `recording_url` field in the call details or your webhook.
    """

    voice_settings: typing.Optional[bool] = pydantic.Field(default=None)
    """
    Should the AI speak first or wait for someone else to talk? Creates more realistic conversations when answered with “Hello?”, “This is {name} speaking.” and so on. When `false` - The AI starts speaking shortly after the call is answered. When `true` - The AI will wait for the answerer to speak.
    """

    language: typing.Optional[str] = pydantic.Field(default=None)
    """
    Select a supported language of your choice. Optimizes every part of our API for that language - transcription, speech, and other inner workings.
    
    Supported Languages and their codes -
    
    - English - `eng`
    - Spanish - `esp`
    - French - `fre`
    - Polish - `pol`
    """

    max_duration: typing.Optional[int] = pydantic.Field(default=None)
    """
    Set the longest you want the call to possibly go in minutes. After the max_duration minutes have passed, the call will automatically end. Example Values - `20, 2`
    """

    voicemail_action: typing.Optional[VoicemailAction] = pydantic.Field(default=None)
    """
    Voicemail action tells the AI what to do when encountering a voicemail. This has 96% accuracy. There is no such thing as a perfect VM detection, but this gets close.
    
    The default value is hangup to save money and keep most users in compliance.
    
    Note - **Leaving voicemails is strongly discouraged.**
    """

    amd: typing.Optional[bool] = pydantic.Field(default=None)
    """
    AMD mode helps our AI navigate phone trees and IVR systems. If you know your call will hit an automated system you should switch it on.
    
    NOTE - AMD mode causes increased delay for the first response, even if answered by a human. Highly recommended to set to `false` in the majority of cases.
    """

    request_data: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
    """
    When you want your AI to “know” a specific fact - like the caller's name or other relevant context.
    
    The AI agent will be aware of both the key names as well as their corresponding values.
    """

    dynamic_data: typing.Optional[typing.List[DynamicData]] = pydantic.Field(default=None)
    """
    Make dynamic requests to external APIs and use the data in your AI's responses.
    """

    interruption_threshold: InterruptionThreshold = pydantic.Field()
    """
    When you increase the interruption latency, you force the AI phone agent to listen longer before responding. In practice, increasing the threshold results in less interruptions and more latency.
    
    Try setting the threshold to `500` milliseconds. You'll encounter higher latency, but you'll be interrupted much less frequently.
    """

    def json(self, **kwargs: typing.Any) -> str:
        kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
        return super().json(**kwargs_with_defaults)

    def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
        kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
        return super().dict(**kwargs_with_defaults)

    class Config:
        frozen = True
        smart_union = True
        allow_population_by_field_name = True
        json_encoders = {dt.datetime: serialize_datetime}
