"""
KPRO - KiessProspector Agent
Handles prospect intelligence, enrichment, and ICP scoring.
"""

from __future__ import annotations
import logging
from datetime import datetime
from typing import Optional

from ..core.agent import BaseAgent
from ..core.memory import MemoryEngine
from ..skills.prospect import ProspectSkill
from ..models.account import Account
from ..models.contact import Contact

logger = logging.getLogger(__name__)


class KiessProspectorAgent(BaseAgent):
    """
    Prospector agent responsible for:
    - Importing leads from CSV/API
    - Enriching company and contact data
    - Scoring ICP fit
    - Detecting buying signals
    """

    codename = "KPRO"
    name = "KiessProspector"
    description = "Prospect intelligence, enrichment, ICP scoring"

    def __init__(self, config: dict, memory: MemoryEngine):
        super().__init__(config, memory)
        self.prospect_skill = ProspectSkill(config)

    def run(self, task: str, **kwargs) -> str:
        """
        Execute a prospecting task.

        Supported tasks:
        - import: Import contacts from CSV
        - score: Score a contact for ICP fit
        - enrich: Enrich a contact or company
        - analyze: Analyze imported prospects
        """
        self.update_status("running", task)

        try:
            if task == "import" or "import" in task.lower():
                return self._handle_import(**kwargs)
            elif task == "score" or "score" in task.lower():
                return self._handle_score(**kwargs)
            elif task == "enrich" or "enrich" in task.lower():
                return self._handle_enrich(**kwargs)
            elif task == "analyze" or "analyze" in task.lower():
                return self._handle_analyze(**kwargs)
            else:
                # Use LLM to interpret the task
                return self._handle_natural_language(task, **kwargs)

        except Exception as e:
            logger.error(f"[KPRO] Error: {e}")
            self.update_status("error", task)
            return f"Error: {str(e)}"

        finally:
            self.update_status("idle")

    def _handle_import(self, file_path: str = None, **kwargs) -> str:
        """Import contacts from CSV file."""
        if not file_path:
            return "Error: file_path is required for import"

        # Import using skill
        raw_contacts = self.prospect_skill.import_csv(file_path)

        if raw_contacts and "error" in raw_contacts[0]:
            return f"Import failed: {raw_contacts[0]['error']}"

        # Process and score each contact
        processed = []
        qualified = 0
        accounts_created = {}

        for raw in raw_contacts:
            # Validate email
            validation = self.prospect_skill.validate_email(raw.get("email", ""))
            if not validation["valid"]:
                continue

            # Get or create account
            domain = raw.get("domain") or ""
            if domain and domain not in accounts_created:
                account = Account(
                    domain=domain,
                    name=raw.get("company", domain),
                    industry=raw.get("industry"),
                    employee_count=raw.get("employee_count"),
                )
                accounts_created[domain] = account

            # Create contact
            contact = Contact(
                account_id=accounts_created.get(domain, Account()).id if domain else "",
                email=raw["email"],
                first_name=raw.get("first_name", ""),
                last_name=raw.get("last_name", ""),
                title=raw.get("title"),
                phone=raw.get("phone"),
                linkedin_url=raw.get("linkedin_url"),
            )

            # Score ICP fit
            score_result = self.prospect_skill.score_icp_fit({
                "title": contact.title,
                "industry": raw.get("industry"),
                "employee_count": raw.get("employee_count"),
            })
            contact.icp_score = score_result["score"]

            if score_result["qualified"]:
                qualified += 1

            processed.append(contact)

        # Save to memory
        contacts_data = [c.to_dict() for c in processed]
        accounts_data = [a.to_dict() for a in accounts_created.values()]

        # Append to existing data
        existing_contacts = self.memory.load_data("contacts")
        existing_accounts = self.memory.load_data("accounts")

        # Deduplicate by email/domain
        existing_emails = {c["email"] for c in existing_contacts}
        existing_domains = {a["domain"] for a in existing_accounts}

        new_contacts = [c for c in contacts_data if c["email"] not in existing_emails]
        new_accounts = [a for a in accounts_data if a["domain"] not in existing_domains]

        self.memory.save_data("contacts", existing_contacts + new_contacts)
        self.memory.save_data("accounts", existing_accounts + new_accounts)

        # Log to memory
        self.memory.log(
            "kpro",
            f"**Import Complete**\n"
            f"- File: {file_path}\n"
            f"- Total processed: {len(processed)}\n"
            f"- New contacts: {len(new_contacts)}\n"
            f"- New accounts: {len(new_accounts)}\n"
            f"- Qualified (ICP >= {self.prospect_skill.min_icp_score}): {qualified}"
        )

        return (
            f"Import complete!\n"
            f"- Processed: {len(processed)} contacts\n"
            f"- New contacts added: {len(new_contacts)}\n"
            f"- New accounts added: {len(new_accounts)}\n"
            f"- Qualified leads: {qualified}"
        )

    def _handle_score(self, contact_id: str = None, email: str = None, **kwargs) -> str:
        """Score a contact for ICP fit."""
        contacts = self.memory.load_data("contacts")

        # Find contact
        contact_data = None
        for c in contacts:
            if (contact_id and c["id"] == contact_id) or (email and c["email"] == email):
                contact_data = c
                break

        if not contact_data:
            return f"Contact not found: {contact_id or email}"

        # Get account data for additional context
        accounts = self.memory.load_data("accounts")
        account_data = None
        for a in accounts:
            if a["id"] == contact_data.get("account_id"):
                account_data = a
                break

        # Build scoring input
        scoring_input = {
            "title": contact_data.get("title"),
            "seniority": contact_data.get("seniority"),
            "industry": account_data.get("industry") if account_data else None,
            "employee_count": account_data.get("employee_count") if account_data else None,
            "email": contact_data.get("email"),
            "linkedin_url": contact_data.get("linkedin_url"),
            "phone": contact_data.get("phone"),
        }

        result = self.prospect_skill.score_icp_fit(scoring_input)

        # Update contact score
        contact_data["icp_score"] = result["score"]
        self.memory.save_data("contacts", contacts)

        return (
            f"ICP Score for {contact_data['email']}: {result['score']}/100\n"
            f"Qualified: {'Yes' if result['qualified'] else 'No'}\n"
            f"Breakdown: {result['breakdown']}"
        )

    def _handle_enrich(self, domain: str = None, email: str = None, **kwargs) -> str:
        """Enrich a company or contact."""
        if domain:
            result = self.prospect_skill.enrich_company(domain)
            return f"Company enrichment: {result}"
        elif email:
            result = self.prospect_skill.enrich_contact(email)
            return f"Contact enrichment: {result}"
        else:
            return "Error: domain or email required for enrichment"

    def _handle_analyze(self, **kwargs) -> str:
        """Analyze imported prospects and provide insights."""
        contacts = self.memory.load_data("contacts")
        accounts = self.memory.load_data("accounts")

        if not contacts:
            return "No contacts found. Import some leads first."

        # Calculate stats
        total = len(contacts)
        qualified = sum(1 for c in contacts if c.get("icp_score", 0) >= self.prospect_skill.min_icp_score)
        avg_score = sum(c.get("icp_score", 0) for c in contacts) / total if total else 0

        # Status breakdown
        status_counts = {}
        for c in contacts:
            status = c.get("status", "new")
            status_counts[status] = status_counts.get(status, 0) + 1

        # Use LLM for insights
        context = (
            f"Prospect Database Analysis:\n"
            f"- Total contacts: {total}\n"
            f"- Total accounts: {len(accounts)}\n"
            f"- Qualified leads (ICP >= {self.prospect_skill.min_icp_score}): {qualified}\n"
            f"- Average ICP score: {avg_score:.1f}\n"
            f"- Status breakdown: {status_counts}\n"
        )

        response = self.think(
            user_message="Analyze this prospect database and provide 3-5 actionable insights for improving outreach effectiveness.",
            context=context,
        )

        return f"**Prospect Analysis**\n\n{context}\n\n**Insights:**\n{response.content}"

    def _handle_natural_language(self, task: str, **kwargs) -> str:
        """Handle natural language task requests."""
        # Get current data context
        contacts = self.memory.load_data("contacts")
        accounts = self.memory.load_data("accounts")

        context = (
            f"Current database:\n"
            f"- {len(contacts)} contacts\n"
            f"- {len(accounts)} accounts\n"
        )

        response = self.think(
            user_message=task,
            context=context,
        )

        return response.content
