from __future__ import annotations
import re
from dataclasses import dataclass
from urllib.parse import urlparse
from matching import confidence, validate_product_match
from condition import assess_condition

@dataclass
class SearchEvidence:
    price: float
    currency: str
    confidence: float
    text: str
    reason: str
    detected_condition: str
    condition_confidence: float
    condition_evidence: str

# Sadece para birimiyle açıkça işaretlenmiş fiyatları al. GB/model numaralarını fiyat sanma.
_PRICE_PATTERNS = [
    re.compile(r'(?<!\w)(?:₺|tl\s*)\s*([0-9]{1,3}(?:[\.\s][0-9]{3})*(?:,[0-9]{1,2})?|[0-9]{4,7}(?:,[0-9]{1,2})?)', re.I),
    re.compile(r'(?<!\w)([0-9]{1,3}(?:[\.\s][0-9]{3})*(?:,[0-9]{1,2})?|[0-9]{4,7}(?:,[0-9]{1,2})?)\s*(?:₺|tl)(?!\w)', re.I),
]

def _parse_tr_number(raw: str) -> float | None:
    s=(raw or '').strip().replace('\u00a0',' ').replace(' ','')
    if not s:return None
    # Türkçe fiyat: nokta binlik, virgül ondalık. 64999.90 biçimini de kabul et.
    if ',' in s:
        s=s.replace('.','').replace(',','.')
    elif s.count('.')>1:
        s=s.replace('.','')
    elif '.' in s:
        left,right=s.rsplit('.',1)
        if len(right)==3 and len(left)<=3:s=left+right
    try:
        v=float(s)
    except ValueError:return None
    if v < 100 or v > 10_000_000:return None
    return v

def prices_from_text(text: str) -> list[float]:
    vals=[]
    for pat in _PRICE_PATTERNS:
        for m in pat.finditer(text or ''):
            # "64.999 TL 256 GB" içindeki ikinci 256'yı "TL 256" diye fiyat sanma.
            suffix=(text or '')[m.end():m.end()+12]
            if re.match(r'\s*(?:gb|tb|gbyte|tbyte|gigabyte|terabyte)\b',suffix,re.I):
                continue
            v=_parse_tr_number(m.group(1))
            if v is not None and v not in vals:vals.append(v)
    return vals

def evaluate_search_result(product: dict, result: dict) -> SearchEvidence | None:
    title=(result.get('title') or '').strip()
    description=(result.get('description') or '').strip()
    extras=' '.join(str(x) for x in (result.get('extra_snippets') or []) if x)
    combined=' '.join(x for x in (title,description,extras) if x).strip()
    if not combined:return None
    try:
        validate_product_match(product,combined,url=result.get('url') or '',condition_text='',enforce_condition=True)
        ca=assess_condition(product,combined,result.get('url') or '', '',require_known=True)
        if ca.status!='verified': return None
    except Exception:return None
    vals=prices_from_text(combined)
    if not vals:return None
    # Arama sonuçlarında eski liste fiyatı + indirimli fiyat birlikte olabilir; en düşük makul sinyali sakla.
    price=min(vals)
    base=confidence(product,combined,'')
    # Dolaylı veri hiçbir zaman doğrudan sayfa kadar güvenilir sayılmaz.
    conf=max(.50,min(.82,base*.76 + .12))
    engine=result.get('engine') or 'search'
    return SearchEvidence(price=price,currency='TRY',confidence=conf,text=combined[:1800],reason=f'{engine} arama indeksinde ürün+varyant+durum ve açık TL fiyatı eşleşti',detected_condition=ca.detected or ca.expected,condition_confidence=ca.confidence,condition_evidence=ca.evidence)

def host_domain(url: str) -> str:
    host=(urlparse(url).hostname or '').lower().strip('.').removeprefix('www.')
    parts=host.split('.')
    multi={'com.tr','net.tr','org.tr','gen.tr','web.tr','co.uk','com.de','com.br'}
    if len(parts)>=3 and '.'.join(parts[-2:]) in multi:return '.'.join(parts[-3:])
    return '.'.join(parts[-2:]) if len(parts)>=2 else host
