"""
Database para o módulo População
Banco de dados separado do Threshold para gerenciar tags específicas do módulo População
"""

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


class PopulacaoDatabase:
    """Banco de dados específico para o módulo População"""
    
    def __init__(self, db_file: str = None):
        """
        Inicializa o banco de dados do População
        
        Args:
            db_file: Caminho para o arquivo JSON do banco (opcional)
        """
        if db_file is None:
            # Define caminho padrão baseado na localização do executável ou script
            if hasattr(sys, '_MEIPASS'):
                # Executável PyInstaller - salva na pasta de dados do usuário
                base_path = os.path.join(os.path.expanduser('~'), '.fastchecker')
                os.makedirs(base_path, exist_ok=True)
            else:
                # Modo desenvolvimento - salva na pasta do projeto
                base_path = os.path.join(os.path.dirname(__file__), 'data')
                os.makedirs(base_path, exist_ok=True)
            
            db_file = os.path.join(base_path, 'populacao_db.json')
        
        self.db_file = db_file
        self.data = self._load_data()
    
    def _load_data(self) -> Dict:
        """Carrega dados do arquivo JSON"""
        if os.path.exists(self.db_file):
            try:
                with open(self.db_file, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    print(f"✅ População DB carregado: {self.db_file}")
                    return data
            except Exception as e:
                print(f"⚠️ Erro ao carregar População DB: {e}")
                return {"tags": []}
        else:
            print(f"📁 Criando novo População DB: {self.db_file}")
            return {"tags": []}
    
    def _save_data(self) -> bool:
        """Salva dados no arquivo JSON"""
        try:
            with open(self.db_file, 'w', encoding='utf-8') as f:
                json.dump(self.data, f, indent=2, ensure_ascii=False)
            return True
        except Exception as e:
            print(f"❌ Erro ao salvar População DB: {e}")
            return False
    
    def get_tags(self) -> List[Dict]:
        """Retorna todas as tags do População"""
        return self.data.get("tags", [])
    
    def get_all_tags(self) -> List[Dict]:
        """Alias para get_tags() - compatibilidade com ThresholdDatabase"""
        return self.get_tags()
    
    def get_tag_by_epc(self, epc: str) -> Optional[Dict]:
        """Busca uma tag pelo EPC"""
        for tag in self.data.get("tags", []):
            if tag.get('epc') == epc:
                return tag
        return None
    
    def add_tag(self, epc: str, name: str = "", initial_rssi: float = 0.0, coordinates: str = "") -> bool:
        """
        Adiciona uma nova tag ao banco do População
        
        Args:
            epc: EPC da tag
            name: Nome/apelido da tag
            initial_rssi: RSSI inicial (não usado no População, mantido para compatibilidade)
            coordinates: Coordenadas (X,Y,Z)
            
        Returns:
            True se adicionou com sucesso, False se a tag já existe
        """
        # Verifica se a tag já existe
        if self.get_tag_by_epc(epc):
            print(f"⚠️ Tag já existe no População DB: {epc}")
            return False
        
        # Cria nova tag
        new_tag = {
            'epc': epc,
            'name': name,
            'initial_rssi': initial_rssi,
            'coordinates': coordinates,
            'registered_at': datetime.now().isoformat()
        }
        
        self.data.setdefault("tags", []).append(new_tag)
        
        if self._save_data():
            print(f"✅ Tag adicionada ao População DB: {epc}")
            return True
        return False
    
    def update_tag(self, epc: str, name: str = None, coordinates: str = None) -> bool:
        """
        Atualiza uma tag existente
        
        Args:
            epc: EPC da tag
            name: Novo nome (opcional)
            coordinates: Novas coordenadas (opcional)
            
        Returns:
            True se atualizou com sucesso
        """
        tag = self.get_tag_by_epc(epc)
        if not tag:
            print(f"⚠️ Tag não encontrada para atualizar: {epc}")
            return False
        
        if name is not None:
            tag['name'] = name
        if coordinates is not None:
            tag['coordinates'] = coordinates
        
        return self._save_data()
    
    def delete_tag(self, epc: str) -> bool:
        """Remove uma tag do banco"""
        tags = self.data.get("tags", [])
        for i, tag in enumerate(tags):
            if tag.get('epc') == epc:
                tags.pop(i)
                return self._save_data()
        return False
    
    def import_tags(self, tags: List[Dict]) -> Dict[str, int]:
        """
        Importa múltiplas tags de uma lista
        
        Args:
            tags: Lista de dicionários com dados das tags
            
        Returns:
            Dicionário com contadores: {'imported': n, 'skipped': n, 'errors': n}
        """
        result = {'imported': 0, 'skipped': 0, 'errors': 0}
        
        for tag_data in tags:
            try:
                epc = tag_data.get('epc')
                if not epc:
                    result['errors'] += 1
                    continue
                
                # Verifica se já existe
                if self.get_tag_by_epc(epc):
                    result['skipped'] += 1
                    continue
                
                # Adiciona a tag
                name = tag_data.get('name', tag_data.get('apelido', ''))
                coordinates = tag_data.get('coordinates', '')
                initial_rssi = tag_data.get('initial_rssi', 0.0)
                
                if self.add_tag(epc, name, initial_rssi, coordinates):
                    result['imported'] += 1
                else:
                    result['errors'] += 1
                    
            except Exception as e:
                print(f"❌ Erro ao importar tag: {e}")
                result['errors'] += 1
        
        return result
    
    def export_tags(self, epcs: List[str] = None) -> List[Dict]:
        """
        Exporta tags para compartilhamento
        
        Args:
            epcs: Lista de EPCs para exportar (None = todas)
            
        Returns:
            Lista de dicionários com dados das tags
        """
        if epcs is None:
            return self.get_tags()
        
        exported = []
        for epc in epcs:
            tag = self.get_tag_by_epc(epc)
            if tag:
                exported.append(tag)
        
        return exported
    
    def clear_all_tags(self) -> bool:
        """Remove todas as tags do banco"""
        self.data["tags"] = []
        return self._save_data()

