import threading
import time
import os
from typing import Callable, List
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../docs/Modulo aquecimento')))
from uhf_reader_wrapper import UHFReader

class CentralHeatingController:
    def __init__(self, dll_path, port, max_power_dbm):
        print(f"[AQUECIMENTO] Inicializando controlador central...")
        print(f"[AQUECIMENTO] DLL: {dll_path}")
        print(f"[AQUECIMENTO] Porta: {port}")
        print(f"[AQUECIMENTO] Potência máxima: {max_power_dbm} dBm")
        
        self.reader = UHFReader(dll_path)
        self.port = port
        self.max_power_dbm = max_power_dbm
        self.frequency_mhz = 915
        self.status = "Inicializando"
        self.temperature = 0.0
        self._monitoring = False
        self._thread = None
        self._users: List[str] = []
        self._lock = threading.Lock()
        self._on_status_change: List[Callable[[str], None]] = []
        self._on_temperature_change: List[Callable[[float], None]] = []
        
        print(f"[AQUECIMENTO] Controlador central inicializado com sucesso")

    def start_monitoring(self):
        print(f"[AQUECIMENTO] Iniciando monitoramento...")
        with self._lock:
            if not self._monitoring:
                self._monitoring = True
                self._thread = threading.Thread(target=self._monitor_loop, daemon=True)
                self._thread.start()
                print(f"[AQUECIMENTO] Thread de monitoramento iniciada")
            else:
                print(f"[AQUECIMENTO] Monitoramento já está ativo")

    def stop_monitoring(self):
        with self._lock:
            self._monitoring = False
            if self._thread:
                self._thread.join(timeout=1)

    def register_user(self, user_id: str):
        print(f"[AQUECIMENTO] Registrando usuário: {user_id}")
        with self._lock:
            if user_id not in self._users:
                self._users.append(user_id)
                print(f"[AQUECIMENTO] Usuários ativos: {self._users}")
            if len(self._users) == 1:
                print(f"[AQUECIMENTO] Primeiro usuário registrado, iniciando monitoramento...")
                self.start_monitoring()

    def unregister_user(self, user_id: str):
        with self._lock:
            if user_id in self._users:
                self._users.remove(user_id)
            if not self._users:
                self.stop_monitoring()

    def get_status(self):
        return self.status

    def get_temperature(self):
        return self.temperature

    def add_status_callback(self, callback: Callable[[str], None]):
        self._on_status_change.append(callback)

    def add_temperature_callback(self, callback: Callable[[float], None]):
        self._on_temperature_change.append(callback)

    def _notify_status(self, status):
        for cb in self._on_status_change:
            try:
                cb(status)
            except:
                pass

    def _notify_temperature(self, temp):
        for cb in self._on_temperature_change:
            try:
                cb(temp)
            except:
                pass

    def _monitor_loop(self):
        try:
            print('[AQUECIMENTO] Iniciando monitoramento...')
            print(f'[AQUECIMENTO] Tentando conectar na porta {self.port}...')
            if not self.reader.connect(self.port):
                self.status = "Erro: Falha ao conectar"
                self._notify_status(self.status)
                print('[AQUECIMENTO] Falha ao conectar ao reader!')
                return
            print('[AQUECIMENTO] Conectado com sucesso!')
            self.status = "Aquecendo"
            self._notify_status(self.status)
            print(f'[AQUECIMENTO] Configurando potência para {self.max_power_dbm} dBm...')
            self.reader.set_power(self.max_power_dbm)
            print('[AQUECIMENTO] Iniciando CW...')
            self.reader.start_cw()
            print('[AQUECIMENTO] Entrando no loop de monitoramento...')
            while self._monitoring:
                try:
                    temp = self.reader.get_temperature()
                    print(f'[AQUECIMENTO] Temperatura lida: {temp:.2f}°C')
                except Exception as e:
                    print(f'[AQUECIMENTO] Erro ao ler temperatura: {e}')
                    temp = 25.0
                self.temperature = temp
                self._notify_temperature(temp)
                if temp >= 50.0:
                    self.status = "Crítico"
                    self._notify_status(self.status)
                    self.reader.stop_cw()
                    print('[AQUECIMENTO] Temperatura crítica!')
                    break
                elif temp >= 32.0 and temp <= 37.0:
                    if self.status != "OK":
                        self.status = "OK"
                        self._notify_status(self.status)
                        print('[AQUECIMENTO] Temperatura OK!')
                    self.reader.stop_cw()
                elif temp < 32.0:
                    if self.status != "Aquecendo":
                        self.status = "Aquecendo"
                        self._notify_status(self.status)
                        print('[AQUECIMENTO] Aquecendo...')
                    self.reader.start_cw()
                time.sleep(10)
        except Exception as e:
            self.status = f"Erro: {e}"
            self._notify_status(self.status)
            print(f'[AQUECIMENTO] Exceção geral: {e}')
        finally:
            try:
                self.reader.stop_cw()
                self.reader.disconnect()
                print('[AQUECIMENTO] Finalizando monitoramento.')
            except Exception:
                pass 