"""
Central place for every scoring weight and business threshold.

Tuning the decision engine should only ever require editing this file.
"""

# ---------------------------------------------------------------------------
# Decisions
# ---------------------------------------------------------------------------
DECISION_SELL = "SELL"
DECISION_CONSIDER = "CONSIDER"
DECISION_DO_NOT_SELL = "DO_NOT_SELL"

# Score thresholds that map a 0-100 score to a decision.
SELL_THRESHOLD = 75.0
CONSIDER_THRESHOLD = 50.0

# ---------------------------------------------------------------------------
# SKU score weights (must sum to 1.0)
# ---------------------------------------------------------------------------
# Rebalanced so one weak factor cannot destroy an otherwise excellent SKU:
# pricing 20 / profit 20 / shipping 15 / store 15 / inventory 10 / delivery 10
# / market popularity 10. Missing components are renormalized at runtime.
SKU_SCORE_WEIGHTS = {
    "supplier_price": 0.20,   # pricing attractiveness
    "profit": 0.20,
    "shipping": 0.15,
    "store_quality": 0.15,    # supplier reliability
    "inventory": 0.10,
    "delivery": 0.10,
    "popularity": 0.10,       # market demand signal
}

# ---------------------------------------------------------------------------
# Product score weights (must sum to 1.0)
# ---------------------------------------------------------------------------
PRODUCT_SCORE_WEIGHTS = {
    "product": 0.15,
    "store": 0.15,
    "best_sku": 0.20,
    "average_sku": 0.15,
    "market": 0.15,
    "risk": 0.10,       # applied as (100 - risk score)
    "strength": 0.10,
}

# ---------------------------------------------------------------------------
# Store grading (0-100 store score -> grade)
# ---------------------------------------------------------------------------
STORE_GRADE_EXCELLENT = 85.0
STORE_GRADE_GOOD = 70.0
STORE_GRADE_AVERAGE = 50.0

STORE_GRADES = {
    "EXCELLENT": "Excellent",
    "GOOD": "Good",
    "AVERAGE": "Average",
    "POOR": "Poor",
}

# Sales / review / follower volume that earns the maximum volume sub-score.
STORE_MAX_SALES_FOR_FULL_SCORE = 10_000
STORE_MAX_REVIEWS_FOR_FULL_SCORE = 2_000
STORE_MAX_FOLLOWERS_FOR_FULL_SCORE = 5_000

# Metric weights inside the store score; metrics the supplier API does not
# provide are skipped and the remaining weights are renormalized, so a store
# is never penalized for data the API simply did not return.
STORE_METRIC_WEIGHTS = {
    "ratings": 0.70,
    "sales": 0.15,
    "reviews": 0.10,
    "followers": 0.05,
}

# ---------------------------------------------------------------------------
# Inventory health bands (units in stock) and smooth score anchors
# 0 = Out of Stock, 1-10 Very Low, 11-30 Low, 31-100 Medium, 101-500 High,
# 500+ Excellent. Scores interpolate linearly between anchors so the curve
# rises gradually instead of dropping off a cliff.
# ---------------------------------------------------------------------------
INVENTORY_EXCELLENT = 500
INVENTORY_HIGH = 100
INVENTORY_MEDIUM = 30
INVENTORY_VERY_LOW = 10

INVENTORY_SCORE_ANCHORS = [
    (0, 0.0),
    (1, 10.0),
    (10, 30.0),
    (30, 50.0),
    (100, 70.0),
    (500, 90.0),
    (1000, 100.0),
]

INVENTORY_HEALTH = {
    "EXCELLENT": "Excellent",
    "HIGH": "High",
    "MEDIUM": "Medium",
    "LOW": "Low",
    "VERY_LOW": "Very Low",
    "OUT_OF_STOCK": "Out Of Stock",
    # Legacy labels kept for backward compatibility with older consumers.
    "GOOD": "High",
    "LIMITED": "Medium",
}

# ---------------------------------------------------------------------------
# Shipping scoring
# ---------------------------------------------------------------------------
# Delivery days: full points at or under FAST, zero points at or over SLOW.
DELIVERY_DAYS_FAST = 7
DELIVERY_DAYS_SLOW = 45

# Shipping cost: full points at or under CHEAP, zero points at or over EXPENSIVE.
SHIPPING_COST_CHEAP = 3.0
SHIPPING_COST_EXPENSIVE = 30.0

TRACKING_BONUS = 15.0

# Carriers considered reliable get a bonus.
TRUSTED_CARRIER_KEYWORDS = (
    "CAINIAO", "ALIEXPRESS", "DHL", "UPS", "FEDEX", "EMS", "YANWEN", "ARAMEX",
)
TRUSTED_CARRIER_BONUS = 10.0

# Warehouses close to the target markets ship faster / avoid customs friction.
PREFERRED_WAREHOUSES = ("GB", "UK", "SA", "AE", "ES", "FR", "DE", "PL", "CZ")
PREFERRED_WAREHOUSE_BONUS = 10.0

# Component weights inside the shipping score (must sum to 1.0).
SHIPPING_SCORE_WEIGHTS = {
    "delivery_time": 0.40,
    "cost": 0.35,
    "extras": 0.25,   # tracking + carrier + warehouse bonuses, capped at 100
}

SHIPPING_GRADE_EXCELLENT = 80.0
SHIPPING_GRADE_GOOD = 60.0
SHIPPING_GRADE_AVERAGE = 40.0

# ---------------------------------------------------------------------------
# Profit scoring
# ---------------------------------------------------------------------------
# ROI (%) that earns the maximum ROI sub-score.
ROI_FOR_FULL_SCORE = 60.0
# Realized margin (%) that earns the maximum margin sub-score.
MARGIN_FOR_FULL_SCORE = 35.0
# Absolute profit (currency units) that earns the maximum profit sub-score.
PROFIT_FOR_FULL_SCORE = 20.0

PROFIT_SCORE_WEIGHTS = {
    "roi": 0.35,
    "margin": 0.30,
    "absolute_profit": 0.20,
    "price_competitiveness": 0.15,
}

# ---------------------------------------------------------------------------
# Popularity scoring (product level, shared by every SKU)
# ---------------------------------------------------------------------------
SALES_FOR_FULL_POPULARITY = 1_000
REVIEWS_FOR_FULL_POPULARITY = 300

# ---------------------------------------------------------------------------
# Market analysis
# ---------------------------------------------------------------------------
MARKET_UK = "uk"
MARKET_SAUDI = "saudi"

MARKET_RECOMMEND_THRESHOLD = 60.0

# Component weights for a market score (sum to 1.0). Rating, reviews,
# shipping, pricing and listing completeness carry the most weight; raw sales
# volume ("popularity") is a minor signal scored on a saturating curve so
# moderate sales are not treated as failure. Missing components are skipped
# and the rest renormalized.
MARKET_SCORE_WEIGHTS = {
    "ratings": 0.18,
    "shipping": 0.15,
    "store": 0.13,
    "price": 0.12,
    "reviews": 0.12,
    "delivery": 0.10,
    "completeness": 0.10,
    "popularity": 0.06,
    "inventory": 0.04,
}

# Warehouse countries that are advantageous per market.
MARKET_LOCAL_WAREHOUSES = {
    MARKET_UK: ("GB", "UK", "ES", "FR", "DE", "PL", "CZ", "BE", "NL", "IT"),
    MARKET_SAUDI: ("SA", "AE"),
}
MARKET_LOCAL_WAREHOUSE_BONUS = 8.0

# Delivery expectations differ by market (days for full / zero delivery score).
MARKET_DELIVERY_FAST = {MARKET_UK: 7, MARKET_SAUDI: 10}
MARKET_DELIVERY_SLOW = {MARKET_UK: 30, MARKET_SAUDI: 40}

# ---------------------------------------------------------------------------
# Risk thresholds
# ---------------------------------------------------------------------------
RISK_LOW_STOCK_UNITS = 50
RISK_POOR_RATING = 4.0            # average store rating below this (out of 5)
RISK_LONG_SHIPPING_DAYS = 25
RISK_HIGH_SHIPPING_COST = 15.0
RISK_LOW_REVIEW_COUNT = 20
RISK_WEAK_STORE_SCORE = 50.0
RISK_HEAVY_PACKAGE_KG = 2.0
RISK_LARGE_PACKAGE_CM = 60.0      # any single dimension above this
RISK_POINTS_PER_ITEM = 15.0       # each identified risk adds this many points

# ---------------------------------------------------------------------------
# Strength thresholds
# ---------------------------------------------------------------------------
STRENGTH_HIGH_RATING = 4.5
STRENGTH_DECENT_RATING = 4.0
STRENGTH_HIGH_SALES = 100
STRENGTH_SOME_SALES = 25
STRENGTH_TRUSTED_STORE_SCORE = 75.0
STRENGTH_FAST_SHIPPING_DAYS = 12
STRENGTH_HEALTHY_STOCK_UNITS = 100
STRENGTH_MANY_VARIANTS = 5
STRENGTH_GOOD_PRICE = 15.0            # supplier price at/below this is attractive
STRENGTH_COMPLETE_DESCRIPTION = 300   # characters
STRENGTH_MULTIPLE_IMAGES = 4
STRENGTH_GOOD_SPECIFICATIONS = 8      # property count

# Each signal contributes its own weight (points). A complete, well-rated,
# fast-shipping listing lands in the 65-85 band instead of ~50.
STRENGTH_SIGNAL_POINTS = {
    "high_rating": 12.0,
    "decent_rating": 7.0,          # only when high_rating not met
    "high_sales": 10.0,
    "some_sales": 6.0,             # only when high_sales not met
    "trusted_store": 12.0,
    "fast_shipping": 10.0,
    "tracking": 8.0,
    "healthy_stock": 8.0,
    "many_variants": 6.0,
    "good_price": 6.0,
    "complete_description": 10.0,
    "multiple_images": 10.0,
    "good_specifications": 8.0,
}

# ---------------------------------------------------------------------------
# Confidence — driven by data quality, not by the score itself.
# 90-100 Extremely Reliable / 75-89 Reliable / 60-74 Moderate /
# 40-59 Limited / <40 Low.
# ---------------------------------------------------------------------------
CONFIDENCE_COMPONENT_WEIGHTS = {
    "reviews": 0.25,
    "sales": 0.15,
    "store_reputation": 0.15,
    "listing_completeness": 0.15,
    "shipping_reliability": 0.15,
    "metric_consistency": 0.15,
}
CONFIDENCE_REVIEWS_FULL = 200      # reviews for a full reviews sub-score
CONFIDENCE_SALES_FULL = 500        # sales for a full sales sub-score
# Hard caps: never assign high confidence with very few reviews.
CONFIDENCE_CAP_FEW_REVIEWS = (10, 65.0)    # under 10 reviews -> max 65
CONFIDENCE_CAP_ALMOST_NO_REVIEWS = (3, 45.0)  # under 3 reviews -> max 45

# Per-SKU confidence (kept simpler; SKUs share product-level review data).
CONFIDENCE_BASE = 40.0
CONFIDENCE_MAX_DISTANCE_BONUS = 30.0
CONFIDENCE_DATA_BONUS = 15.0

# ---------------------------------------------------------------------------
# Product-level decision gates
# SELL requires a high score AND low risk AND reliable confidence.
# ---------------------------------------------------------------------------
PRODUCT_SELL_SCORE = 80.0
PRODUCT_SELL_MAX_RISK = 30.0
PRODUCT_SELL_MIN_CONFIDENCE = 75.0
PRODUCT_CONSIDER_SCORE = 60.0
PRODUCT_CONSIDER_FALLBACK_SCORE = 50.0   # 50-59 still CONSIDER when risk is moderate
PRODUCT_CONSIDER_MAX_RISK = 45.0
