from pydantic import BaseModel, Field, HttpUrl
from datetime import datetime
from typing import Optional, Dict, Any
from enum import Enum


class CrawlStatus(str, Enum):
    PENDING = "pending"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    FAILED = "failed"
    RETRYING = "retrying"


class CompanyData(BaseModel):
    """Strukturerad data för svenska företag"""
    url: HttpUrl = Field(..., description="Original URL som crawlades")
    company_name: Optional[str] = Field(None, description="Företagsnamn")
    org_number: Optional[str] = Field(None, description="Organisationsnummer")
    email: Optional[str] = Field(None, description="E-postadress")
    phone: Optional[str] = Field(None, description="Telefonnummer")
    address: Optional[str] = Field(None, description="Adress")
    postal_code: Optional[str] = Field(None, description="Postnummer")
    city: Optional[str] = Field(None, description="Stad")
    website: Optional[HttpUrl] = Field(None, description="Hemsida")
    
    # Metadata
    crawled_at: datetime = Field(default_factory=datetime.now)
    status: CrawlStatus = Field(default=CrawlStatus.COMPLETED)
    raw_html_hash: Optional[str] = Field(None, description="Hash av rå HTML för deduplikation")
    extraction_confidence: Optional[float] = Field(None, ge=0.0, le=1.0, description="Konfidensgrad för extraherad data")
    
    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat(),
            HttpUrl: lambda v: str(v)
        }


class CrawlJob(BaseModel):
    """Representerar ett crawl-jobb"""
    job_id: str
    urls: list[HttpUrl]
    status: CrawlStatus = CrawlStatus.PENDING
    started_at: Optional[datetime] = None
    completed_at: Optional[datetime] = None
    total_urls: int = 0
    processed_urls: int = 0
    successful_urls: int = 0
    failed_urls: int = 0
    error_details: Dict[str, Any] = Field(default_factory=dict)
    
    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat(),
            HttpUrl: lambda v: str(v)
        }


class ExtractionResult(BaseModel):
    """Resultat från data-extraktion"""
    success: bool
    data: Optional[CompanyData] = None
    error_message: Optional[str] = None
    extraction_method: Optional[str] = None
    confidence_score: Optional[float] = None
    processing_time: Optional[float] = None
