"""ChatGPT conversations.json parser."""

import json
from datetime import datetime
from pathlib import Path
from typing import List

from .base import BaseParser
from ..models import Conversation, Message


class ChatGPTParser(BaseParser):
    def can_parse(self, path: Path) -> bool:
        if not path.is_file() or path.suffix != ".json":
            return False
        try:
            with open(path, encoding="utf-8") as f:
                data = json.load(f)
            if not isinstance(data, list) or len(data) == 0:
                return False
            # ChatGPT exports have "mapping" with tree structure
            return "mapping" in data[0]
        except (json.JSONDecodeError, KeyError, IndexError):
            return False

    def parse(self, path: Path) -> List[Conversation]:
        with open(path, encoding="utf-8") as f:
            data = json.load(f)

        conversations = []
        for item in data:
            mapping = item.get("mapping", {})
            messages = self._linearize_tree(mapping)
            if not messages:
                continue

            create_time = item.get("create_time")
            created = datetime.fromtimestamp(create_time) if create_time else None

            conv = Conversation(
                id=item.get("conversation_id", item.get("id", "")),
                title=item.get("title", ""),
                messages=messages,
                created=created,
                platform="chatgpt",
            )
            conversations.append(conv)

        conversations.sort(key=lambda c: c.created or datetime.min)
        return conversations

    def _linearize_tree(self, mapping: dict) -> List[Message]:
        """Convert tree structure to linear message list by following first child."""
        # Find root node (parent is None)
        root_id = None
        for node_id, node in mapping.items():
            if node.get("parent") is None:
                root_id = node_id
                break

        if root_id is None:
            return []

        messages = []
        current_id = root_id

        while current_id:
            node = mapping.get(current_id)
            if not node:
                break

            msg_data = node.get("message")
            if msg_data:
                role = msg_data.get("author", {}).get("role", "")
                if role in ("user", "assistant"):
                    parts = msg_data.get("content", {}).get("parts", [])
                    content = ""
                    for part in parts:
                        if isinstance(part, str):
                            content = part
                            break

                    if content:
                        ts = msg_data.get("create_time")
                        timestamp = datetime.fromtimestamp(ts) if ts else None
                        messages.append(Message(role=role, content=content, timestamp=timestamp))

            children = node.get("children", [])
            current_id = children[0] if children else None

        return messages
