"""Local persistence for recent Luckee CLI sessions."""

from __future__ import annotations

import json
import os
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Optional


def _utc_now_iso() -> str:
    return datetime.now(timezone.utc).isoformat()


def _parse_timestamp(value: Any) -> float:
    if not value:
        return 0.0
    if isinstance(value, (int, float)):
        return float(value)
    text = str(value).strip()
    if not text:
        return 0.0
    try:
        return datetime.fromisoformat(text.replace("Z", "+00:00")).timestamp()
    except Exception:
        return 0.0


class LuckeeSessionStore:
    def __init__(self, path: Optional[str] = None) -> None:
        target = path or os.getenv("LUCKEE_SESSION_STORE") or "~/.luckee/sessions.json"
        self.path = Path(target).expanduser()

    def _load_entries(self) -> list[dict[str, Any]]:
        if not self.path.exists():
            return []
        try:
            raw = json.loads(self.path.read_text(encoding="utf-8"))
        except Exception:
            return []

        if isinstance(raw, dict):
            items = raw.get("sessions") or []
        elif isinstance(raw, list):
            items = raw
        else:
            items = []

        entries: list[dict[str, Any]] = []
        for item in items:
            if not isinstance(item, dict):
                continue
            thread_id = str(item.get("thread_id") or "").strip()
            if not thread_id:
                continue
            entries.append(item)
        return entries

    def _save_entries(self, entries: list[dict[str, Any]]) -> None:
        self.path.parent.mkdir(parents=True, exist_ok=True)
        tmp_path = self.path.with_suffix(".tmp")
        tmp_path.write_text(
            json.dumps(entries, ensure_ascii=False, indent=2),
            encoding="utf-8",
        )
        tmp_path.replace(self.path)

    def upsert_session(
        self,
        *,
        thread_id: str,
        endpoint: str,
        user_id: str,
        language: Optional[str],
        cwd: Optional[str] = None,
        branch: Optional[str] = None,
        conversation: Optional[str] = None,
    ) -> None:
        thread_id = str(thread_id or "").strip()
        if not thread_id:
            return

        entries = self._load_entries()
        now = _utc_now_iso()
        normalized_conversation = str(conversation or "").strip()

        existing = None
        for item in entries:
            if str(item.get("thread_id") or "").strip() == thread_id:
                existing = item
                break

        if existing is None:
            existing = {
                "thread_id": thread_id,
                "created_at": now,
            }
            entries.append(existing)

        existing["thread_id"] = thread_id
        existing["endpoint"] = endpoint
        existing["user_id"] = user_id
        existing["language"] = language or existing.get("language") or ""
        existing["cwd"] = cwd or existing.get("cwd") or ""
        existing["branch"] = branch or existing.get("branch") or "-"
        if normalized_conversation:
            existing["conversation"] = normalized_conversation
        else:
            existing.setdefault("conversation", "")
        existing["updated_at"] = now

        entries.sort(key=lambda item: _parse_timestamp(item.get("updated_at")), reverse=True)
        self._save_entries(entries[:200])

    def update_conversation(self, *, thread_id: str, conversation: str) -> None:
        thread_id = str(thread_id or "").strip()
        conversation = str(conversation or "").strip()
        if not thread_id or not conversation:
            return

        entries = self._load_entries()
        changed = False
        for item in entries:
            if str(item.get("thread_id") or "").strip() != thread_id:
                continue
            item["conversation"] = conversation
            item["updated_at"] = _utc_now_iso()
            changed = True
            break
        if changed:
            self._save_entries(entries)

    def list_sessions(
        self,
        *,
        endpoint: Optional[str] = None,
        user_id: Optional[str] = None,
        limit: int = 20,
    ) -> list[dict[str, Any]]:
        entries = self._load_entries()
        filtered: list[dict[str, Any]] = []
        for item in entries:
            if endpoint and str(item.get("endpoint") or "") != endpoint:
                continue
            if user_id and str(item.get("user_id") or "") != user_id:
                continue
            filtered.append(item)
        filtered.sort(
            key=lambda item: _parse_timestamp(item.get("updated_at")),
            reverse=True,
        )
        return filtered[: max(1, int(limit))]
