#!/usr/bin/env python3
"""
Genesis Tradie Funnel Architect Skill
======================================
Strategic design and lead funnel management for tradie services.
Bridges GHL execution with AI-driven funnel optimization.

PM-040: Tradie Funnel Skill Enhancement
- Stages: capture, qualify, nurture, convert
- Integrates with GHL
- Complete lead funnel processing
"""

import os
import json
import logging
from typing import Dict, Any, List, Optional
from datetime import datetime, timedelta
from dataclasses import dataclass, asdict

logger = logging.getLogger("TradieFunnelArchitect")
logging.basicConfig(level=logging.INFO)


@dataclass
class FunnelLead:
    """Represents a lead in the funnel."""
    lead_id: str
    first_name: str
    last_name: str
    email: str
    phone: str
    niche: str
    service_area: str
    stage: str
    score: int
    source: str
    entered_at: str
    last_activity: str
    metadata: Dict[str, Any]

    def to_dict(self) -> Dict[str, Any]:
        return asdict(self)


class TradieFunnelArchitectSkill:
    """
    Expertise in high-converting funnels for professional tradie services.
    Handles the complete funnel lifecycle: capture, qualify, nurture, convert.
    """

    # Funnel stages
    STAGES = ["capture", "qualify", "nurture", "convert", "closed"]

    # Niche-specific configurations
    NICHE_DATA = {
        "plumber": {
            "pain_points": ["Missed emergency calls", "Scheduling conflicts", "Unqualified leads"],
            "keywords": ["Emergency Plumber", "Blocked Drains", "Hot Water Repairs"],
            "value_prop": "Never miss a high-ticket pipe repair call again.",
            "avg_ticket": 450,
            "qualifying_questions": [
                "Is this an emergency?",
                "What type of plumbing service do you need?",
                "What suburb are you in?"
            ]
        },
        "electrician": {
            "pain_points": ["On-site busy", "Small job overload", "Late night quotes"],
            "keywords": ["Level 2 Electrician", "Fast Quote", "Rewiring"],
            "value_prop": "Automated quoting for your residential electrical jobs.",
            "avg_ticket": 380,
            "qualifying_questions": [
                "Is this residential or commercial?",
                "Do you need a Level 2 electrician?",
                "What's your postcode?"
            ]
        },
        "hvac": {
            "pain_points": ["Seasonal demand spikes", "Emergency callouts", "Parts availability"],
            "keywords": ["Air Conditioning", "Heating Repair", "Ducted AC"],
            "value_prop": "Handle peak season demand with AI-powered booking.",
            "avg_ticket": 520,
            "qualifying_questions": [
                "Is your unit heating, cooling, or both?",
                "When was it last serviced?",
                "What brand is your system?"
            ]
        },
        "roofer": {
            "pain_points": ["Weather delays", "Quote competition", "Lead qualification"],
            "keywords": ["Roof Repair", "Tile Replacement", "Gutter Cleaning"],
            "value_prop": "Qualify storm damage leads before you get to the roof.",
            "avg_ticket": 800,
            "qualifying_questions": [
                "Is this storm damage or general maintenance?",
                "What type of roof do you have?",
                "Can you send photos of the damage?"
            ]
        }
    }

    def __init__(self, ghl_skill=None):
        """
        Initialize funnel architect.

        Args:
            ghl_skill: Optional GHLMasterySkill instance for GHL integration
        """
        self.ghl_skill = ghl_skill
        self.leads: Dict[str, FunnelLead] = {}
        self.funnel_stats: Dict[str, int] = {stage: 0 for stage in self.STAGES}

        logger.info("Tradie Funnel Architect Skill initialized")

    def _generate_lead_id(self) -> str:
        """Generate unique lead ID."""
        import uuid
        return f"lead_{uuid.uuid4().hex[:12]}"

    def _calculate_lead_score(self, lead_data: Dict[str, Any]) -> int:
        """Calculate lead quality score (0-100)."""
        score = 50  # Base score

        # Urgency bonus
        if lead_data.get("urgency") == "emergency":
            score += 20
        elif lead_data.get("urgency") == "this_week":
            score += 10

        # Contact info completeness
        if lead_data.get("email"):
            score += 10
        if lead_data.get("phone"):
            score += 10

        # Service type match
        niche = lead_data.get("niche", "").lower()
        if niche in self.NICHE_DATA:
            score += 10

        # Budget indication
        if lead_data.get("budget_confirmed"):
            score += 10

        return min(score, 100)

    # ===== CAPTURE STAGE =====

    def capture_lead(self, first_name: str, last_name: str,
                     email: str, phone: str, niche: str,
                     service_area: str, source: str = "website",
                     metadata: Dict[str, Any] = None) -> FunnelLead:
        """
        Capture a new lead into the funnel.

        Args:
            first_name: Lead's first name
            last_name: Lead's last name
            email: Email address
            phone: Phone number
            niche: Tradie niche (plumber, electrician, etc.)
            service_area: Service location
            source: Lead source (website, facebook, google, referral)
            metadata: Additional lead data

        Returns:
            Created FunnelLead
        """
        now = datetime.utcnow().isoformat()

        lead = FunnelLead(
            lead_id=self._generate_lead_id(),
            first_name=first_name,
            last_name=last_name,
            email=email,
            phone=phone,
            niche=niche.lower(),
            service_area=service_area,
            stage="capture",
            score=self._calculate_lead_score({
                "email": email,
                "phone": phone,
                "niche": niche,
                **(metadata or {})
            }),
            source=source,
            entered_at=now,
            last_activity=now,
            metadata=metadata or {}
        )

        self.leads[lead.lead_id] = lead
        self.funnel_stats["capture"] += 1

        logger.info(f"Lead captured: {first_name} {last_name} ({niche}) - Score: {lead.score}")

        # Sync to GHL if available
        if self.ghl_skill:
            self._sync_lead_to_ghl(lead)

        return lead

    def _sync_lead_to_ghl(self, lead: FunnelLead) -> Dict[str, Any]:
        """Sync lead to GHL CRM."""
        if not self.ghl_skill:
            return {"error": "GHL skill not configured"}

        try:
            result = self.ghl_skill.execute(
                "create_contact",
                location_id=os.getenv("GHL_LOCATION_ID", ""),
                first_name=lead.first_name,
                last_name=lead.last_name,
                email=lead.email,
                phone=lead.phone,
                tags=[f"niche:{lead.niche}", f"stage:{lead.stage}", "genesis_funnel"],
                custom_fields={
                    "service_area": lead.service_area,
                    "lead_score": str(lead.score),
                    "source": lead.source
                }
            )
            logger.info(f"Lead synced to GHL: {lead.lead_id}")
            return result
        except Exception as e:
            logger.error(f"GHL sync failed: {e}")
            return {"error": str(e)}

    # ===== QUALIFY STAGE =====

    def qualify_lead(self, lead_id: str, qualification_data: Dict[str, Any]) -> FunnelLead:
        """
        Qualify a captured lead based on responses.

        Args:
            lead_id: Lead ID to qualify
            qualification_data: Qualification responses

        Returns:
            Updated FunnelLead
        """
        if lead_id not in self.leads:
            raise ValueError(f"Lead not found: {lead_id}")

        lead = self.leads[lead_id]

        # Update score based on qualification
        score_adjustment = 0

        # Check urgency
        if qualification_data.get("urgency") == "emergency":
            score_adjustment += 25
        elif qualification_data.get("urgency") == "this_week":
            score_adjustment += 15
        elif qualification_data.get("urgency") == "this_month":
            score_adjustment += 5

        # Check budget
        if qualification_data.get("has_budget"):
            score_adjustment += 15

        # Check decision maker
        if qualification_data.get("is_decision_maker"):
            score_adjustment += 10

        # Update lead
        lead.score = min(lead.score + score_adjustment, 100)
        lead.stage = "qualify"
        lead.last_activity = datetime.utcnow().isoformat()
        lead.metadata.update(qualification_data)

        self.funnel_stats["qualify"] += 1
        logger.info(f"Lead qualified: {lead_id} - New score: {lead.score}")

        # Trigger GHL workflow if high score
        if lead.score >= 70 and self.ghl_skill:
            self._trigger_hot_lead_workflow(lead)

        return lead

    def _trigger_hot_lead_workflow(self, lead: FunnelLead) -> Dict[str, Any]:
        """Trigger GHL workflow for hot leads."""
        if not self.ghl_skill:
            return {}

        try:
            return self.ghl_skill.execute(
                "trigger_workflow",
                location_id=os.getenv("GHL_LOCATION_ID", ""),
                workflow_id=os.getenv("GHL_HOT_LEAD_WORKFLOW_ID", ""),
                contact_id=lead.metadata.get("ghl_contact_id", ""),
                event_data={"lead_score": lead.score, "niche": lead.niche}
            )
        except Exception as e:
            logger.error(f"Workflow trigger failed: {e}")
            return {"error": str(e)}

    # ===== NURTURE STAGE =====

    def nurture_lead(self, lead_id: str, nurture_action: str,
                     content: Dict[str, Any] = None) -> FunnelLead:
        """
        Move lead to nurture stage and apply nurture sequence.

        Args:
            lead_id: Lead ID
            nurture_action: Type of nurture (email_sequence, sms_drip, retarget)
            content: Nurture content details

        Returns:
            Updated FunnelLead
        """
        if lead_id not in self.leads:
            raise ValueError(f"Lead not found: {lead_id}")

        lead = self.leads[lead_id]
        lead.stage = "nurture"
        lead.last_activity = datetime.utcnow().isoformat()

        nurture_data = {
            "nurture_action": nurture_action,
            "nurture_started": datetime.utcnow().isoformat(),
            **(content or {})
        }
        lead.metadata.update(nurture_data)

        self.funnel_stats["nurture"] += 1
        logger.info(f"Lead in nurture: {lead_id} - Action: {nurture_action}")

        return lead

    def get_nurture_content(self, lead: FunnelLead) -> Dict[str, Any]:
        """Get personalized nurture content for a lead."""
        niche_data = self.NICHE_DATA.get(lead.niche, {})

        return {
            "email_subject": f"Your {lead.niche.capitalize()} question answered",
            "email_body": f"Hi {lead.first_name},\n\n{niche_data.get('value_prop', '')}\n\nReady to chat?",
            "sms_text": f"Hi {lead.first_name}! Quick question about your {lead.niche} needs. Reply YES to connect.",
            "pain_points": niche_data.get("pain_points", []),
            "value_prop": niche_data.get("value_prop", "")
        }

    # ===== CONVERT STAGE =====

    def convert_lead(self, lead_id: str, conversion_data: Dict[str, Any]) -> FunnelLead:
        """
        Convert a lead to customer.

        Args:
            lead_id: Lead ID
            conversion_data: Conversion details (deal_value, service_type, etc.)

        Returns:
            Updated FunnelLead
        """
        if lead_id not in self.leads:
            raise ValueError(f"Lead not found: {lead_id}")

        lead = self.leads[lead_id]
        lead.stage = "convert"
        lead.last_activity = datetime.utcnow().isoformat()
        lead.metadata.update({
            "converted_at": datetime.utcnow().isoformat(),
            **conversion_data
        })

        self.funnel_stats["convert"] += 1
        logger.info(f"Lead converted: {lead_id} - Value: ${conversion_data.get('deal_value', 0)}")

        return lead

    # ===== FUNNEL PROCESSING =====

    def process(self, lead_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        Process a lead through the funnel.
        Main entry point for funnel operations.

        Args:
            lead_data: Lead information including stage action

        Returns:
            Processing result
        """
        action = lead_data.get("action", "capture")

        if action == "capture":
            lead = self.capture_lead(
                first_name=lead_data.get("first_name", ""),
                last_name=lead_data.get("last_name", ""),
                email=lead_data.get("email", ""),
                phone=lead_data.get("phone", ""),
                niche=lead_data.get("niche", "general"),
                service_area=lead_data.get("service_area", ""),
                source=lead_data.get("source", "website"),
                metadata=lead_data.get("metadata", {})
            )
            return {"status": "captured", "lead": lead.to_dict()}

        elif action == "qualify":
            lead = self.qualify_lead(
                lead_id=lead_data.get("lead_id"),
                qualification_data=lead_data.get("qualification", {})
            )
            return {"status": "qualified", "lead": lead.to_dict()}

        elif action == "nurture":
            lead = self.nurture_lead(
                lead_id=lead_data.get("lead_id"),
                nurture_action=lead_data.get("nurture_action", "email_sequence"),
                content=lead_data.get("content", {})
            )
            return {"status": "nurturing", "lead": lead.to_dict()}

        elif action == "convert":
            lead = self.convert_lead(
                lead_id=lead_data.get("lead_id"),
                conversion_data=lead_data.get("conversion", {})
            )
            return {"status": "converted", "lead": lead.to_dict()}

        else:
            return {"error": f"Unknown action: {action}"}

    # ===== COPY GENERATION =====

    def generate_copy_variants(self, niche: str, tone: str = "Professional") -> Dict[str, str]:
        """Generate high-converting copy for a niche."""
        if niche not in self.NICHE_DATA:
            return {
                "headline": "Modern AI Solutions for Your Business",
                "subheadline": "Scale faster with voice technology.",
                "cta": "Get Started"
            }

        data = self.NICHE_DATA[niche]
        logger.info(f"Generating {tone} copy for {niche}")

        return {
            "headline": f"Your New 24/7 AI Receptionist: Never Miss a {niche.capitalize()} Lead Again.",
            "subheadline": data["value_prop"],
            "cta": "Get Your AI Agent Demo",
            "pain_points": data["pain_points"],
            "keywords": data["keywords"],
            "avg_ticket": data["avg_ticket"]
        }

    def validate_conversion_pathway(self, funnel_json: Dict[str, Any]) -> List[str]:
        """Analyze funnel for conversion leaks."""
        feedback = []

        if "form" not in funnel_json:
            feedback.append("CRITICAL: No lead capture form detected.")
        if not funnel_json.get("mobile_responsive"):
            feedback.append("WARNING: Not optimized for mobile-first tradies.")
        if not funnel_json.get("urgency_indicator"):
            feedback.append("SUGGESTION: Add urgency qualifier (emergency vs scheduled).")
        if not funnel_json.get("social_proof"):
            feedback.append("SUGGESTION: Add testimonials or review count.")

        return feedback or ["Funnel pathway looks optimal."]

    # ===== ANALYTICS =====

    def get_funnel_metrics(self) -> Dict[str, Any]:
        """Get funnel performance metrics."""
        return {
            "stage_counts": self.funnel_stats,
            "total_leads": len(self.leads),
            "conversion_rate": (
                (self.funnel_stats["convert"] / self.funnel_stats["capture"] * 100)
                if self.funnel_stats["capture"] > 0 else 0
            ),
            "avg_score": (
                sum(l.score for l in self.leads.values()) / len(self.leads)
                if self.leads else 0
            ),
            "by_niche": self._get_niche_breakdown(),
            "by_source": self._get_source_breakdown()
        }

    def _get_niche_breakdown(self) -> Dict[str, int]:
        """Get lead count by niche."""
        breakdown = {}
        for lead in self.leads.values():
            breakdown[lead.niche] = breakdown.get(lead.niche, 0) + 1
        return breakdown

    def _get_source_breakdown(self) -> Dict[str, int]:
        """Get lead count by source."""
        breakdown = {}
        for lead in self.leads.values():
            breakdown[lead.source] = breakdown.get(lead.source, 0) + 1
        return breakdown

    def execute(self, action: str, **kwargs) -> Dict[str, Any]:
        """Generic action executor for skill interface."""
        action_map = {
            "capture": lambda **kw: self.capture_lead(**kw).to_dict(),
            "qualify": lambda **kw: self.qualify_lead(**kw).to_dict(),
            "nurture": lambda **kw: self.nurture_lead(**kw).to_dict(),
            "convert": lambda **kw: self.convert_lead(**kw).to_dict(),
            "process": self.process,
            "generate_copy": self.generate_copy_variants,
            "validate_pathway": self.validate_conversion_pathway,
            "get_metrics": self.get_funnel_metrics
        }

        if action not in action_map:
            return {"error": f"Unknown action: {action}", "available": list(action_map.keys())}

        try:
            return action_map[action](**kwargs)
        except Exception as e:
            return {"error": str(e)}


if __name__ == "__main__":
    # Self-test
    architect = TradieFunnelArchitectSkill()

    # Test funnel flow
    print("\n=== Tradie Funnel Test ===")

    # Capture
    lead = architect.capture_lead(
        first_name="Mike",
        last_name="Smith",
        email="mike@example.com",
        phone="+61400111222",
        niche="plumber",
        service_area="Sydney",
        source="facebook",
        metadata={"urgency": "emergency"}
    )
    print(f"Captured: {lead.first_name} - Score: {lead.score}")

    # Qualify
    lead = architect.qualify_lead(
        lead_id=lead.lead_id,
        qualification_data={
            "urgency": "emergency",
            "has_budget": True,
            "is_decision_maker": True,
            "service_needed": "blocked drain"
        }
    )
    print(f"Qualified: Score now {lead.score}")

    # Convert
    lead = architect.convert_lead(
        lead_id=lead.lead_id,
        conversion_data={"deal_value": 450, "service": "emergency_drain_clear"}
    )
    print(f"Converted: {lead.stage}")

    # Copy generation
    copy = architect.generate_copy_variants("plumber")
    print(f"\nGenerated Copy: {copy['headline']}")

    # Metrics
    print(f"\nFunnel Metrics: {architect.get_funnel_metrics()}")
