from datetime import datetime
from MongoDBConnection import tier_settings_collection


class TierSettingsModel:
    DEFAULT_DOC_ID = "user_tier_program"

    DEFAULT_CONFIG = {
        "_id": DEFAULT_DOC_ID,
        "defaultTier": "Silver",
        "tiers": [
            {"code": "Silver", "minPaidQty": 0, "order": 1},
            {"code": "Gold", "minPaidQty": 5, "order": 2},
            {"code": "Diamond", "minPaidQty": 11, "order": 3},
        ],
        "updatedAt": None,
    }

    @classmethod
    def get_settings(cls):
        doc = tier_settings_collection.find_one({"_id": cls.DEFAULT_DOC_ID})
        if not doc:
            tier_settings_collection.insert_one(cls.DEFAULT_CONFIG.copy())
            doc = tier_settings_collection.find_one({"_id": cls.DEFAULT_DOC_ID})
        return doc

    @classmethod
    def update_settings(cls, default_tier: str, tiers: list):
        if not tiers or not isinstance(tiers, list):
            raise ValueError("tiers is required")

        normalized = []
        seen = set()

        for item in tiers:
            code = str(item.get("code") or "").strip()
            min_paid_qty = int(item.get("minPaidQty", 0))
            order = int(item.get("order", 0))

            if not code:
                raise ValueError("Each tier must have code")

            if code in seen:
                raise ValueError(f"Duplicate tier code: {code}")

            seen.add(code)
            normalized.append({
                "code": code,
                "minPaidQty": max(0, min_paid_qty),
                "order": order,
            })

        normalized.sort(key=lambda x: (x["order"], x["minPaidQty"], x["code"]))

        if default_tier not in [x["code"] for x in normalized]:
            raise ValueError("defaultTier must exist in tiers")

        tier_settings_collection.update_one(
            {"_id": cls.DEFAULT_DOC_ID},
            {
                "$set": {
                    "defaultTier": default_tier,
                    "tiers": normalized,
                    "updatedAt": datetime.utcnow().isoformat(),
                }
            },
            upsert=True,
        )

        return cls.get_settings()