"""Per-tenant branding for chatbot emails.

This is a multi-tenant product: a tenant's customers must see that tenant's
brand, not GalaxiQ's. Branding is resolved from the tenant's Organisation
record in the master database (businessName, image, website, email).

Coverage there is partial -- most organisations have a business name but no
logo -- so anything missing degrades rather than falling back to GalaxiQ's
identity. Showing one tenant's customers another company's logo would be worse
than showing no logo at all.
"""
import logging
from dataclasses import dataclass

from app.services.integrations.brandforge import brandforge_profile
from app.services.infra.database import fetch_organisation_profile

logger = logging.getLogger(__name__)


@dataclass(frozen=True)
class Branding:
    name: str
    logo_url: str = ""          # empty -> the template omits the logo entirely
    chatbot_url: str = ""
    primary_color: str = ""
    accent_color: str = ""
    font_stack: str = ""
    reference_links: tuple = ()
    reply_to: str = ""
    show_cta: bool = False
    # Transactional replies to something the user asked for in chat, not
    # marketing, so no unsubscribe link by default.
    show_unsubscribe: bool = False
    unsubscribe_url: str = ""


# Used when the tenant is unknown or its Organisation record cannot be read.
# NOTE: the logo must be PNG/JPG -- Gmail and Outlook do not render SVG, and
# the only logo on the marketing site is an SVG.
GALAXIQ_BRANDING = Branding(
    name="GalaxiQ",
    logo_url="https://studio.galaxiq.ai/uploads/1781693316095-Email_Logo_4_.png",
)

def _normalise_url(url: str) -> str:
    url = (url or "").strip()
    if not url:
        return ""
    if not url.startswith(("http://", "https://")):
        url = "https://" + url
    return url


def _looks_like_email(value: str) -> bool:
    return "@" in (value or "")


def brand_for_tenant(tenant_id: str = None) -> Branding:
    """Resolve a tenant's email branding, falling back to GalaxiQ when unknown."""
    if not tenant_id:
        return GALAXIQ_BRANDING

    # BrandForge crawls the tenant's real site, so it is a better source than the
    # Organisation signup record, where the trading name is often a placeholder.
    bf = brandforge_profile(tenant_id)

    try:
        org = fetch_organisation_profile(tenant_id)
    except Exception as ex:
        logger.error(f"Could not load branding for {tenant_id}: {ex}")
        org = None

    if not org and not bf:
        return GALAXIQ_BRANDING
    org = org or {}

    # businessName is the trading name; `name` is often the signup user's own
    # name, so only fall back to it when there is nothing better. Some records
    # hold an email address in these fields -- never greet a customer with that.
    name = (org.get("businessName") or "").strip()
    if not name or _looks_like_email(name):
        candidate = (org.get("name") or "").strip()
        name = "" if _looks_like_email(candidate) else candidate

    return Branding(
        # BrandForge reads the name off the tenant's own site, so prefer it.
        name=(bf.get("name") or name or GALAXIQ_BRANDING.name),
        # Most Organisation records have no logo; BrandForge usually finds one.
        logo_url=bf.get("logo_url") or _normalise_url(org.get("image") or ""),
        chatbot_url=_normalise_url(org.get("website") or ""),
        reply_to=(org.get("email") or "").strip(),
        primary_color=bf.get("primary_color") or "",
        accent_color=bf.get("accent_color") or "",
        font_stack=bf.get("font_stack") or "",
        reference_links=tuple(bf.get("links") or ()),
    )
