from typing import Optional, Union
from .ical import ICalParser, ICal


class Task:
    """
    A task as given by the vCalendar/vEvent/iCal payload to parse.
    Note that the convenience getter/setter proxies silently ignore iCal 'parameters' and assume UTC timestamps.
    """

    def __init__(self, data: Optional[Union[str, ICal]] = None) -> None:
        """Parse content obtained from the API."""
        if data is None:
            self._caldav: ICal = ICalParser.create()
        elif isinstance(data, str):
            self._caldav = ICalParser.from_string(data)
        elif isinstance(data, ICal):
            self._caldav = data
        else:
            raise ValueError("Invalid ical payload for task")

    def to_string(self) -> str:
        """Give content to be passed to the API."""
        return ICalParser.to_string(self._caldav)

    def copy(self) -> 'Task':
        """Deep copy, Faster way of Task(self.to_string), bypassing de/serialization"""
        return Task(ICal(self._caldav.data.copy()))

    @property
    def data(self) -> ICal:
        """Direct access to the parsed iCal datastructure, without using the convenience getter/setter proxies below."""
        return self._caldav

    @property
    def uid(self) -> Optional[str]:
        return self._caldav.find_value("UID")

    @property
    def related_to(self) -> Optional[str]:
        return self._caldav.find_value("RELATED-TO")

    @related_to.setter
    def related_to(self, uid: Optional[str]) -> None:
        self._caldav.upsert_value("RELATED-TO", uid if uid else None)

    @property
    def summary(self) -> Optional[str]:
        return self._caldav.find_value("SUMMARY")

    @summary.setter
    def summary(self, value: str) -> None:
        self._caldav.upsert_value("SUMMARY", value)

    @property
    def description(self) -> Optional[str]:
        return self._caldav.find_value("DESCRIPTION")

    @description.setter
    def description(self, value: Optional[str]) -> None:
        self._caldav.upsert_value("DESCRIPTION", value)

    @property
    def created(self) -> Optional[float]:
        ts: Optional[str] = self._caldav.find_value("CREATED")
        return ICalParser.parse_timestamp(ts) if ts is not None else None

    @property
    def last_modified(self) -> Optional[float]:
        ts: Optional[str] = self._caldav.find_value("LAST-MODIFIED")
        return ICalParser.parse_timestamp(ts) if ts is not None else None

    @last_modified.setter
    def last_modified(self, value: float) -> None:
        self._caldav.upsert_value("LAST-MODIFIED", ICalParser.from_timestamp(value))

    @property
    def completed(self) -> Optional[float]:
        ts: Optional[str] = self._caldav.find_value("COMPLETED")
        return ICalParser.parse_timestamp(ts) if ts is not None else None

    @completed.setter
    def completed(self, value: Optional[float]) -> None:
        self._caldav.upsert_value("COMPLETED", ICalParser.from_timestamp(value) if value is not None else None)
        self._caldav.upsert_value("PERCENT-COMPLETE", "100" if value is not None else None)
        self._caldav.upsert_value("STATUS", "COMPLETED" if value is not None else None)