from __future__ import annotations

from typing import List, Optional, Literal, Dict

from pydantic import BaseModel, Field

ColumnType = Literal[
    "domain",
    "email",
    "name",
    "id",
    "city",
    "state",
    "zip",
    "phone",
    "url",
    "text",
    "unknown",
]
Relation = Literal["identity", "supporting"]


class ColumnProfile(BaseModel):
    file: Literal["source", "reference"]
    name: str
    type_guess: ColumnType
    stats: Dict[str, float] = Field(default_factory=dict)
    samples: List[str] = Field(default_factory=list)
    header: Optional[str] = None


class MappingSuggestion(BaseModel):
    source: str
    reference: str
    relation: Relation
    algo: Literal["Exact", "TokenSet", "WRatio", "JaroWinkler"]
    transforms: List[str] = Field(default_factory=list)
    weight: float = 1.0
    why: List[str] = Field(default_factory=list)


class SmartMapRequest(BaseModel):
    source_columns: List[ColumnProfile]
    reference_columns: List[ColumnProfile]
    max_pairs: int = 6


class SmartMapResponse(BaseModel):
    columns: List[ColumnProfile]
    pairs: List[MappingSuggestion]
    threshold_suggestion: Optional[float] = None
    blocking_suggestion: Optional[Dict] = None
