from typing import Literal

from pydantic import BaseModel, Field, model_validator


GoogleWorkspaceDocumentKind = Literal["doc", "sheet"]


class GoogleWorkspaceConnection(BaseModel):
    access_token: str = Field(min_length=1)
    refresh_token: str | None = None
    scope: str = ""
    token_type: str = "Bearer"
    expires_at: str
    account_email: str | None = None
    connected_at: str
    updated_at: str


class GoogleWorkspacePendingAuthorization(BaseModel):
    state: str = Field(min_length=1)
    code_verifier: str = Field(min_length=43, max_length=128)
    tenant_id: str | None = Field(default=None, min_length=1)
    return_to: str = "/documents"
    created_at: str


class GoogleWorkspaceState(BaseModel):
    legacy_connection: GoogleWorkspaceConnection | None = None
    tenant_connections: dict[str, GoogleWorkspaceConnection] = Field(default_factory=dict)
    pending_authorizations: list[GoogleWorkspacePendingAuthorization] = Field(default_factory=list)

    @model_validator(mode="before")
    @classmethod
    def migrate_legacy_connection(cls, payload: object) -> object:
        if not isinstance(payload, dict):
            return payload

        if payload.get("legacy_connection") is None and payload.get("connection") is not None:
            migrated = dict(payload)
            migrated["legacy_connection"] = payload.get("connection")
            return migrated

        return payload


class GoogleWorkspaceStatusResponse(BaseModel):
    configured: bool
    connected: bool
    ready: bool
    account_email: str | None = None
    expires_at: str | None = None
    redirect_uri: str | None = None
    scopes: list[str] = Field(default_factory=list)
    granted_scopes: list[str] = Field(default_factory=list)
    missing_scopes: list[str] = Field(default_factory=list)
    next_step: str


class GoogleWorkspaceAuthorizationResponse(BaseModel):
    authorization_url: str


class GoogleWorkspacePreviewRequest(BaseModel):
    kind: GoogleWorkspaceDocumentKind
    title: str = Field(min_length=3, max_length=200)
    prompt: str = Field(min_length=5, max_length=4000)
    destination_folder_id: str | None = Field(default=None, max_length=255)


class GoogleWorkspaceDocumentPreview(BaseModel):
    kind: GoogleWorkspaceDocumentKind
    title: str
    summary: str
    destination_folder_id: str | None = None
    content: str | None = None
    columns: list[str] = Field(default_factory=list)
    rows: list[list[str]] = Field(default_factory=list)


class GoogleWorkspaceCreateRequest(BaseModel):
    kind: GoogleWorkspaceDocumentKind
    title: str = Field(min_length=3, max_length=200)
    destination_folder_id: str | None = Field(default=None, max_length=255)
    content: str | None = None
    columns: list[str] = Field(default_factory=list)
    rows: list[list[str]] = Field(default_factory=list)

    @model_validator(mode="after")
    def validate_payload(self) -> "GoogleWorkspaceCreateRequest":
        if self.kind == "doc":
            if not self.content or not self.content.strip():
                raise ValueError("Il documento Google Doc richiede contenuto testuale")
            return self

        if not self.columns:
            raise ValueError("Il foglio Google Sheet richiede almeno una colonna")

        column_count = len(self.columns)
        for row in self.rows:
            if len(row) != column_count:
                raise ValueError("Ogni riga del foglio deve avere lo stesso numero di colonne")

        return self


class GoogleWorkspaceCreateResponse(BaseModel):
    kind: GoogleWorkspaceDocumentKind
    file_id: str
    title: str
    web_url: str
    destination_folder_id: str | None = None
    account_email: str | None = None
