from __future__ import annotations

import json
import sqlite3
from datetime import datetime
from typing import Any


class HeavenRepositoryMixin:
    def list_sector_phase_overrides(self) -> dict[str, str]:
        with self.connect() as connection:
            rows = connection.execute(
                "SELECT name, element FROM sector_phase_overrides ORDER BY updated_at DESC, name"
            ).fetchall()
        return {row["name"]: row["element"] for row in rows}

    def save_sector_phase_override(self, name: str, element: str) -> None:
        now = datetime.now().astimezone().isoformat(timespec="seconds")
        with self.connect() as connection:
            connection.execute(
                """
                INSERT INTO sector_phase_overrides (name, element, updated_at)
                VALUES (?, ?, ?)
                ON CONFLICT(name) DO UPDATE SET
                    element = excluded.element,
                    updated_at = excluded.updated_at
                """,
                (name, element, now),
            )

    def delete_sector_phase_override(self, name: str) -> bool:
        with self.connect() as connection:
            cursor = connection.execute(
                "DELETE FROM sector_phase_overrides WHERE name = ?",
                (name,),
            )
            return cursor.rowcount > 0

    @staticmethod
    def _heaven_reading_dict(row: sqlite3.Row | None) -> dict[str, Any] | None:
        if not row:
            return None
        return {
            "id": int(row["id"]),
            "mode": str(row["mode"]),
            "context_date": str(row["context_date"]),
            "subject": str(row["subject"]),
            "subject_detail": str(row["subject_detail"]),
            "answer": str(row["answer"]),
            "created_at": str(row["created_at"]),
        }

    def save_heaven_reading(
        self,
        user_id: int,
        mode: str,
        context_date: str,
        subject: str,
        subject_detail: str,
        answer: str,
        context_snapshot: dict[str, Any],
        dedupe_key: str,
    ) -> dict[str, Any]:
        now = datetime.now().astimezone().isoformat(timespec="seconds")
        snapshot_json = json.dumps(
            context_snapshot, ensure_ascii=False, separators=(",", ":")
        )
        with self.connect() as connection:
            connection.execute(
                """
                INSERT INTO heaven_readings
                    (user_id, mode, context_date, subject, subject_detail, answer,
                     context_snapshot, dedupe_key, created_at)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
                ON CONFLICT(user_id, dedupe_key) DO NOTHING
                """,
                (
                    int(user_id), mode, context_date, subject, subject_detail,
                    answer, snapshot_json, dedupe_key, now,
                ),
            )
            row = connection.execute(
                """
                SELECT id, mode, context_date, subject, subject_detail, answer, created_at
                FROM heaven_readings WHERE user_id = ? AND dedupe_key = ?
                """,
                (int(user_id), dedupe_key),
            ).fetchone()
            connection.execute(
                """
                DELETE FROM heaven_readings
                WHERE user_id = ? AND mode = ? AND id NOT IN (
                    SELECT id FROM heaven_readings
                    WHERE user_id = ? AND mode = ? ORDER BY id DESC LIMIT 100
                )
                """,
                (int(user_id), mode, int(user_id), mode),
            )
        result = self._heaven_reading_dict(row)
        if not result:
            raise ValueError("解读记录保存失败。")
        return result

    def list_heaven_readings(
        self,
        user_id: int,
        mode: str,
        context_date: str = "",
        limit: int = 100,
    ) -> list[dict[str, Any]]:
        clauses = ["user_id = ?", "mode = ?"]
        parameters: list[Any] = [int(user_id), mode]
        if context_date:
            clauses.append("context_date = ?")
            parameters.append(context_date)
        parameters.append(max(1, min(100, int(limit))))
        with self.connect() as connection:
            rows = connection.execute(
                f"""
                SELECT id, mode, context_date, subject, subject_detail, answer, created_at
                FROM heaven_readings WHERE {' AND '.join(clauses)}
                ORDER BY context_date DESC, id DESC LIMIT ?
                """,
                parameters,
            ).fetchall()
        return [self._heaven_reading_dict(row) for row in rows if row]

    def latest_heaven_reading(
        self, user_id: int, mode: str, context_date: str = ""
    ) -> dict[str, Any] | None:
        items = self.list_heaven_readings(user_id, mode, context_date, 1)
        return items[0] if items else None

    def heaven_reading_interpretation_version(
        self, user_id: int, reading_id: int
    ) -> str:
        with self.connect() as connection:
            row = connection.execute(
                """
                SELECT context_snapshot FROM heaven_readings
                WHERE id = ? AND user_id = ?
                """,
                (int(reading_id), int(user_id)),
            ).fetchone()
        if not row:
            return ""
        try:
            snapshot = json.loads(str(row["context_snapshot"] or "{}"))
        except (TypeError, json.JSONDecodeError):
            return ""
        return str(snapshot.get("interpretation_version") or "")

    def delete_heaven_reading(self, user_id: int, reading_id: int) -> bool:
        with self.connect() as connection:
            cursor = connection.execute(
                "DELETE FROM heaven_readings WHERE id = ? AND user_id = ?",
                (int(reading_id), int(user_id)),
            )
            return cursor.rowcount > 0
