# register_tags_popup.py
import tkinter as tk
from tkinter import ttk, messagebox
import threading
from .i18n import get_translator, t

class RegisterTagsPopup(tk.Toplevel):
    def __init__(self, parent, db_interface, hardware_scan_func, license_limits=None):
        super().__init__(parent)
        self.parent = parent
        self.db_interface = db_interface
        self.hardware_scan_func = hardware_scan_func
        self.license_limits = license_limits or {}
        
        self.found_tags = []
        self.tag_names = {}  # Dicionário para armazenar nomes personalizados
        self.result = False  # Atributo para indicar se tags foram registradas
        self.transient(parent)
        self.grab_set()
        
        self.show_lookup_view()

    def show_lookup_view(self):
        """Mostra a primeira janela: 'Lookup for new tags'."""
        self.title("Lookup for new tags")
        self.geometry("300x180")
        
        main_frame = ttk.Frame(self, padding="10")
        main_frame.pack(fill="both", expand=True)
        
        ttk.Label(main_frame, text="Power:").pack(pady=5)
        
        power_frame = ttk.Frame(main_frame)
        power_frame.pack(pady=5)
        
        # Aplica limites de licença se disponíveis
        min_power = self.license_limits.get('min_power', 5)
        max_power = self.license_limits.get('max_power', 25)
        default_power = min(max_power, 15)  # Usa 15 ou o máximo permitido
        
        self.power_var = tk.IntVar(value=default_power)
        
        # Botão de diminuição com validação
        def decrease_power():
            current = self.power_var.get()
            if current > min_power:
                self.power_var.set(current - 1)
        
        # Botão de aumento com validação
        def increase_power():
            current = self.power_var.get()
            if current < max_power:
                self.power_var.set(current + 1)
        
        ttk.Button(power_frame, text="-", command=decrease_power).pack(side="left")
        self.power_entry = ttk.Entry(power_frame, textvariable=self.power_var, width=5, justify='center')
        self.power_entry.pack(side="left", padx=5)
        ttk.Button(power_frame, text="+", command=increase_power).pack(side="left")
        
        # Adiciona validação ao campo de entrada
        def validate_power_input(*args):
            try:
                value = int(self.power_var.get())
                if value < min_power:
                    self.power_var.set(min_power)
                elif value > max_power:
                    self.power_var.set(max_power)
            except ValueError:
                self.power_var.set(default_power)
        
        self.power_var.trace('w', validate_power_input)
        
        # Mostra limites de potência
        limits_text = f"Limite: {min_power}-{max_power} dBm"
        ttk.Label(power_frame, text=limits_text, font=("Helvetica", 8), foreground="blue").pack(side="left", padx=10)

        self.search_button = ttk.Button(main_frame, text="► Start Search", command=self.start_search)
        self.search_button.pack(pady=10)

    def start_search(self):
        """Inicia a busca por tags em uma nova thread."""
        power = self.power_var.get()
        self.search_button.config(state="disabled", text="Searching...")
        
        # Executa a busca em uma thread para não travar a UI
        threading.Thread(target=self._search_worker, args=(power,), daemon=True).start()

    def _search_worker(self, power):
        """Função que executa na thread para chamar o hardware."""
        print(f"🔍 DEBUG: _search_worker iniciado com potência: {power}")
        try:
            # Chama a função de scan que foi passada pelo módulo principal
            print(f"🔍 DEBUG: Chamando hardware_scan_func...")
            self.found_tags = self.hardware_scan_func(power)
            print(f"🔍 DEBUG: hardware_scan_func retornou: {self.found_tags}")
            
            # NOVO: Verifica se as tags já existem antes de mostrar a tela de registro
            if not self.found_tags:
                # Nenhuma tag encontrada
                print(f"🔍 DEBUG: Nenhuma tag encontrada - mostrando mensagem")
                
                def show_no_tags_message():
                    self.search_button.config(state="normal", text="► Start Search")
                    messagebox.showinfo(t('register_tags_popup.search_completed'), t('register_tags_popup.no_tags_found'), parent=self)
                    self.destroy()
                
                self.after(0, show_no_tags_message)
                return
            
            # Verifica quais tags já existem
            new_tags = []
            existing_tags = []
            
            print(f"🔍 DEBUG: Verificando {len(self.found_tags)} tags encontradas")
            
            for tag in self.found_tags:
                epc = tag.epc if hasattr(tag, 'epc') else str(tag)
                print(f"🔍 DEBUG: Verificando tag EPC: {epc}")
                
                # DEBUG: Verifica se o banco de dados está funcionando
                existing_tag = self.db_interface.get_tag_by_epc(epc)
                print(f"🔍 DEBUG: Resultado da busca no banco para {epc}: {existing_tag}")
                
                # DEBUG: Verifica se a tag está na lista completa do banco
                all_tags = self.db_interface.get_all_tags()
                print(f"🔍 DEBUG: Total de tags no banco: {len(all_tags)}")
                tag_in_list = any(tag.get('epc') == epc for tag in all_tags)
                print(f"🔍 DEBUG: Tag {epc} está na lista completa? {tag_in_list}")
                
                if existing_tag:
                    existing_tags.append(epc)
                    print(f"⚠️ DEBUG: Tag já existe: {epc}")
                else:
                    new_tags.append(tag)
                    print(f"✅ DEBUG: Tag nova: {epc}")
            
            print(f"🔍 DEBUG: Resumo - Novas: {len(new_tags)}, Existentes: {len(existing_tags)}")
            
            # Se todas as tags já existem, mostra mensagem simples
            if not new_tags and existing_tags:
                print(f"🔍 DEBUG: Todas as tags já existem - mostrando mensagem")
                existing_list = "\n".join([f"• {epc}" for epc in existing_tags])
                
                # CORREÇÃO: Chama as funções na thread principal de forma sequencial
                def show_message_and_close():
                    self.search_button.config(state="normal", text="► Start Search")
                    # SIMPLIFICADO: Mostra apenas "Tag já Registrada" e o EPC
                    messagebox.showinfo(t('register_tags_popup.already_registered'), 
                        t('register_tags_popup.already_registered_msg').format(tags=existing_list), 
                        parent=self)
                    self.destroy()
                
                self.after(0, show_message_and_close)
                return
            
            # Se algumas tags já existem, mostra aviso mas continua
            if existing_tags:
                print(f"🔍 DEBUG: Algumas tags já existem - mostrando aviso")
                existing_list = "\n".join([f"• {epc}" for epc in existing_tags])
                
                def show_warning_message():
                    messagebox.showwarning(t('register_tags_popup.some_already_registered'), 
                        t('register_tags_popup.some_already_registered_msg').format(count=len(existing_tags), tags=existing_list, new_count=len(new_tags)), 
                        parent=self)
                
                self.after(0, show_warning_message)
            
            # Atualiza a lista para mostrar apenas tags novas
            self.found_tags = new_tags
            
            # Se não há tags novas, não mostra tela de registro
            if not self.found_tags:
                self.after(0, lambda: self.search_button.config(state="normal", text="► Start Search"))
                self.after(0, self.destroy)
                return
            
            # Quando terminar, agenda a troca de tela na thread principal da UI
            self.after(0, self.show_registration_view)
            
        except Exception as e:
            print(f"🔍 DEBUG: Erro capturado: {e}")
            
            def show_error_and_close():
                self.search_button.config(state="normal", text="► Start Search")
                messagebox.showerror("Erro de Hardware", f"Ocorreu um erro durante a busca: {e}", parent=self)
                self.destroy()
            
            self.after(0, show_error_and_close)

    def show_registration_view(self):
        """Limpa a janela e mostra a segunda tela: 'Tag Registration'."""
        for widget in self.winfo_children():
            widget.destroy()
            
        self.title("Tag Registration")
        self.geometry("700x600")
        
        main_frame = ttk.Frame(self, padding="10")
        main_frame.pack(fill="both", expand=True)

        found_label = ttk.Label(main_frame, text=f"Found {len(self.found_tags)} new tag(s)", font=("Helvetica", 12, "bold"))
        found_label.pack(pady=(0, 10))

        # Frame para instruções
        instruction_frame = ttk.Frame(main_frame)
        instruction_frame.pack(fill="x", pady=(0, 10))
        ttk.Label(instruction_frame, text="Selecione as tags e insira apelidos (opcional):", 
                 font=("Helvetica", 9)).pack()

        # Frame para a tabela com scrollbar
        table_frame = ttk.Frame(main_frame)
        table_frame.pack(fill="both", expand=True)
        
        # Tabela para exibir as tags com entrada de apelido e coordenadas
        columns = ('select', 'epc', 'rssi', 'nickname', 'coordinates')
        self.tree = ttk.Treeview(table_frame, columns=columns, show='headings', selectmode="none", height=8)
        
        self.tree.heading('select', text="")
        self.tree.heading('epc', text='EPC')
        self.tree.heading('rssi', text='RSSI')
        self.tree.heading('nickname', text='Apelido (opcional)')
        self.tree.heading('coordinates', text='Coordenadas X,Y,Z')

        self.tree.column('select', width=40, stretch=False, anchor='center')
        self.tree.column('epc', width=180)
        self.tree.column('rssi', width=70, anchor='center')
        self.tree.column('nickname', width=130)
        self.tree.column('coordinates', width=120, anchor='center')
        
        # Adiciona as tags encontradas na tabela
        for tag in self.found_tags:
            # A 'tag' é um objeto TagInfo com atributos .epc e .rssi
            # Colunas apelido e coordenadas ficam vazias inicialmente
            self.tree.insert('', 'end', values=('\u2610', tag.epc, f"{tag.rssi:.1f} dBm", "", ""), tags=('unchecked',))
            
        self.tree.tag_configure('checked', text='\u2611')
        self.tree.tag_configure('unchecked', text='\u2610')
        self.tree.bind('<Button-1>', self.toggle_checkbox)
        self.tree.bind('<Double-1>', self.edit_tag_info)
        
        # Scrollbar para a tabela
        scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)
        
        self.tree.pack(side="left", fill="both", expand=True)
        scrollbar.pack(side="right", fill="y")

        # Botões de ação
        button_frame = ttk.Frame(main_frame, padding=(0, 10, 0, 0))
        button_frame.pack(fill="x")
        
        ttk.Button(button_frame, text="Register selected tags", command=self.register_tags).pack(side="left")
        ttk.Button(button_frame, text="Retry", command=self.retry_search).pack(side="right")
        ttk.Button(button_frame, text="Close", command=self.destroy).pack(side="right", padx=5)

    def toggle_checkbox(self, event):
        """Alterna o estado do checkbox na tabela."""
        row_id = self.tree.identify_row(event.y)
        if not row_id:
            return
            
        if self.tree.identify_column(event.x) == '#1':
            tags = self.tree.item(row_id, 'tags')
            new_tags = ('checked',) if 'unchecked' in tags else ('unchecked',)
            self.tree.item(row_id, tags=new_tags)
            # Atualiza o texto do checkbox
            current_values = list(self.tree.item(row_id, 'values'))
            current_values[0] = '\u2611' if 'checked' in new_tags else '\u2610'
            self.tree.item(row_id, values=current_values)

    def edit_tag_info(self, event):
        """Permite editar o apelido e coordenadas da tag com duplo clique"""
        row_id = self.tree.identify_row(event.y)
        column = self.tree.identify_column(event.x)
        
        if not row_id or column not in ['#4', '#5']:  # Apenas colunas do apelido e coordenadas
            return
            
        # Obtém os valores atuais
        current_values = list(self.tree.item(row_id, 'values'))
        epc = current_values[1]
        
        # Cria popup para editar apelido e coordenadas
        edit_popup = tk.Toplevel(self)
        edit_popup.title("Editar Informações da Tag")
        edit_popup.geometry("400x250")
        edit_popup.transient(self)
        edit_popup.grab_set()
        
        # Frame principal
        edit_frame = ttk.Frame(edit_popup, padding="20")
        edit_frame.pack(fill="both", expand=True)
        
        ttk.Label(edit_frame, text=f"EPC: {epc}", font=("Helvetica", 9)).pack(pady=(0, 15))
        
        # Apelido
        ttk.Label(edit_frame, text="Apelido (opcional):").pack(anchor="w")
        nickname_var = tk.StringVar(value=current_values[3] if current_values[3] else "")
        nickname_entry = ttk.Entry(edit_frame, textvariable=nickname_var, width=35)
        nickname_entry.pack(pady=(2, 10), fill="x")
        
        # Coordenadas
        ttk.Label(edit_frame, text="Coordenadas X,Y,Z (opcional):").pack(anchor="w")
        coordinates_var = tk.StringVar(value=current_values[4] if current_values[4] else "")
        coordinates_entry = ttk.Entry(edit_frame, textvariable=coordinates_var, width=35)
        coordinates_entry.pack(pady=(2, 5), fill="x")
        
        # Instruções
        ttk.Label(edit_frame, text="Formato: 1,1,1 ou 2,1,2 (X,Y,Z)", 
                 font=("Helvetica", 8), foreground="gray").pack(anchor="w")
        ttk.Label(edit_frame, text="Deixe vazio para não usar apelido/coordenadas", 
                 font=("Helvetica", 8), foreground="gray").pack(anchor="w", pady=(0, 10))
        
        def save_info():
            new_nickname = nickname_var.get().strip()
            new_coordinates = coordinates_var.get().strip()
            
            # CORREÇÃO: Validação do apelido (máximo 4 caracteres)
            if len(new_nickname) > 4:
                messagebox.showerror(t('register_tags_popup.error_nickname_max'), t('register_tags_popup.error_nickname_max_msg'), parent=edit_popup)
                return
            
            # Valida formato das coordenadas se preenchido
            if new_coordinates:
                try:
                    coords = [float(x.strip()) for x in new_coordinates.split(',')]
                    if len(coords) != 3:
                        raise ValueError("Deve ter exatamente 3 valores")
                    # Reformatar para garantir formato consistente
                    new_coordinates = f"{coords[0]:.0f},{coords[1]:.0f},{coords[2]:.0f}"
                except ValueError:
                    messagebox.showerror(t('register_tags_popup.error_coordinates'), t('register_tags_popup.error_coordinates_msg'), parent=edit_popup)
                    return
            
            # Valida duplicatas antes de salvar
            if new_nickname or new_coordinates:
                print(f"🔍 DEBUG POPUP: Validando apelido '{new_nickname}' para EPC {epc}")
                existing_tags = self.db_interface.get_all_tags()
                print(f"🔍 DEBUG POPUP: Encontradas {len(existing_tags)} tags existentes")
                
                # Verifica se o apelido já existe (exceto para a própria tag)
                if new_nickname:
                    for tag in existing_tags:
                        existing_name = tag.get('name', '').strip()
                        existing_epc = tag.get('epc')
                        print(f"🔍 DEBUG POPUP: Tag {existing_epc} tem apelido '{existing_name}'")
                        
                        if (existing_name.lower() == new_nickname.lower() and 
                            existing_epc != epc):
                            print(f"❌ DEBUG POPUP: Apelido duplicado encontrado! '{new_nickname}' já existe em {existing_epc}")
                            messagebox.showwarning("Apelido Duplicado", 
                                f"O apelido '{new_nickname}' já está registrado para outra tag.\n"
                                f"Por favor, escolha um apelido diferente.", parent=edit_popup)
                            return
                    
                    print(f"✅ DEBUG POPUP: Apelido '{new_nickname}' é único")
                
                # Verifica se as coordenadas já existem (exceto para a própria tag)
                if new_coordinates:
                    for tag in existing_tags:
                        if (tag.get('coordinates', '').strip().lower() == new_coordinates.lower() and 
                            tag.get('epc') != epc):
                            messagebox.showwarning("Coordenadas Duplicadas", 
                                f"As coordenadas '{new_coordinates}' já estão registradas para outra tag.\n"
                                f"Por favor, escolha coordenadas diferentes.", parent=edit_popup)
                            return
            
            current_values[3] = new_nickname
            current_values[4] = new_coordinates
            self.tree.item(row_id, values=current_values)
            self.tag_names[epc] = new_nickname
            edit_popup.destroy()
        
        def cancel():
            edit_popup.destroy()
        
        # Botões
        button_frame = ttk.Frame(edit_frame)
        button_frame.pack(pady=(15, 0), fill="x")
        ttk.Button(button_frame, text="Salvar", command=save_info).pack(side="left", padx=5)
        ttk.Button(button_frame, text="Cancelar", command=cancel).pack(side="left", padx=5)
        
        # Bind Enter para salvar
        nickname_entry.bind('<Return>', lambda e: save_info())
        coordinates_entry.bind('<Return>', lambda e: save_info())
        nickname_entry.bind('<Escape>', lambda e: cancel())
        coordinates_entry.bind('<Escape>', lambda e: cancel())
        
        # Foco no primeiro campo
        if column == '#4':
            nickname_entry.focus()
        else:
            coordinates_entry.focus()

    def _validate_duplicates(self, selected_tags):
        """Valida se há apelidos ou coordenadas duplicadas"""
        existing_tags = self.db_interface.get_all_tags()
        
        # Coleta apelidos e coordenadas existentes
        existing_nicknames = set()
        existing_coordinates = set()
        
        for tag in existing_tags:
            if tag.get('name') and tag.get('name').strip():
                existing_nicknames.add(tag.get('name').strip().lower())
            if tag.get('coordinates') and tag.get('coordinates').strip():
                existing_coordinates.add(tag.get('coordinates').strip().lower())
        
        # Verifica duplicatas nas tags selecionadas
        duplicate_nicknames = []
        duplicate_coordinates = []
        
        for epc, nickname, coordinates in selected_tags:
            if nickname and nickname.strip():
                if nickname.strip().lower() in existing_nicknames:
                    duplicate_nicknames.append(nickname.strip())
            
            if coordinates and coordinates.strip():
                if coordinates.strip().lower() in existing_coordinates:
                    duplicate_coordinates.append(coordinates.strip())
        
        return duplicate_nicknames, duplicate_coordinates
    
    def _show_duplicate_warning(self, duplicate_nicknames, duplicate_coordinates):
        """Mostra popup de aviso para duplicatas"""
        message = ""
        
        if duplicate_nicknames:
            message += f"⚠️ Apelidos já registrados:\n{', '.join(duplicate_nicknames)}\n\n"
        
        if duplicate_coordinates:
            message += f"⚠️ Coordenadas já registradas:\n{', '.join(duplicate_coordinates)}\n\n"
        
        if message:
            message += "Por favor, altere os valores duplicados antes de continuar."
            messagebox.showwarning("Duplicatas Encontradas", message)
            return True
        
        return False

    def register_tags(self):
        """Salva as tags selecionadas no banco de dados."""
        selected_tags = []
        
        # Primeiro, coleta todas as tags selecionadas
        for item_id in self.tree.get_children():
            if 'checked' in self.tree.item(item_id, 'tags'):
                values = self.tree.item(item_id, 'values')
                epc = values[1]
                rssi_str = values[2].replace(' dBm', '')
                rssi = float(rssi_str)
                
                # Usa apelido se fornecido, senão fica vazio (nulo)
                nickname = values[3].strip() if values[3].strip() else ""
                
                # Usa coordenadas se fornecidas, senão fica vazio (nulo)
                coordinates = values[4].strip() if values[4].strip() else ""
                
                selected_tags.append((epc, nickname, coordinates))
        
        # Valida duplicatas antes de salvar
        duplicate_nicknames, duplicate_coordinates = self._validate_duplicates(selected_tags)
        
        if self._show_duplicate_warning(duplicate_nicknames, duplicate_coordinates):
            return  # Para o processo se houver duplicatas
        
        # Se não há duplicatas, procede com o salvamento
        registered_count = 0
        already_exists_count = 0
        already_exists_tags = []
        
        for epc, nickname, coordinates in selected_tags:
            # CORREÇÃO: Limpa apelidos antigos se a tag for registrada sem apelido
            if hasattr(self.parent, 'tag_apelidos') and not nickname:
                if epc in self.parent.tag_apelidos:
                    del self.parent.tag_apelidos[epc]
                    print(f"🗑️ Apelido antigo removido para EPC {epc}")
            
            # NOVO: Verifica se a tag já existe antes de tentar adicionar
            if self.db_interface.get_tag_by_epc(epc):
                already_exists_count += 1
                already_exists_tags.append(epc)
                print(f"⚠️ Tag já registrada: {epc}")
            else:
                # Chama a função de salvar do banco de dados
                if self.db_interface.add_tag(epc, nickname, rssi, coordinates):
                    registered_count += 1
                    print(f"✅ Tag registrada: {epc}")
                else:
                    already_exists_count += 1
                    already_exists_tags.append(epc)
                    print(f"⚠️ Falha ao registrar tag: {epc}")
        
        # CORREÇÃO: Salva apelidos após limpar os antigos
        if hasattr(self.parent, '_save_tag_apelidos'):
            self.parent._save_tag_apelidos()
        
        if selected_tags:
            # NOVO: Mostra resumo detalhado com tags registradas e já existentes
            if already_exists_count > 0:
                # Há tags que já existiam
                summary = f"Registro Concluído!\n\n"
                summary += f"✅ Tags registradas: {registered_count}\n"
                summary += f"⚠️ Tags já existentes: {already_exists_count}\n\n"
                
                if registered_count > 0:
                    summary += "Tags registradas com sucesso:\n"
                    for epc, nickname, coordinates in selected_tags:
                        if epc not in already_exists_tags:
                            if nickname and coordinates:
                                summary += f"• {nickname} ({epc}) - Coord: {coordinates}\n"
                            elif nickname:
                                summary += f"• {nickname} ({epc})\n"
                            elif coordinates:
                                summary += f"• {epc} - Coord: {coordinates}\n"
                            else:
                                summary += f"• {epc}\n"
                
                if already_exists_count > 0:
                    summary += f"\nTags já registradas (ignoradas):\n"
                    for epc in already_exists_tags:
                        summary += f"• {epc}\n"
                
                messagebox.showwarning(t('register_tags_popup.registration_complete'), summary, parent=self)
            else:
                # Todas as tags foram registradas com sucesso
                summary = f"{registered_count} tag(s) registrada(s) com sucesso!\n\n"
                for epc, nickname, coordinates in selected_tags:
                    if nickname and coordinates:
                        summary += f"• {nickname} ({epc}) - Coord: {coordinates}\n"
                    elif nickname:
                        summary += f"• {nickname} ({epc})\n"
                    elif coordinates:
                        summary += f"• {epc} - Coord: {coordinates}\n"
                    else:
                        summary += f"• {epc}\n"
                
                messagebox.showinfo(t('register_tags_popup.registration_success'), summary, parent=self)
            
            # Define result como True para indicar sucesso
            self.result = True
            
            # SALVA OS APELIDOS NO MÓDULO POPULAÇÃO (apenas para tags realmente registradas)
            for epc, nickname, coordinates in selected_tags:
                if epc not in already_exists_tags and nickname:  # Só salva se houver apelido e tag foi registrada
                    self.parent.save_tag_apelido(epc, nickname)
            
            # ATUALIZA A LISTA E SELECIONA AS TAGS REGISTRADAS
            self.parent.update_tags_list()
            
            # SELECIONA AUTOMATICAMENTE APENAS AS TAGS RECÉM-REGISTRADAS
            for epc, nickname, coordinates in selected_tags:
                if epc not in already_exists_tags:  # Só seleciona tags que foram realmente registradas
                    self.parent.selected_tags.add(epc)
            
            # ATUALIZA A INTERFACE PARA MOSTRAR AS TAGS SELECIONADAS
            self.parent.update_tags_list()
            
            self.destroy()
        else:
            messagebox.showwarning(t('register_tags_popup.no_selection'), t('register_tags_popup.no_selection_msg'), parent=self)
    
    def retry_search(self):
        """Volta para a tela de busca."""
        for widget in self.winfo_children():
            widget.destroy()
        self.show_lookup_view()