from __future__ import annotations
from datetime import datetime
from scripts.integrations.base import IntegrationBase


class AppleCalendarIntegration(IntegrationBase):
    name = "apple_calendar"
    label = "Apple Calendar (CalDAV)"
    tier = "paid"

    def __init__(self):
        self._config: dict = {}

    def fields(self) -> list[dict]:
        return [
            {"key": "caldav_url", "label": "CalDAV URL", "type": "url",
             "placeholder": "https://caldav.icloud.com/", "required": True,
             "help": "iCloud: https://caldav.icloud.com/  |  self-hosted: your server URL"},
            {"key": "username", "label": "Apple ID / username", "type": "text",
             "placeholder": "you@icloud.com", "required": True,
             "help": ""},
            {"key": "app_password", "label": "App-Specific Password", "type": "password",
             "placeholder": "xxxx-xxxx-xxxx-xxxx", "required": True,
             "help": "appleid.apple.com → Security → App-Specific Passwords → Generate"},
            {"key": "calendar_name", "label": "Calendar name", "type": "text",
             "placeholder": "Interviews", "required": True,
             "help": "Name of the calendar to write interview events to"},
        ]

    def connect(self, config: dict) -> bool:
        self._config = config
        return bool(
            config.get("caldav_url") and
            config.get("username") and
            config.get("app_password")
        )

    def test(self) -> bool:
        try:
            import caldav
            client = caldav.DAVClient(
                url=self._config["caldav_url"],
                username=self._config["username"],
                password=self._config["app_password"],
            )
            principal = client.principal()
            return principal is not None
        except Exception:
            return False

    def _get_calendar(self):
        """Return the configured caldav Calendar object."""
        import caldav
        client = caldav.DAVClient(
            url=self._config["caldav_url"],
            username=self._config["username"],
            password=self._config["app_password"],
        )
        principal = client.principal()
        cal_name = self._config.get("calendar_name", "Interviews")
        for cal in principal.calendars():
            if cal.name == cal_name:
                return cal
        # Calendar not found — create it
        return principal.make_calendar(name=cal_name)

    def create_event(self, uid: str, title: str, start_dt: datetime,
                     end_dt: datetime, description: str = "") -> str:
        """Create a calendar event. Returns the UID (used as calendar_event_id)."""
        from icalendar import Calendar, Event
        cal = Calendar()
        cal.add("prodid", "-//CircuitForge Peregrine//EN")
        cal.add("version", "2.0")
        event = Event()
        event.add("uid", uid)
        event.add("summary", title)
        event.add("dtstart", start_dt)
        event.add("dtend", end_dt)
        event.add("description", description)
        cal.add_component(event)
        dav_cal = self._get_calendar()
        dav_cal.add_event(cal.to_ical().decode())
        return uid

    def update_event(self, uid: str, title: str, start_dt: datetime,
                     end_dt: datetime, description: str = "") -> str:
        """Update an existing event by UID, or create it if not found."""
        from icalendar import Calendar, Event
        dav_cal = self._get_calendar()
        try:
            existing = dav_cal.event_by_uid(uid)
            cal = Calendar()
            cal.add("prodid", "-//CircuitForge Peregrine//EN")
            cal.add("version", "2.0")
            event = Event()
            event.add("uid", uid)
            event.add("summary", title)
            event.add("dtstart", start_dt)
            event.add("dtend", end_dt)
            event.add("description", description)
            cal.add_component(event)
            existing.data = cal.to_ical().decode()
            existing.save()
        except Exception:
            return self.create_event(uid, title, start_dt, end_dt, description)
        return uid
