"""Pydantic models for Tableau REST and Metadata API responses."""

from __future__ import annotations

from typing import Any, Dict, Optional

from pydantic import BaseModel, ConfigDict, Field


class TableauBaseModel(BaseModel):
    model_config = ConfigDict(extra="allow", populate_by_name=True)


class WorkbookInfo(TableauBaseModel):
    id: str
    name: str
    project_id: Optional[str] = Field(default=None, alias="projectId")
    project_name: Optional[str] = Field(default=None, alias="projectName")
    owner_id: Optional[str] = Field(default=None, alias="ownerId")
    content_url: Optional[str] = Field(default=None, alias="contentUrl")
    created_at: Optional[str] = Field(default=None, alias="createdAt")
    updated_at: Optional[str] = Field(default=None, alias="updatedAt")

    @classmethod
    def from_api(cls, payload: Dict[str, Any]) -> "WorkbookInfo":
        data = dict(payload or {})
        project = data.pop("project", None) or {}
        owner = data.pop("owner", None) or {}
        data.setdefault("projectId", project.get("id"))
        data.setdefault("projectName", project.get("name"))
        data.setdefault("ownerId", owner.get("id"))
        return cls.model_validate(data)


class DatasourceInfo(TableauBaseModel):
    id: str
    name: str
    project_id: Optional[str] = Field(default=None, alias="projectId")
    project_name: Optional[str] = Field(default=None, alias="projectName")
    owner_id: Optional[str] = Field(default=None, alias="ownerId")
    content_url: Optional[str] = Field(default=None, alias="contentUrl")
    datasource_type: Optional[str] = Field(default=None, alias="datasourceType")
    created_at: Optional[str] = Field(default=None, alias="createdAt")
    updated_at: Optional[str] = Field(default=None, alias="updatedAt")

    @classmethod
    def from_api(cls, payload: Dict[str, Any]) -> "DatasourceInfo":
        data = dict(payload or {})
        project = data.pop("project", None) or {}
        owner = data.pop("owner", None) or {}
        data.setdefault("projectId", project.get("id"))
        data.setdefault("projectName", project.get("name"))
        data.setdefault("ownerId", owner.get("id"))
        return cls.model_validate(data)


class ViewInfo(TableauBaseModel):
    id: str
    name: str
    workbook_id: Optional[str] = Field(default=None, alias="workbookId")
    workbook_name: Optional[str] = Field(default=None, alias="workbookName")
    content_url: Optional[str] = Field(default=None, alias="contentUrl")

    @classmethod
    def from_api(cls, payload: Dict[str, Any]) -> "ViewInfo":
        data = dict(payload or {})
        workbook = data.pop("workbook", None) or {}
        data.setdefault("workbookId", workbook.get("id"))
        data.setdefault("workbookName", workbook.get("name"))
        return cls.model_validate(data)


class FieldInfo(TableauBaseModel):
    name: str
    data_type: Optional[str] = Field(default=None, alias="dataType")
    description: Optional[str] = None
    table_name: Optional[str] = Field(default=None, alias="table")
    role: Optional[str] = None
    is_hidden: Optional[bool] = Field(default=None, alias="isHidden")

    @classmethod
    def from_api(cls, payload: Dict[str, Any]) -> "FieldInfo":
        return cls.model_validate(payload or {})


__all__ = [
    "WorkbookInfo",
    "DatasourceInfo",
    "ViewInfo",
    "FieldInfo",
]
