"""calendar_push.py — push interview events to connected calendar integrations.

Supports Apple Calendar (CalDAV) and Google Calendar. Idempotent: a second
push updates the existing event rather than creating a duplicate.
"""
from __future__ import annotations

import yaml
from datetime import datetime, timedelta, timezone
from pathlib import Path
from typing import Optional

from scripts.db import get_job_by_id, get_research, set_calendar_event_id, DEFAULT_DB

_CALENDAR_INTEGRATIONS = ("apple_calendar", "google_calendar")

# Stage label map matches 5_Interviews.py
_STAGE_LABELS = {
    "phone_screen":  "Phone Screen",
    "interviewing":  "Interview",
    "offer":         "Offer Review",
}


def _load_integration(name: str, config_dir: Path):
    """Instantiate and connect an integration from its saved config file."""
    config_file = config_dir / "integrations" / f"{name}.yaml"
    if not config_file.exists():
        return None
    with open(config_file) as f:
        config = yaml.safe_load(f) or {}
    if name == "apple_calendar":
        from scripts.integrations.apple_calendar import AppleCalendarIntegration
        integration = AppleCalendarIntegration()
    elif name == "google_calendar":
        from scripts.integrations.google_calendar import GoogleCalendarIntegration
        integration = GoogleCalendarIntegration()
    else:
        return None
    integration.connect(config)
    return integration


def _build_event_details(job: dict, research: Optional[dict]) -> tuple[str, str]:
    """Return (title, description) for the calendar event."""
    stage_label = _STAGE_LABELS.get(job.get("status", ""), "Interview")
    title = f"{stage_label}: {job.get('title', 'Interview')} @ {job.get('company', '')}"

    lines = []
    if job.get("url"):
        lines.append(f"Job listing: {job['url']}")
    if research and research.get("company_brief"):
        brief = research["company_brief"].strip()
        # Trim to first 3 sentences so the event description stays readable
        sentences = brief.split(". ")
        lines.append("\n" + ". ".join(sentences[:3]) + ("." if len(sentences) > 1 else ""))
    lines.append("\n— Sent by Peregrine (CircuitForge)")

    return title, "\n".join(lines)


def push_interview_event(
    db_path: Path = DEFAULT_DB,
    job_id: int = None,
    config_dir: Path = None,
) -> dict:
    """Push (or update) an interview event on the first connected calendar integration.

    Returns:
        {"ok": True,  "provider": "apple_calendar", "event_id": "..."}
        {"ok": False, "error": "..."}
    """
    if config_dir is None:
        config_dir = Path(__file__).parent.parent / "config"

    job = get_job_by_id(db_path, job_id)
    if not job:
        return {"ok": False, "error": f"Job {job_id} not found"}

    interview_date = job.get("interview_date")
    if not interview_date:
        return {"ok": False, "error": "No interview date set — save a date first"}

    # Build datetimes: noon UTC, 1 hour duration
    try:
        base = datetime.fromisoformat(interview_date).replace(
            hour=12, minute=0, second=0, microsecond=0, tzinfo=timezone.utc
        )
    except ValueError:
        return {"ok": False, "error": f"Could not parse interview_date: {interview_date!r}"}
    start_dt = base
    end_dt = base + timedelta(hours=1)

    research = get_research(db_path, job_id)
    title, description = _build_event_details(job, research)

    existing_event_id = job.get("calendar_event_id")

    for name in _CALENDAR_INTEGRATIONS:
        integration = _load_integration(name, config_dir)
        if integration is None:
            continue

        try:
            # Use a stable UID derived from job_id for CalDAV; gcal uses the returned event id
            uid = existing_event_id or f"peregrine-job-{job_id}@circuitforge.tech"
            if existing_event_id:
                event_id = integration.update_event(uid, title, start_dt, end_dt, description)
            else:
                event_id = integration.create_event(uid, title, start_dt, end_dt, description)

            set_calendar_event_id(db_path, job_id, event_id)
            return {"ok": True, "provider": name, "event_id": event_id}

        except Exception as exc:
            return {"ok": False, "error": str(exc)}

    return {"ok": False, "error": "No calendar integration configured — connect one in Settings → Integrations"}
