from __future__ import annotations
from typing import Optional, Dict, Any
from ...services.domain_family import domain_normalize


class CRMAdapter:
    async def find_account_by_lead(
        self, lead: Dict[str, Any]
    ) -> Optional[Dict[str, Any]]:
        raise NotImplementedError

    async def find_account_by_domain(self, domain: str) -> Optional[Dict[str, Any]]:
        raise NotImplementedError

    async def find_account_by_name_like(self, name: str) -> Optional[Dict[str, Any]]:
        raise NotImplementedError


class SalesforceAdapter(CRMAdapter):
    def __init__(self, sfdc_client):
        self.sf = sfdc_client

    async def find_account_by_domain(self, domain: str) -> Optional[Dict[str, Any]]:
        d = domain_normalize(domain)
        if not d:
            return None
        # If you create an indexed formula field Domain__c in SFDC, switch to equality:
        # q = f"SELECT Id, Name, Website, OwnerId, Type, ABM_Tier__c FROM Account WHERE Domain__c = '{d}' LIMIT 1"
        q = (
            "SELECT Id, Name, Website, OwnerId, Type, ABM_Tier__c "
            f"FROM Account WHERE Website LIKE '%{d}' LIMIT 1"
        )  # right‑anchored
        res = await self.sf.soql(q)
        recs = (res or {}).get("records", [])
        if not recs:
            return None
        r = recs[0]
        return {
            "id": r["Id"],
            "name": r["Name"],
            "website": r.get("Website"),
            "owner_id": r.get("OwnerId"),
            "abm_tier": r.get("ABM_Tier__c"),
            "customer_status": "customer"
            if r.get("Type") == "Customer"
            else "prospect",
        }

    async def find_account_by_name_like(self, name: str) -> Optional[Dict[str, Any]]:
        if not name:
            return None
        safe = name.replace("'", "\\'")
        q = (
            "SELECT Id, Name, Website, OwnerId, Type, ABM_Tier__c "
            f"FROM Account WHERE Name LIKE '%{safe}%' LIMIT 1"
        )
        res = await self.sf.soql(q)
        recs = (res or {}).get("records", [])
        if not recs:
            return None
        r = recs[0]
        return {
            "id": r["Id"],
            "name": r["Name"],
            "website": r.get("Website"),
            "owner_id": r.get("OwnerId"),
            "abm_tier": r.get("ABM_Tier__c"),
            "customer_status": "customer"
            if r.get("Type") == "Customer"
            else "prospect",
        }

    async def find_account_by_lead(
        self, lead: Dict[str, Any]
    ) -> Optional[Dict[str, Any]]:
        # Try domain first
        dom = domain_normalize(lead.get("email") or lead.get("website"))
        if dom:
            acc = await self.find_account_by_domain(dom)
            if acc:
                return acc
        # Fallback: company name
        if lead.get("company"):
            return await self.find_account_by_name_like(lead["company"])
        return None
