"""DataImporter: import MemoTrail data from JSON format."""

import json
from pathlib import Path

from memotrail.storage import SQLiteStore
from memotrail.utils import get_logger

logger = get_logger("memotrail.sync.importer")


class DataImporter:
    """Import MemoTrail data from portable JSON format."""

    def __init__(self, sqlite_store: SQLiteStore | None = None):
        self.sqlite = sqlite_store or SQLiteStore()

    def import_from_file(self, input_path: str | Path, merge: bool = True) -> dict:
        """Import data from a JSON file.

        Args:
            input_path: Path to the JSON export file
            merge: If True, skip existing records. If False, error on conflicts.

        Returns:
            Summary dict with counts of imported records
        """
        input_path = Path(input_path)
        data = json.loads(input_path.read_text(encoding="utf-8"))

        counts = {
            "sessions": 0,
            "messages": 0,
            "decisions": 0,
            "memories": 0,
            "entities": 0,
            "relations": 0,
            "fact_history": 0,
        }

        # Import sessions first (other tables reference them)
        for session in data.get("sessions", []):
            if self._import_session(session, merge):
                counts["sessions"] += 1

        for message in data.get("messages", []):
            if self._import_message(message, merge):
                counts["messages"] += 1

        for decision in data.get("decisions", []):
            if self._import_decision(decision, merge):
                counts["decisions"] += 1

        for memory in data.get("memories", []):
            if self._import_memory(memory, merge):
                counts["memories"] += 1

        for entity in data.get("entities", []):
            if self._import_entity(entity, merge):
                counts["entities"] += 1

        for relation in data.get("relations", []):
            if self._import_relation(relation, merge):
                counts["relations"] += 1

        for entry in data.get("fact_history", []):
            if self._import_fact_history(entry, merge):
                counts["fact_history"] += 1

        self.sqlite.conn.commit()
        logger.info(f"Imported from {input_path}: {counts}")
        return counts

    def _exists(self, table: str, record_id: str) -> bool:
        """Check if a record already exists."""
        row = self.sqlite.conn.execute(
            f"SELECT id FROM {table} WHERE id = ?", (record_id,)
        ).fetchone()
        return row is not None

    def _import_session(self, session: dict, merge: bool) -> bool:
        if merge and self._exists("sessions", session["id"]):
            return False
        self.sqlite.conn.execute(
            "INSERT OR IGNORE INTO sessions (id, project, started_at, ended_at, summary, message_count, tags, source) "
            "VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
            (session["id"], session.get("project"), session["started_at"],
             session.get("ended_at"), session.get("summary"),
             session.get("message_count", 0), session.get("tags", "[]"),
             session.get("source", "claude_code")),
        )
        return True

    def _import_message(self, message: dict, merge: bool) -> bool:
        if merge and self._exists("messages", message["id"]):
            return False
        self.sqlite.conn.execute(
            "INSERT OR IGNORE INTO messages (id, session_id, role, content, timestamp, token_count) "
            "VALUES (?, ?, ?, ?, ?, ?)",
            (message["id"], message["session_id"], message["role"],
             message["content"], message["timestamp"],
             message.get("token_count", 0)),
        )
        return True

    def _import_decision(self, decision: dict, merge: bool) -> bool:
        if merge and self._exists("decisions", decision["id"]):
            return False
        self.sqlite.conn.execute(
            "INSERT OR IGNORE INTO decisions (id, session_id, decision_text, context, category, created_at) "
            "VALUES (?, ?, ?, ?, ?, ?)",
            (decision["id"], decision["session_id"], decision["decision_text"],
             decision.get("context"), decision.get("category", "general"),
             decision["created_at"]),
        )
        return True

    def _import_memory(self, memory: dict, merge: bool) -> bool:
        if merge and self._exists("memories", memory["id"]):
            return False
        tags = memory.get("tags", "[]")
        if isinstance(tags, list):
            tags = json.dumps(tags)
        self.sqlite.conn.execute(
            "INSERT OR IGNORE INTO memories (id, content, tags, created_at, updated_at) "
            "VALUES (?, ?, ?, ?, ?)",
            (memory["id"], memory["content"], tags,
             memory["created_at"], memory.get("updated_at", memory["created_at"])),
        )
        return True

    def _import_entity(self, entity: dict, merge: bool) -> bool:
        try:
            if merge and self._exists("entities", entity["id"]):
                return False
            self.sqlite.conn.execute(
                "INSERT OR IGNORE INTO entities "
                "(id, name, entity_type, description, first_seen_session, "
                "last_seen_session, mention_count, created_at, updated_at) "
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
                (entity["id"], entity["name"], entity["entity_type"],
                 entity.get("description"), entity.get("first_seen_session"),
                 entity.get("last_seen_session"), entity.get("mention_count", 1),
                 entity["created_at"], entity["updated_at"]),
            )
            return True
        except Exception:
            return False

    def _import_relation(self, relation: dict, merge: bool) -> bool:
        try:
            if merge and self._exists("relations", relation["id"]):
                return False
            self.sqlite.conn.execute(
                "INSERT OR IGNORE INTO relations "
                "(id, source_entity_id, target_entity_id, relation_type, "
                "context, session_id, confidence, created_at) "
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
                (relation["id"], relation["source_entity_id"],
                 relation["target_entity_id"], relation["relation_type"],
                 relation.get("context"), relation.get("session_id"),
                 relation.get("confidence", 1.0), relation["created_at"]),
            )
            return True
        except Exception:
            return False

    def _import_fact_history(self, entry: dict, merge: bool) -> bool:
        try:
            if merge and self._exists("fact_history", entry["id"]):
                return False
            self.sqlite.conn.execute(
                "INSERT OR IGNORE INTO fact_history "
                "(id, fact_type, fact_id, previous_value, new_value, "
                "change_type, session_id, changed_at) "
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
                (entry["id"], entry["fact_type"], entry["fact_id"],
                 entry.get("previous_value"), entry["new_value"],
                 entry["change_type"], entry.get("session_id"),
                 entry["changed_at"]),
            )
            return True
        except Exception:
            return False
