from typing import Optional, Dict, Any, List

from pydantic import Field, BaseModel, ConfigDict

from thestage.services.clients.thestage_api.dtos.frontend_status import FrontendStatusDto
from thestage.services.clients.thestage_api.dtos.base_response import TheStageBasePaginatedResponse, \
    TheStageBaseResponse
from thestage.services.clients.thestage_api.dtos.paginated_entity_list import PaginatedEntityList
from thestage.instance.dto.enum.gpu_name import InstanceGpuType
from thestage.instance.dto.enum.cpu_type import InstanceCpuType


class InstanceRentedCreateRequest(BaseModel):
    slug: Optional[str] = Field(None, alias='slug')
    gpuName: Optional[str] = Field(None, alias='gpuName')
    cloudProviderName: Optional[str] = Field(None, alias='cloudProviderName')

    # optional prompted fields 'direct user input' values are str to avoid type casting errors
    gpuCount: Optional[str] = Field(None, alias='gpuCount')
    diskSizeGb: Optional[str] = Field(None, alias='diskSizeGb')

    forceStartRent: Optional[bool] = Field(None, alias='forceStartRent')
    concreteInstanceOfferPublicId: Optional[str] = Field(None, alias='concreteInstanceOfferPublicId')


class ConcreteInstanceOffer(BaseModel):
    publicId: Optional[str] = Field(None, alias='publicId', title='ID')
    # offerName: Optional[str] = Field(None, alias='offerName', title='Offer Name')
    providerAndRegion: Optional[str] = Field(None, alias='providerAndRegion', title='Provider and Region')
    gpuInfo: Optional[str] = Field(None, alias='gpuInfo', title='GPU')
    cpuInfo: Optional[str] = Field(None, alias='cpuInfo', title='CPU')
    diskSizeGb: Optional[int] = Field(None, alias='diskSizeGb', title='Disk size, GB')
    ramSizeGb: Optional[int] = Field(None, alias='ramSizeGb', title='RAM size, GB')
    pricePerHour: Optional[str] = Field(None, alias='pricePerHour', title='Price per hour')


class InstanceRentedCreateResponse(TheStageBaseResponse):
    instanceRentedPublicId: Optional[str] = Field(None, alias='instanceRentedPublicId')
    concreteInstanceOffersToSelect: Optional[List[ConcreteInstanceOffer]] = Field(None, alias='concreteInstanceOffersToSelect')
    selectedConcreteInstanceOffer: Optional[ConcreteInstanceOffer] = Field(None, alias='selectedConcreteInstanceOffer')

    missingFieldName: Optional[str] = Field(None, alias='missingFieldName')
    missingFieldDisplayName: Optional[str] = Field(None, alias='missingFieldDisplayName')
    missingFieldOptions: Optional[Dict[str, str]] = Field(None, alias='missingFieldOptions')
