from __future__ import annotations
from dataclasses import dataclass
from statistics import median
try:
    from rapidfuzz import fuzz
except Exception:
    fuzz=None
from matching import confidence, norm, product_query

@dataclass
class Decision:
    status: str
    score: float
    match_confidence: float
    price_sanity: float
    reasons: list[str]
    summary: str


def _historical_prices(c, product_id: int, condition_type: str='new', limit=30):
    rows=c.execute('''SELECT price FROM price_observations WHERE product_id=? AND condition_type=? AND price>0
                      ORDER BY observed_at DESC LIMIT ?''',(product_id,condition_type,limit)).fetchall()
    return [float(r['price']) for r in rows]


def evaluate(c, product, offer, html='', *, trust_score=70.0, fetched_via='http') -> Decision:
    match_text=getattr(offer,'match_text',None) or offer.title or ''
    base=confidence(product,match_text,html or '')
    fuzzy=0.0
    if fuzz and match_text:
        q=product_query(product,include_price_word=False)
        fuzzy=fuzz.token_set_ratio(norm(q),norm(match_text))/100.0
    match=min(1.0,max(base,base*0.78+fuzzy*0.22))

    reasons=[]
    if match>=.85: reasons.append('ürün başlığı çok güçlü eşleşiyor')
    elif match>=.68: reasons.append('ürün başlığı yeterli eşleşiyor')
    else: reasons.append('ürün başlığı eşleşmesi zayıf')

    price_sanity=.82
    pid=(product.get('product_id') if isinstance(product,dict) else product['product_id'] if 'product_id' in product.keys() else None)
    condition=(product.get('condition_type') if isinstance(product,dict) else product['condition_type'] if 'condition_type' in product.keys() else 'new') or 'new'
    prices=_historical_prices(c,int(pid),str(condition)) if pid else []
    if prices:
        med=median(prices)
        ratio=float(offer.price)/med if med else 1.0
        if .65 <= ratio <= 1.55:
            price_sanity=1.0; reasons.append('fiyat yakın geçmiş aralığıyla uyumlu')
        elif .45 <= ratio <= 2.10:
            price_sanity=.65; reasons.append('fiyat geçmişe göre belirgin farklı; temkinli değerlendirildi')
        else:
            price_sanity=.25; reasons.append('fiyat geçmişe göre aşırı aykırı')
    else:
        reasons.append('henüz fiyat geçmişi az; anomali kontrolü sınırlı')

    trust=max(0.0,min(1.0,float(trust_score)/100.0))
    score=match*.70 + trust*.18 + price_sanity*.12
    if fetched_via=='browser':
        reasons.append('HTTP başarısız olduğu için Chromium fallback ile doğrulandı')
    else:
        reasons.append('hafif HTTP yöntemiyle doğrulandı')

    # Aşırı fiyat anomalisi otomatik onayı engeller; kesin varyant eşleşmesi yine aday olarak tutulabilir.
    if price_sanity<=.30:
        status='candidate' if match>=.70 else 'reject'
    elif score>=.78 and match>=.72:
        status='auto'
    elif score>=.58 and match>=.56:
        status='candidate'
    else:
        status='reject'
    summary=f"Akıllı karar: {round(score*100)}% · " + '; '.join(reasons[:4])
    return Decision(status,score,match,price_sanity,reasons,summary)
