"""Daily digest: compile 24h metrics and deliver as MCP notification.

The digest summarizes: invitations sent, acceptance rate, replies,
hot leads, job success/failure rates, and any issues detected.

Triggered by JOB_DAILY_DIGEST scheduled once per day.
"""

from __future__ import annotations

import logging
import time
from datetime import datetime

from ..db.queries import (
    count_inbound_dms_today,
    get_daily_auto_reply_count,
    get_daily_brand_engage_count,
    get_daily_brand_post_count,
    get_daily_engagement_counts_all,
    get_daily_signal_outreach_count,
    get_daily_voice_memo_count,
    get_job_metrics,
    get_rate_limit_today,
    get_recent_scheduler_events,
    get_scheduler_event_summary,
    get_sending_days_7d,
    get_weekly_invitation_sum,
    list_campaigns,
)
from ..constants import (
    DAILY_AUTO_REPLY_LIMIT,
    DAILY_BRAND_ENGAGE_LIMIT,
    DAILY_BRAND_POST_LIMIT,
    DAILY_ENDORSE_LIMIT,
    DAILY_ENGAGEMENT_LIMIT,
    DAILY_FOLLOW_LIMIT,
    DAILY_INBOUND_DM_LIMIT,
    DAILY_PROFILE_VIEW_LIMIT,
    DAILY_SIGNAL_OUTREACH_LIMIT,
    DAILY_VOICE_MEMO_LIMIT,
)

logger = logging.getLogger(__name__)


def compile_daily_digest() -> str:
    """Compile a plain-text daily digest of the last 24 hours.

    Returns markdown string suitable for MCP tool output or email body.
    """
    now = datetime.now()
    lines = [
        f"# Daily Digest — {now.strftime('%Y-%m-%d')}",
        "",
    ]

    # ── Rate Limits / Sends ──
    rl = get_rate_limit_today()
    sent = rl.get("sent", 0)
    daily_limit = rl.get("daily_limit", 15)
    lines.append("## Outreach")
    lines.append(f"- Invitations sent today: **{sent}/{daily_limit}**")
    lines.append("")

    # ── Weekly Limits ──
    from ..linkedin.rate_limiter import _get_effective_caps, estimate_weekly_limit_reset
    weekly_sent = get_weekly_invitation_sum()
    weekly_cap, daily_max = _get_effective_caps()
    weekly_pct = round(weekly_sent / weekly_cap * 100, 1) if weekly_cap > 0 else 0
    sending_days = get_sending_days_7d()

    lines.append("## Weekly Limits")
    lines.append(f"- LinkedIn invitations: **{weekly_sent}/{weekly_cap}** ({weekly_pct}%)")
    lines.append(f"- Daily max: {daily_max} | Sending days: {sending_days}/7")

    # Email overflow stats
    try:
        from ..db.queries import get_weekly_email_sum
        from ..constants import WEEKLY_EMAIL_OUTREACH_CAP
        from ..services.channel_selector import has_email_channel
        if has_email_channel():
            weekly_email = get_weekly_email_sum()
            email_pct = round(weekly_email / WEEKLY_EMAIL_OUTREACH_CAP * 100, 1) if WEEKLY_EMAIL_OUTREACH_CAP > 0 else 0
            lines.append(f"- Email overflow: **{weekly_email}/{WEEKLY_EMAIL_OUTREACH_CAP}** ({email_pct}%)")
    except Exception:
        pass

    if weekly_sent >= weekly_cap:
        at_limit, _, eta_msg = estimate_weekly_limit_reset()
        lines.append(f"- **LIMIT REACHED** — invitations resume in {eta_msg}")
    elif weekly_pct >= 80:
        remaining = weekly_cap - weekly_sent
        lines.append(f"- Approaching limit — {remaining} invitations remaining")
    lines.append("")

    # ── Daily Action Limits ──
    lines.append("## Daily Action Limits")
    eng_counts = get_daily_engagement_counts_all()
    comment_react = eng_counts.get("comment", 0) + eng_counts.get("react", 0)
    action_limits = [
        ("Invitations", sent, daily_limit),
        ("Engagements (comment/react)", comment_react, DAILY_ENGAGEMENT_LIMIT),
        ("Profile Views", eng_counts.get("profile_view", 0), DAILY_PROFILE_VIEW_LIMIT),
        ("Follows", eng_counts.get("follow", 0), DAILY_FOLLOW_LIMIT),
        ("Endorsements", eng_counts.get("endorse", 0), DAILY_ENDORSE_LIMIT),
        ("Auto-replies", get_daily_auto_reply_count(), DAILY_AUTO_REPLY_LIMIT),
        ("Inbound DMs", count_inbound_dms_today(), DAILY_INBOUND_DM_LIMIT),
        ("Voice Memos", get_daily_voice_memo_count(), DAILY_VOICE_MEMO_LIMIT),
        ("Brand Posts", get_daily_brand_post_count(), DAILY_BRAND_POST_LIMIT),
        ("Brand Engagements", get_daily_brand_engage_count(), DAILY_BRAND_ENGAGE_LIMIT),
        ("Signal Outreaches", get_daily_signal_outreach_count(), DAILY_SIGNAL_OUTREACH_LIMIT),
    ]
    for label, used, limit in action_limits:
        pct = round(used / limit * 100) if limit > 0 else 0
        lines.append(f"- {label}: **{used}/{limit}** ({pct}%)")
    lines.append("")

    # ── Campaign Summary ──
    campaigns = list_campaigns(status="active")
    if campaigns:
        lines.append("## Active Campaigns")
        for c in campaigns:
            name = c.get("name") or "Unnamed"
            mode = c.get("mode", "?")
            lines.append(f"- **{name}** ({mode})")
        lines.append("")

    # ── Event Summary (24h) ──
    summary = get_scheduler_event_summary(24)
    if summary:
        lines.append("## Event Summary (24h)")
        parts = [f"{etype}: {cnt}" for etype, cnt in summary.items()]
        lines.append(", ".join(parts))
        lines.append("")

    # ── Job Metrics ──
    metrics = get_job_metrics(24)
    if metrics:
        total_jobs = sum(m["total"] for m in metrics.values())
        total_ok = sum(m["success"] for m in metrics.values())
        total_fail = sum(m["failed"] for m in metrics.values())
        overall_rate = round(total_ok / total_jobs * 100, 1) if total_jobs > 0 else 0

        lines.append("## Job Performance (24h)")
        lines.append(
            f"- Total: **{total_jobs}** | Success: {total_ok} | "
            f"Failed: {total_fail} | Rate: {overall_rate}%"
        )

        # Top failures by type
        failures = [(jt, m) for jt, m in metrics.items() if m["failed"] > 0]
        if failures:
            lines.append("- Failures by type:")
            for jtype, m in sorted(failures, key=lambda x: x[1]["failed"], reverse=True):
                lines.append(f"  - {jtype}: {m['failed']} failures")
        lines.append("")

    # ── Recent Failures ──
    recent_failures = get_recent_scheduler_events(hours=24, event_type="job_failed", limit=5)
    if recent_failures:
        lines.append("## Recent Failures")
        for evt in recent_failures:
            ts = evt.get("created_at", 0)
            t = datetime.fromtimestamp(ts).strftime("%H:%M") if ts else "?"
            ctx = evt.get("context", {})
            jtype = ctx.get("job_type", "?")
            cat = ctx.get("error_category", "")
            err = ctx.get("error", "")[:60]
            lines.append(f"- [{t}] {jtype} [{cat}]: {err}")
        lines.append("")

    # ── Engagement Anomalies ──
    all_recent = get_recent_scheduler_events(hours=24, event_type="", limit=500)
    anomaly_events = [
        e for e in all_recent
        if (e.get("event_type") or "").startswith("anomaly_")
    ]
    if anomaly_events:
        lines.append("## Engagement Anomalies")
        for evt in anomaly_events[:10]:
            ts = evt.get("created_at", 0)
            t = datetime.fromtimestamp(ts).strftime("%H:%M") if ts else "?"
            ctx = evt.get("context", {})
            severity = ctx.get("severity", "?")
            summary = ctx.get("summary", "")[:80]
            severity_icon = "!!" if severity == "critical" else "!"
            lines.append(f"- [{t}] [{severity_icon} {severity}] {summary}")
        lines.append("")

    # ── Hot Leads ──
    # Count positive replies from events
    positive_events = get_recent_scheduler_events(
        hours=24, event_type="job_completed", limit=500
    )
    reply_jobs = [
        e for e in positive_events
        if (e.get("context") or {}).get("job_type") in ("check_replies", "qualify_inbound")
    ]
    if reply_jobs:
        lines.append(f"## Replies & Inbound: {len(reply_jobs)} processed")
        lines.append("")

    lines.append("---")
    lines.append("Run `scheduler(action='logs')` for full details.")

    return "\n".join(lines)
