"""Demo data: one campaign, its rule set, its templates and 15 prospects.

The prospects are deliberately mixed - CEOs, founders, owners, the wrong
industry, the wrong location, a student, an intern and a recruiter - so the rule
engine visibly qualifies some and rejects others.
"""

from __future__ import annotations

from datetime import date, timedelta
from typing import Any

from sqlalchemy import select
from sqlalchemy.orm import Session

from app.models import (
    Campaign,
    CampaignSettings,
    Lead,
    MessageTemplate,
    MessageVariant,
    OutreachTask,
    Rule,
    User,
)
from app.models.enums import (
    CampaignStatus,
    ReplyStatus,
    RuleAction,
    RuleMatchType,
    RuleOperator,
    TaskType,
)
from app.rules.defaults import GLOBAL_RULE_SEEDS
from app.services import lead_service, outreach_service, scoring_service

DEMO_CAMPAIGN_NAME = "USA Real Estate CEOs"

CAMPAIGN_RULES: list[dict[str, Any]] = [
    {"name": "CEO", "field": "jobTitle", "operator": RuleOperator.CONTAINS, "value": "CEO",
     "action": RuleAction.SCORE, "points": 30, "priority": 100},
    {"name": "Founder", "field": "jobTitle", "operator": RuleOperator.CONTAINS, "value": "Founder",
     "action": RuleAction.SCORE, "points": 25, "priority": 101},
    {"name": "Owner", "field": "jobTitle", "operator": RuleOperator.CONTAINS, "value": "Owner",
     "action": RuleAction.SCORE, "points": 20, "priority": 102},
    {"name": "Managing Director", "field": "jobTitle", "operator": RuleOperator.CONTAINS,
     "value": "Managing Director", "action": RuleAction.SCORE, "points": 20, "priority": 103},
    {"name": "Real Estate industry", "field": "industry", "operator": RuleOperator.CONTAINS,
     "value": "real estate", "action": RuleAction.SCORE, "points": 30, "priority": 110},
    {"name": "United States", "field": "location", "operator": RuleOperator.CONTAINS,
     "value": "United States", "action": RuleAction.SCORE, "points": 20, "priority": 120},
    {"name": "Company size 10-100", "field": "companySize", "operator": RuleOperator.BETWEEN,
     "value": "10", "value2": "100", "action": RuleAction.SCORE, "points": 15, "priority": 130},
    {"name": "Use the CEO template", "field": "jobTitle", "operator": RuleOperator.CONTAINS,
     "value": "CEO", "action": RuleAction.SELECT_TEMPLATE, "action_value": "CEO connection",
     "priority": 300},
    {"name": "Use the Founder template", "field": "jobTitle", "operator": RuleOperator.CONTAINS,
     "value": "Founder", "action": RuleAction.SELECT_TEMPLATE,
     "action_value": "Founder connection", "priority": 301},
    {"name": "Real estate personalisation", "field": "industry", "operator": RuleOperator.CONTAINS,
     "value": "real estate", "action": RuleAction.ADD_PHRASE,
     "action_value": "I've been building sites and CRMs for {companyDescriptor}s in property.",
     "priority": 400},
]

TEMPLATES: list[dict[str, Any]] = [
    {
        "name": "CEO connection",
        "category": "connection",
        "priority": 10,
        "conditions": [{"field": "jobTitle", "operator": "contains", "value": "CEO"}],
        "body": (
            "Hi {firstName|there}, I came across {company} while researching "
            "{industry|your industry} companies in {location|your area}. "
            "{{#if companySize less_than 50}}Always interested in how a {companyDescriptor} "
            "handles its tooling.{{else}}Curious how your team handles its tooling.{{/if}} "
            "Would be great to connect."
        ),
        "description": "Used when the job title contains CEO.",
    },
    {
        "name": "Founder connection",
        "category": "connection",
        "priority": 20,
        "conditions": [{"field": "jobTitle", "operator": "regex", "value": "founder|co-founder"}],
        "body": (
            "Hi {firstName|there}, I noticed you founded {company}. "
            "I work with founders of {companyDescriptor}s on websites, CRMs and automation. "
            "Would be great to connect."
        ),
        "description": "Used when the job title contains Founder.",
    },
    {
        "name": "Real estate connection",
        "category": "connection",
        "priority": 30,
        "conditions": [{"field": "industry", "operator": "contains", "value": "real estate"}],
        "body": (
            "Hi {firstName|there}, I came across your profile while researching "
            "{industry} companies in {location|your area}. Would be great to connect."
        ),
        "description": "Used for any real estate prospect that is not a CEO or founder.",
    },
    {
        "name": "General connection",
        "category": "connection",
        "priority": 100,
        "is_default": True,
        "body": "Hi {firstName|there}, I came across {company} and thought it would be great to connect.",
        "description": "Fallback connection note with three rotating variations.",
        "variants": [
            {
                "name": "Variation A",
                "body": "Hi {firstName|there}, I came across {company} and thought it would be great to connect.",
            },
            {
                "name": "Variation B",
                "body": "Hi {firstName|there}, noticed you're working in {industry|your field}. I'd love to connect and exchange ideas.",
            },
            {
                "name": "Variation C",
                "body": "Hi {firstName|there}, I came across your profile while researching {industry|your industry} companies in {location|your area}. Would be great to connect.",
            },
        ],
    },
    {
        "name": "First message",
        "category": "first_message",
        "priority": 100,
        "is_default": True,
        "body": (
            "Thanks for connecting, {firstName|there}. {industryPhrase}\n\n"
            "{{#if jobTitle contains CEO}}Since you're running {company}, you'd know better than "
            "anyone where the manual work sits.{{else}}Curious whether that's on your radar at "
            "{company}.{{/if}} Worth a short chat?"
        ),
    },
    {
        "name": "Follow-up 1",
        "category": "follow_up_1",
        "priority": 100,
        "is_default": True,
        "body": (
            "Hi {firstName|there}, just floating this back to the top of your inbox. "
            "Happy to share a couple of examples of what we built for other "
            "{industry|similar} teams if that's useful."
        ),
    },
    {
        "name": "Follow-up 2",
        "category": "follow_up_2",
        "priority": 100,
        "is_default": True,
        "body": (
            "Hi {firstName|there}, no worries if the timing isn't right. "
            "If it helps, I can send over a one-page outline of how we'd approach it for {company}."
        ),
    },
    {
        "name": "Follow-up 3",
        "category": "follow_up_3",
        "priority": 100,
        "is_default": True,
        "body": (
            "Hi {firstName|there}, last note from me so I'm not cluttering your inbox. "
            "If it becomes relevant later, I'm easy to find here."
        ),
    },
]

DEMO_LEADS: list[dict[str, Any]] = [
    {
        "full_name": "John Smith", "job_title": "CEO", "company": "ABC Realty",
        "industry": "Real Estate", "location": "Austin, United States", "company_size": 42,
        "headline": "CEO at ABC Realty | Residential property investment",
        "about": "Building a residential brokerage across Texas.",
        "profile_url": "https://www.linkedin.com/in/john-smith-abc-realty",
        "website": "https://abcrealty.example.com",
    },
    {
        "full_name": "Maria Gonzalez", "job_title": "Founder", "company": "Sunrise Property Group",
        "industry": "Real Estate", "location": "Miami, United States", "company_size": 18,
        "headline": "Founder at Sunrise Property Group | Property management",
        "profile_url": "https://www.linkedin.com/in/maria-gonzalez-sunrise",
    },
    {
        "full_name": "David Chen", "job_title": "Owner", "company": "Chen Brokerage",
        "industry": "Real Estate", "location": "Seattle, United States", "company_size": 12,
        "headline": "Owner at Chen Brokerage | Commercial realtor",
        "profile_url": "https://www.linkedin.com/in/david-chen-brokerage",
        "website": "https://chenbrokerage.example.com",
    },
    {
        "full_name": "Priya Raman", "job_title": "Managing Director",
        "company": "Metro Realty Partners", "industry": "Real Estate",
        "location": "Chicago, United States", "company_size": 150,
        "headline": "Managing Director at Metro Realty Partners",
        "profile_url": "https://www.linkedin.com/in/priya-raman-metro",
        "website": "https://metrorealty.example.com",
    },
    {
        "full_name": "Carlos Mendes", "job_title": "Owner & Real Estate Investor",
        "company": "Mendes Holdings", "industry": "Real Estate",
        "location": "Phoenix, United States",
        "headline": "Owner at Mendes Holdings | Multifamily property investor",
        "profile_url": "https://www.linkedin.com/in/carlos-mendes-holdings",
    },
    {
        "full_name": "Nina Patel", "job_title": "VP of Operations",
        "company": "Skyline Realty Group", "industry": "Real Estate",
        "location": "Atlanta, United States", "company_size": 90,
        "headline": "VP Operations at Skyline Realty Group",
        "profile_url": "https://www.linkedin.com/in/nina-patel-skyline",
        "website": "https://skylinerealty.example.com",
    },
    {
        "full_name": "Tom Becker", "job_title": "CEO", "company": "Becker Construction",
        "industry": "Construction", "location": "Denver, United States", "company_size": 60,
        "headline": "CEO at Becker Construction | Commercial builds",
        "profile_url": "https://www.linkedin.com/in/tom-becker-construction",
        "website": "https://beckerconstruction.example.com",
    },
    {
        "full_name": "Robert Kline", "job_title": "CEO", "company": None,
        "industry": "Real Estate", "location": "Houston, United States",
        "headline": "CEO | Independent real estate consultant",
        "profile_url": "https://www.linkedin.com/in/robert-kline-re",
    },
    {
        "full_name": "Alex Turner", "job_title": "Marketing Manager", "company": "Bright Homes",
        "industry": "Real Estate", "location": "New York, United States", "company_size": 35,
        "headline": "Marketing Manager at Bright Homes",
        "profile_url": "https://www.linkedin.com/in/alex-turner-bright",
    },
    {
        "full_name": "Emily Watson", "job_title": "Founder", "company": "Watson Interiors",
        "industry": "Interior Design", "location": "Portland, United States", "company_size": 8,
        "headline": "Founder at Watson Interiors",
        "profile_url": "https://www.linkedin.com/in/emily-watson-interiors",
        "website": "https://watsoninteriors.example.com",
    },
    {
        "full_name": "Sofia Almeida", "job_title": "CEO", "company": "Lisboa Imobiliaria",
        "industry": "Real Estate", "location": "Lisbon, Portugal", "company_size": 5,
        "headline": "CEO at Lisboa Imobiliaria | Property sales",
        "profile_url": "https://www.linkedin.com/in/sofia-almeida-lisboa",
    },
    {
        "full_name": "Michael Osei", "job_title": "CTO", "company": "FinEdge Analytics",
        "industry": "Financial Services", "location": "London, United Kingdom",
        "company_size": 80, "headline": "CTO at FinEdge Analytics",
        "profile_url": "https://www.linkedin.com/in/michael-osei-finedge",
        "website": "https://finedge.example.com",
    },
    {
        "full_name": "Rachel Adams", "job_title": "Student", "company": "University of Texas",
        "industry": "Education", "location": "Austin, United States",
        "headline": "Student | Real estate finance major",
        "profile_url": "https://www.linkedin.com/in/rachel-adams-ut",
    },
    {
        "full_name": "Kevin Brooks", "job_title": "Marketing Intern", "company": "HomeSpark",
        "industry": "Real Estate", "location": "Boston, United States", "company_size": 30,
        "headline": "Marketing Intern at HomeSpark",
        "profile_url": "https://www.linkedin.com/in/kevin-brooks-homespark",
    },
    {
        "full_name": "Laura Diaz", "job_title": "Technical Recruiter", "company": "TalentBridge",
        "industry": "Staffing & Recruiting", "location": "Dallas, United States",
        "company_size": 200, "headline": "Technical Recruiter at TalentBridge",
        "profile_url": "https://www.linkedin.com/in/laura-diaz-talentbridge",
    },
]


def seed_user(db: Session) -> User:
    user = db.scalars(select(User).order_by(User.id)).first()
    if user is None:
        user = User(
            name="Alex Morgan",
            email="alex@example.com",
            company="Easylife Studio",
            job_title="Founder",
            calendar_link="https://cal.example.com/alex",
        )
        db.add(user)
        db.flush()
    return user


def seed_global_rules(db: Session) -> int:
    created = 0
    for spec in GLOBAL_RULE_SEEDS:
        exists = db.scalars(
            select(Rule).where(Rule.name == spec["name"], Rule.campaign_id.is_(None))
        ).first()
        if exists is not None:
            continue
        db.add(Rule(campaign_id=None, **spec))
        created += 1
    db.flush()
    return created


def seed_campaign_rules(db: Session, campaign: Campaign) -> int:
    created = 0
    for spec in CAMPAIGN_RULES:
        exists = db.scalars(
            select(Rule).where(Rule.name == spec["name"], Rule.campaign_id == campaign.id)
        ).first()
        if exists is not None:
            continue
        db.add(Rule(campaign_id=campaign.id, **spec))
        created += 1
    db.flush()
    return created


def seed_templates(db: Session, campaign: Campaign) -> int:
    created = 0
    for spec in TEMPLATES:
        exists = db.scalars(
            select(MessageTemplate).where(
                MessageTemplate.name == spec["name"], MessageTemplate.campaign_id == campaign.id
            )
        ).first()
        if exists is not None:
            continue
        variants = spec.pop("variants", [])
        template = MessageTemplate(
            campaign_id=campaign.id, match_type=RuleMatchType.ALL, **spec
        )
        for variant in variants:
            template.variants.append(MessageVariant(**variant))
        db.add(template)
        created += 1
        if variants:
            spec["variants"] = variants
    db.flush()
    return created


def seed_campaign(db: Session) -> Campaign:
    campaign = db.scalars(select(Campaign).where(Campaign.name == DEMO_CAMPAIGN_NAME)).first()
    if campaign is None:
        campaign = Campaign(
            name=DEMO_CAMPAIGN_NAME,
            description="Decision makers at small and mid-size US real estate businesses.",
            status=CampaignStatus.ACTIVE,
            target_industries=["Real Estate"],
            target_locations=["United States"],
            target_titles=["CEO", "Founder", "Owner", "Managing Director"],
            keywords=["real estate", "property", "realtor", "brokerage"],
            exclude_keywords=["recruiter", "student", "intern"],
            company_size_min=10,
            company_size_max=100,
            min_score=70,
            outreach_objective=(
                "Offer website development, SaaS/CRM builds and workflow automation."
            ),
        )
        db.add(campaign)
        db.flush()
        db.add(CampaignSettings(campaign_id=campaign.id, followup_days=[3, 7, 14]))
        db.flush()
    return campaign


def seed_all(db: Session, reset: bool = False) -> dict[str, Any]:
    """Create (or refresh) the full demo dataset. Returns a small summary."""
    if reset:
        existing = db.scalars(select(Campaign).where(Campaign.name == DEMO_CAMPAIGN_NAME)).first()
        if existing is not None:
            db.delete(existing)
            db.commit()

    seed_user(db)
    seed_global_rules(db)
    campaign = seed_campaign(db)
    seed_campaign_rules(db, campaign)
    seed_templates(db, campaign)
    db.commit()

    created_leads = 0
    for payload in DEMO_LEADS:
        data = dict(payload)
        data["source"] = "demo"
        lead, created = lead_service.create_lead(db, data, campaign, source="demo")
        if created:
            created_leads += 1
    db.commit()

    for lead in db.scalars(select(Lead).where(Lead.campaign_id == campaign.id)).all():
        scoring_service.score_lead(db, lead, campaign, record_history=False)
    db.commit()

    outreach_service.generate_tasks_for_campaign(db, campaign, only_qualified=False)
    _simulate_progress(db, campaign)

    total = len(db.scalars(select(Lead).where(Lead.campaign_id == campaign.id)).all())
    return {"campaign": campaign.name, "leads": total, "created": created_leads}


def _simulate_progress(db: Session, campaign: Campaign) -> None:
    """Complete a couple of tasks and log one reply so the analytics are not empty."""
    john = db.scalars(
        select(Lead).where(Lead.campaign_id == campaign.id, Lead.full_name == "John Smith")
    ).first()
    maria = db.scalars(
        select(Lead).where(Lead.campaign_id == campaign.id, Lead.full_name == "Maria Gonzalez")
    ).first()

    if john is not None:
        task = db.scalars(
            select(OutreachTask).where(
                OutreachTask.lead_id == john.id,
                OutreachTask.task_type == TaskType.CONNECTION_REQUEST.value,
                OutreachTask.status == "pending",
            )
        ).first()
        if task is not None:
            outreach_service.approve_task(db, task)
            outreach_service.complete_task(db, task, notes="Invite sent manually on LinkedIn")

    if maria is not None:
        task = db.scalars(
            select(OutreachTask).where(
                OutreachTask.lead_id == maria.id,
                OutreachTask.task_type == TaskType.CONNECTION_REQUEST.value,
                OutreachTask.status == "pending",
            )
        ).first()
        if task is not None:
            outreach_service.complete_task(db, task)
            task.completed_at = task.completed_at - timedelta(days=2)
            task.scheduled_date = date.today() - timedelta(days=2)
        outreach_service.record_reply(
            db, maria, ReplyStatus.INTERESTED.value, "Sounds interesting, send more details."
        )
    db.commit()
