"""Marketing público, waitlist, UTM y insights diferenciadores."""

from __future__ import annotations

import secrets
from collections import Counter
from datetime import datetime, timezone

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session

from app.api.deps import get_current_user, require_admin
from app.core.database import get_db
from app.models import Application, Job, JobScore, MarketingEvent, MarketingLead, User

router = APIRouter(prefix="/marketing", tags=["marketing"])


class LeadIn(BaseModel):
    email: str = Field(min_length=3, max_length=255)
    name: str = ""
    interest: str = "waitlist"
    message: str = ""
    utm_source: str | None = None
    utm_medium: str | None = None
    utm_campaign: str | None = None
    referral_code: str | None = None
    privacy_accepted: bool = False


class EventIn(BaseModel):
    event: str = Field(min_length=2, max_length=64)
    path: str = "/"
    utm_source: str | None = None
    utm_medium: str | None = None
    utm_campaign: str | None = None
    meta: dict = Field(default_factory=dict)


class LeadOut(BaseModel):
    id: int
    email: str
    name: str
    interest: str
    message: str
    utm_source: str | None = None
    utm_campaign: str | None = None
    created_at: datetime | None = None

    model_config = {"from_attributes": True}


@router.get("/playbook")
def playbook_public():
    """Playbook de captación rápida (volumen × precio irresistible)."""
    return {
        "positioning": (
            "JobsWorld es el copiloto de empleo para España e internacional: "
            "feed unificado, IA local (privacidad del CV), revisión humana antes de enviar, "
            "y un precio mensual pensado para que TODO el mundo se suscriba — no un club exclusivo a 40€."
        ),
        "pricing_strategy": {
            "thesis": "Muchos usuarios a precio irrechazable > pocos a precio Teal/Huntr.",
            "hero_plan": "profesional",
            "anchor": "Teal/Huntr ~25–40 €/mes → nosotros Profesional ~15 € y Esencial ~8 €.",
            "volume_play": "Free potente + upsell suave tras primera adaptación IA exitosa.",
        },
        "differentiators": [
            {
                "title": "España-first + internacional potente",
                "why": "Teal/Huntr son US-centric; nosotros cubrimos InfoJobs/SEPE/ETT + remoto global.",
            },
            {
                "title": "CV con revisión obligatoria",
                "why": "No auto-spam: borrador → apruebas secciones → aplicas. Más ético y mejor señal a RRHH.",
            },
            {
                "title": "IA local (Ollama) + opción self-host",
                "why": "Privacidad del CV: el currículum no tiene que salir a SaaS USA.",
            },
            {
                "title": "Compatible con inglés no fluido",
                "why": "Filtros y scoring pensados para candidatos ES que buscan remoto EU/US sin EN nativo.",
            },
            {
                "title": "Precio de volumen",
                "why": "Suscripción mensual asequible: más gente convierte, más boca a boca.",
            },
            {
                "title": "Extracción de contacto del publicador",
                "why": "Email/LinkedIn/teléfono cuando aparecen en la oferta — ventaja frente a trackers pasivos.",
            },
            {
                "title": "Cualquier puesto, no solo tech",
                "why": "Categorías, roles y portales generalistas + ejecutivos + servicios.",
            },
        ],
        "channels_30_days": [
            {
                "channel": "SEO local + landing",
                "action": "Páginas / y /pricing indexables; keywords: 'buscar trabajo Valencia', 'adaptar CV oferta', 'empleo remoto desde España'.",
                "effort": "bajo",
            },
            {
                "channel": "LinkedIn orgánico",
                "action": "Cola de campañas en /admin/launch (7 posts semana 1) con UTM; CTA a Profesional.",
                "effort": "medio",
            },
            {
                "channel": "Comunidades ES",
                "action": "Reddit r/spain, foros InfoJobs, Discord/Telegram empleo, grupos Facebook provincias.",
                "effort": "medio",
            },
            {
                "channel": "Product Hunt / BetaList",
                "action": "Lanzamiento EN+ES con 14 días Profesional para early adopters.",
                "effort": "bajo",
            },
            {
                "channel": "Micro-influencers empleo",
                "action": "Career coaches ES con referral_code = 1 mes Profesional por lead convertido.",
                "effort": "alto",
            },
            {
                "channel": "Ads baratos de validación",
                "action": "50–100€ Meta/Google Ads a /pricing?utm_campaign=valencia_jobs; CPL waitlist < 3€.",
                "effort": "medio",
            },
            {
                "channel": "Partnerships ETT / bootcamps",
                "action": "White-label BrandPack Partner + cohort Esencial a precio academia.",
                "effort": "alto",
            },
            {
                "channel": "Referral viral",
                "action": "3 referidos → 1 mes Profesional. Código en /invite.",
                "effort": "bajo",
            },
            {
                "channel": "Agente lab → Bridge",
                "action": "Inbox /agent-ops: el lab propone campañas; al aceptar Cursor las ejecuta.",
                "effort": "bajo",
            },
        ],
        "offer_hooks": [
            "Gratis para siempre el feed básico — paga solo cuando la IA te ahorra horas",
            "Profesional al precio de un menú del día × 3: irrechazable vs Teal",
            "7 días Carrera Max con código LANZAMIENTO",
            "Comparativa antes/después de CV adaptado a una oferta real",
            "Checklist PDF: 'Remoto desde España sin inglés fluido'",
        ],
        "kpis_week_1": [
            "500 visitas landing",
            "80 registros free",
            "15 upgrades a Esencial/Profesional",
            "CPL waitlist < 3€ si hay ads",
            "3 propuestas agente aceptadas y ejecutadas",
        ],
        "launch_week": [
            "D1: post problema (pestañas) + CTA free",
            "D2: demo 60s War Room / CV",
            "D3: precio vs Teal",
            "D4: historia privacidad IA local",
            "D5: insight salarial semanal (lead magnet)",
            "D6: referral challenge",
            "D7: case study + urgencia early adopter",
        ],
    }


@router.post("/leads", response_model=LeadOut)
def create_lead(payload: LeadIn, db: Session = Depends(get_db)):
    if not payload.privacy_accepted:
        raise HTTPException(400, "Debes aceptar la política de privacidad")
    lead = MarketingLead(
        email=str(payload.email).lower().strip(),
        name=payload.name or "",
        interest=payload.interest or "waitlist",
        message=payload.message or "",
        utm_source=payload.utm_source,
        utm_medium=payload.utm_medium,
        utm_campaign=payload.utm_campaign,
        referral_code=payload.referral_code,
    )
    db.add(lead)
    db.add(
        MarketingEvent(
            event="lead_submit",
            path="/",
            utm_source=payload.utm_source,
            utm_medium=payload.utm_medium,
            utm_campaign=payload.utm_campaign,
            meta={"interest": payload.interest},
        )
    )
    db.commit()
    db.refresh(lead)
    return lead


@router.post("/events")
def track_event(payload: EventIn, db: Session = Depends(get_db)):
    db.add(
        MarketingEvent(
            event=payload.event,
            path=payload.path or "/",
            utm_source=payload.utm_source,
            utm_medium=payload.utm_medium,
            utm_campaign=payload.utm_campaign,
            meta=payload.meta or {},
        )
    )
    db.commit()
    return {"ok": True}


@router.get("/admin/leads", response_model=list[LeadOut])
def admin_leads(admin: User = Depends(require_admin), db: Session = Depends(get_db)):
    return db.query(MarketingLead).order_by(MarketingLead.created_at.desc()).limit(200).all()


@router.get("/admin/stats")
def admin_mkt_stats(admin: User = Depends(require_admin), db: Session = Depends(get_db)):
    from sqlalchemy import func

    leads = db.query(MarketingLead).count()
    events = db.query(MarketingEvent).count()
    by_src: Counter[str] = Counter()
    for e in db.query(MarketingEvent).order_by(MarketingEvent.id.desc()).limit(2000):
        by_src[e.utm_source or "(direct)"] += 1
    refs = (
        db.query(User.referred_by, func.count(User.id))
        .filter(User.referred_by.isnot(None))
        .group_by(User.referred_by)
        .all()
    )
    return {
        "leads": leads,
        "events": events,
        "utm_sources": dict(by_src.most_common(15)),
        "referrals": {r[0]: r[1] for r in refs if r[0]},
    }


@router.get("/me/referral")
def my_referral(user: User = Depends(get_current_user), db: Session = Depends(get_db)):
    if not user.referral_code:
        user.referral_code = secrets.token_urlsafe(6).replace("-", "")[:10].upper()
        db.commit()
        db.refresh(user)
    return {
        "referral_code": user.referral_code,
        "share_url": f"/?ref={user.referral_code}",
        "marketing_consent": bool(user.marketing_consent),
    }


@router.get("/insights/weekly")
def weekly_insight(user: User = Depends(get_current_user), db: Session = Depends(get_db)):
    """Insight semanal diferenciador: gaps de mercado vs perfil."""
    scores = (
        db.query(JobScore)
        .filter(JobScore.user_id == user.id)
        .order_by(JobScore.match_score.desc())
        .limit(80)
        .all()
    )
    apps = db.query(Application).filter(Application.user_id == user.id).count()
    top = []
    reason_counter: Counter[str] = Counter()
    for s in scores[:20]:
        job = db.get(Job, s.job_id)
        if not job:
            continue
        top.append(
            {
                "title": job.title,
                "company": job.company,
                "score": s.match_score,
                "source": job.source,
                "location": job.location,
            }
        )
        for r in s.reasons or []:
            reason_counter[str(r).split(":")[0].strip()] += 1

    profile = user.profile
    gaps = []
    if profile and not profile.english_fluent:
        gaps.append(
            "Hay ofertas internacionales que penalizan por inglés fluido: prioriza fuentes ES/LATAM o mejora el pitch en español."
        )
    if profile and profile.remote_only:
        gaps.append("Tu filtro 'solo remoto' reduce oportunidades locales (Valencia/Madrid). Prueba híbrido 1 día/semana.")
    if not top:
        gaps.append("Aún no hay scores: sincroniza Fuentes y completa roles/categorías en Perfil.")

    return {
        "generated_at": datetime.now(timezone.utc).isoformat(),
        "applications_tracked": apps,
        "top_matches": top[:8],
        "signal_heatmap": reason_counter.most_common(8),
        "gaps": gaps,
        "actions": [
            "Adapta el CV a las 3 ofertas con score > 70 y aprueba secciones antes de enviar.",
            "Comparte tu enlace referral para desbloquear mes gratis cuando actives el programa.",
            "En Marketing → canales, elige 1 canal y publica esta semana (constancia > perfección).",
        ],
        "moat_note": (
            "Esto no lo dan trackers genéricos: combina scoring local, gaps de perfil ES y plan de acción semanal."
        ),
    }


class CampaignIn(BaseModel):
    title: str = Field(min_length=2, max_length=160)
    channel: str = "linkedin"
    body: str = Field(min_length=2)
    utm_campaign: str = ""
    status: str = "draft"


class CampaignPatch(BaseModel):
    title: str | None = None
    channel: str | None = None
    body: str | None = None
    utm_campaign: str | None = None
    status: str | None = None


@router.get("/campaigns")
def campaigns_list(user: User = Depends(require_admin)):
    from app.services import campaigns as camp

    camp.seed_default_campaigns()
    return {"items": camp.list_campaigns()}


@router.post("/campaigns")
def campaigns_create(payload: CampaignIn, user: User = Depends(require_admin)):
    from app.services import campaigns as camp

    return camp.create_campaign(
        title=payload.title,
        channel=payload.channel,
        body=payload.body,
        utm_campaign=payload.utm_campaign,
        status=payload.status,
    )


@router.patch("/campaigns/{cid}")
def campaigns_patch(cid: str, payload: CampaignPatch, user: User = Depends(require_admin)):
    from app.services import campaigns as camp

    try:
        return camp.update_campaign(cid, **payload.model_dump(exclude_unset=True))
    except FileNotFoundError:
        raise HTTPException(404, "Campaña no encontrada") from None


@router.get("/automation/status")
def automation_status(_: User = Depends(require_admin)):
    from app.services import marketing_engine as eng

    return eng.status()


@router.post("/automation/generate-week")
def automation_generate_week(_: User = Depends(require_admin)):
    from app.services import marketing_engine as eng

    return eng.generate_week_pack(use_llm=True)


@router.post("/automation/publish-next")
def automation_publish_next(_: User = Depends(require_admin)):
    from app.services import marketing_engine as eng

    return eng.advance_ready_campaigns(limit=1)


@router.post("/automation/tick")
def automation_tick(_: User = Depends(require_admin)):
    from app.services import marketing_engine as eng

    return eng.auto_tick()

