# @File: backend/models/api_hub_credentials.py
# @Desc: Storage model for API Hub provider credentials that admins update
#        through the UI. Each row corresponds to exactly ONE env var / secret
#        for ONE provider. Values are encrypted at rest using the project's
#        existing Fernet-based `mask_crypto` helpers before being persisted,
#        and are decrypted on demand when the API Hub resolves a provider's
#        effective credential set.
#
# Lookup precedence for provider credentials:
#   1. DB-stored value (this table) — highest priority, set via the UI
#   2. Environment variable         — fallback for values baked into the deploy
#
# This lets the portal keep reading env vars in production while also letting
# admins override / add new keys without redeploying.
from datetime import datetime

from core.database import Base
from sqlalchemy import Column, DateTime, Integer, String, Text, UniqueConstraint


class ApiHubCredential(Base):
    """A single encrypted credential value for an API Hub provider."""

    __tablename__ = "api_hub_credentials"
    __table_args__ = (
        UniqueConstraint("provider_id", "name", name="uq_api_hub_credentials_provider_name"),
        {"extend_existing": True},
    )

    id = Column(Integer, primary_key=True, index=True, autoincrement=True, nullable=False)

    # Which provider & env-var this credential maps to (e.g. ("stripe",
    # "STRIPE_SECRET_KEY")). The pair is unique.
    provider_id = Column(String(64), nullable=False, index=True)
    name = Column(String(128), nullable=False)

    # Encrypted blob produced by core.mask_crypto.encrypt_text. We never
    # store the raw value; the column is intentionally text-typed so the
    # Fernet output (with its `mgxkey-` prefix) is not size-bounded.
    encrypted_value = Column(Text, nullable=False)

    # Audit — which admin last touched the value, for the activity trail.
    updated_by = Column(String(255), nullable=True)

    created_at = Column(DateTime(timezone=True), default=datetime.now, nullable=False)
    updated_at = Column(
        DateTime(timezone=True),
        default=datetime.now,
        onupdate=datetime.now,
        nullable=False,
    )