"""Persistência local para testes do módulo Fast Orientation.

Este módulo segue a mesma abordagem simples do `rssi_power_database.py`,
armazenando os resultados em um arquivo JSON no diretório do projeto. Cada
teste guarda os metadados principais (EPC, faixa angular, passos, frequência)
e a lista completa dos pontos medidos (ângulo x threshold).
"""

from __future__ import annotations

import json
import os
from datetime import datetime
from typing import Dict, List, Optional


class OrientationDatabase:
    """Banco de dados JSON para histórico do Fast Orientation."""

    def __init__(self, db_file: Optional[str] = None) -> None:
        if db_file is None:
            base_dir = os.path.dirname(os.path.abspath(__file__))
            self.db_file = os.path.join(base_dir, "fast_orientation_db.json")
        else:
            self.db_file = db_file

        self.data = self._load_data()

    # ------------------------------------------------------------------
    # Rotinas internas de leitura/escrita
    # ------------------------------------------------------------------
    def _load_data(self) -> Dict:
        try:
            if os.path.exists(self.db_file):
                with open(self.db_file, "r", encoding="utf-8") as fp:
                    payload = json.load(fp)
                    if isinstance(payload, dict) and "test_history" in payload:
                        return payload
        except (json.JSONDecodeError, OSError):
            pass

        return self._create_initial_structure()

    def _create_initial_structure(self) -> Dict:
        return {
            "test_history": [],
            "metadata": {
                "created": datetime.now().strftime("%d/%m/%Y %H:%M"),
                "version": "1.0"
            }
        }

    def _save_data(self) -> bool:
        try:
            self.data.setdefault("metadata", {})["last_modified"] = datetime.now().strftime("%d/%m/%Y %H:%M")
            with open(self.db_file, "w", encoding="utf-8") as fp:
                json.dump(self.data, fp, indent=2, ensure_ascii=False)
            return True
        except OSError as exc:
            print(f"❌ Erro ao salvar o banco de dados de orientação: {exc}")
            return False

    # ------------------------------------------------------------------
    # Operações públicas
    # ------------------------------------------------------------------
    def get_test_history(self) -> List[Dict]:
        self.data = self._load_data()
        return self.data.get("test_history", [])

    def add_test(self, test_payload: Dict) -> Optional[int]:
        history = self.data.setdefault("test_history", [])
        next_id = max((t.get("id", 0) for t in history), default=0) + 1

        test_payload = dict(test_payload)
        test_payload["id"] = next_id
        test_payload.setdefault("timestamp", datetime.now().strftime("%d/%m/%Y %H:%M"))

        history.append(test_payload)
        return next_id if self._save_data() else None

    def update_test(self, test_id: int, new_payload: Dict) -> bool:
        history = self.data.setdefault("test_history", [])
        for idx, test in enumerate(history):
            if test.get("id") == test_id:
                new_payload = dict(new_payload)
                new_payload["id"] = test_id
                new_payload.setdefault("timestamp", test.get("timestamp"))
                history[idx] = new_payload
                return self._save_data()
        return False

    def delete_test(self, test_id: int) -> bool:
        history = self.data.setdefault("test_history", [])
        original_len = len(history)
        history[:] = [test for test in history if test.get("id") != test_id]
        if len(history) != original_len:
            return self._save_data()
        return False

    def get_test_by_id(self, test_id: int) -> Optional[Dict]:
        for test in self.data.get("test_history", []):
            if test.get("id") == test_id:
                return test
        return None

    def get_statistics(self) -> Dict:
        history = self.data.get("test_history", [])
        total_tests = len(history)
        unique_epcs = {test.get("epc") for test in history if test.get("epc")}
        return {
            "total_tests": total_tests,
            "unique_tags": len(unique_epcs)
        }





