# backend/app/connectors/calendar/ics_import.py — .ics 파일 임포트(로컬 우선, OAuth 불필요)
# 의존성 없이 VEVENT 를 직접 파싱 → cal_event 정규화로 귀결.
from datetime import UTC, datetime

from sqlmodel import Session

from ..base import BaseConnector, NormalizedRecord, RawRecord
from .normalize import normalize_event, upsert_event


def _unfold(text: str) -> list[str]:
    """RFC5545 라인 언폴딩(다음 줄이 공백/탭으로 시작하면 이어붙임)."""
    out: list[str] = []
    for line in text.replace("\r\n", "\n").split("\n"):
        if line[:1] in (" ", "\t") and out:
            out[-1] += line[1:]
        else:
            out.append(line)
    return out


def _prop(line: str) -> tuple[str, str]:
    # "DTSTART;TZID=Asia/Seoul:20260610T090000" → ("DTSTART", "20260610T090000")
    name, _, value = line.partition(":")
    return name.split(";", 1)[0].upper(), value.strip()


def parse_ics(text: str) -> list[dict]:
    events: list[dict] = []
    cur: dict | None = None
    for line in _unfold(text):
        key, val = _prop(line)
        if key == "BEGIN" and val == "VEVENT":
            cur = {}
        elif key == "END" and val == "VEVENT":
            if cur is not None:
                events.append(cur)
            cur = None
        elif cur is not None:
            if key == "UID":
                cur["id"] = val
            elif key == "SUMMARY":
                cur["title"] = val
            elif key == "LOCATION":
                cur["loc"] = val
            elif key == "DESCRIPTION":
                cur["note"] = val
            elif key == "DTSTART":
                cur["_start_raw"] = val
            elif key == "DTEND":
                cur["_end_raw"] = val
    for e in events:
        sr, er = e.pop("_start_raw", ""), e.pop("_end_raw", "")
        e["day"] = int(sr[6:8]) if len(sr) >= 8 and sr[6:8].isdigit() else 0
        e["start"] = f"{sr[9:11]}:{sr[11:13]}" if "T" in sr else ""
        e["end"] = f"{er[9:11]}:{er[11:13]}" if "T" in er else ""
        e["cal"] = "work"
        e.setdefault("id", f"ics-{e.get('title', '')[:8]}-{sr}")
    return events


class IcsConnector(BaseConnector):
    domain = "calendar"
    entity_type = "event"

    def fetch(self, session: Session, *, full: bool = False):
        for p in getattr(self, "_events", []):
            yield RawRecord(
                external_id=p["id"],
                payload=p,
                etag=f"{p.get('start', '')}-{p.get('title', '')}",
                external_updated_at=datetime.now(UTC),
            )

    def normalize(self, raw: RawRecord) -> NormalizedRecord:
        return normalize_event(self.account, raw, provider="ics")

    def write(self, session: Session, norm: NormalizedRecord):
        return upsert_event(session, norm)

    def event_for(self, norm, entity_id):
        return "calendar.updated"

    def import_bytes(self, session: Session, content: bytes, filename: str = "") -> dict:
        text = content.decode("utf-8", "ignore")
        self._events = parse_ics(text)
        res = self.sync(session, full=True)
        return {
            "entity_type": "event",
            "imported": res.upserted,
            "skipped": res.skipped,
            "errors": res.errors,
            "detail": f"{filename or '.ics'} · 이벤트 {res.upserted}건 정규화 완료",
        }
