from pydantic import BaseModel, Field, EmailStr
from typing import Optional, List, Dict, Any
from datetime import datetime

# ──────────────────────────────────────────────
# Mailbox Models
# ──────────────────────────────────────────────

class MailboxConnection(BaseModel):
    smtp_host: str
    smtp_port: int
    smtp_user: str
    smtp_pass: str
    imap_host: str
    imap_port: int
    imap_user: str
    imap_pass: str

class MailboxBulkRequest(BaseModel):
    mailboxes: List[MailboxConnection]

class WarmupData(BaseModel):
    status: Optional[str] = None

class MailboxDetails(BaseModel):
    email: str
    provider: Optional[str] = None
    login: Optional[str] = None
    server: Optional[str] = None
    port: Optional[int] = None
    from_name: Optional[str] = None
    error: Optional[str] = None
    daily_limit: Optional[int] = 0
    sent_today: int = 0
    frequency_from: Optional[int] = None
    frequency_to: Optional[int] = None
    bcc_crm: Optional[str] = None
    signature: Optional[str] = None
    open_url: Optional[str] = None
    click_url: Optional[str] = None
    unsubscribe_url: Optional[str] = None
    freeze_account: List[Any] = []
    in_slot: Optional[bool] = None
    warmup_data: Optional[WarmupData] = None
    imap_id: Optional[int] = None
    private: Optional[bool] = None

class MailboxResponse(BaseModel):
    id: int
    type: str
    details: MailboxDetails
    status: Optional[str] = "active" 
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

class MailboxMongo(MailboxResponse):
    user_id: str
    last_synced_at: datetime = Field(default_factory=datetime.now)

# ──────────────────────────────────────────────
# Campaign Models
# ──────────────────────────────────────────────

class CampaignSettings(BaseModel):
    timezone: str = "Europe/Warsaw"
    prospect_timezone: bool = True
    daily_enroll: int = 40

class EmailVersion(BaseModel):
    subject: str
    message: str

class EmailBody(BaseModel):
    versions: List[EmailVersion]

class FollowupEmail(BaseModel):
    type: str = "EMAIL"
    delivery_time: Dict[str, List[Dict[str, str]]]
    body: EmailBody

class CampaignStep(BaseModel):
    type: str = "START"
    followup: FollowupEmail

class CampaignCreateRequest(BaseModel):
    name: str
    email_account_ids: List[int]
    cc: Optional[str] = None
    bcc: Optional[str] = None
    settings: Optional[CampaignSettings] = None
    steps: Optional[CampaignStep] = None

class CampaignUpdateRequest(BaseModel):
    settings: Optional[CampaignSettings] = None


class CampaignResponse(BaseModel):
    id: int
    name: str
    status: str
    created: Optional[datetime] = None
    from_name: Optional[str] = ""
    from_names: List[str] = []
    from_email: Optional[str] = ""
    from_emails: List[str] = []
    per_day: int = 0
    folder_name: Optional[str] = "UNASSIGNED"
    folder_id: Optional[int] = 0
    gdpr_unsubscribe: bool = False
    bcc: Optional[str] = ""
    cc: Optional[str] = ""
    error: Optional[str] = ""
    email_account_ids: Optional[List[int]] = []
    updated_at: Optional[datetime] = None

class CampaignMongo(CampaignResponse):
    user_id: str
    last_synced_at: datetime = Field(default_factory=datetime.now)

# ──────────────────────────────────────────────
# Prospect Models
# ──────────────────────────────────────────────

class Prospect(BaseModel):
    email: EmailStr
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    company: Optional[str] = None
    industry_name: Optional[str] = None
    city: Optional[str] = None
    state: Optional[str] = None
    country: Optional[str] = None
    website: Optional[str] = None
    linkedin_url: Optional[str] = None
    twitter_url: Optional[str] = None
    facebook_url: Optional[str] = None
    custom_id: Optional[str] = None
    tags: List[str] = []

class AddProspectsRequest(BaseModel):
    campaign_id: int
    prospects: List[Prospect]

# ──────────────────────────────────────────────
# Prospect Models (v1)
# ──────────────────────────────────────────────

class CampaignIdWrapper(BaseModel):
    campaign_id: int

class ProspectV1(BaseModel):
    email: str # Use str instead of EmailStr to be flexible if needed, though EmailStr is better. 
               # Actually keeping str to avoid validation issues if Woodpecker allows slightly different formats.
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    snippet1: Optional[str] = None
    snippet2: Optional[str] = None
    custom_id: Optional[str] = None

class AddProspectsV1Request(BaseModel):
    campaign: CampaignIdWrapper
    prospects: List[ProspectV1]


# ──────────────────────────────────────────────
# General API Response
# ──────────────────────────────────────────────

class WoodpeckerSyncResponse(BaseModel):
    success: bool
    mailboxes_synced: int
    campaigns_synced: int
    message: str
