# gestor_clientes.py
import json
import os
import sys
import tkinter as tk
from tkinter import ttk, messagebox, filedialog

# ==================== Diretório base ====================
# Se estiver "frozen" (empacotado como exe), usa a pasta do executável
if getattr(sys, 'frozen', False):
    BASE_DIR = os.path.dirname(sys.executable)
else:
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))

CLIENTES_FILE = os.path.join(BASE_DIR, "clientes.json")
ULTIMO_CLIENTE_FILE = os.path.join(BASE_DIR, "ultimo_cliente.txt")

# ==================== Utilitários ====================

def centralizar_janela(janela, largura=700, altura=400):
    """Centraliza qualquer janela Tkinter no ecrã."""
    janela.update_idletasks()
    sw = janela.winfo_screenwidth()
    sh = janela.winfo_screenheight()
    x = (sw // 2) - (largura // 2)
    y = (sh // 2) - (altura // 2)
    janela.geometry(f"{largura}x{altura}+{x}+{y}")

def carregar_clientes():
    """Carrega clientes do ficheiro JSON."""
    if os.path.exists(CLIENTES_FILE):
        try:
            with open(CLIENTES_FILE, "r", encoding="utf-8") as f:
                return json.load(f)
        except:
            return {}
    return {}

def guardar_clientes(clientes):
    """Guarda clientes no ficheiro JSON."""
    with open(CLIENTES_FILE, "w", encoding="utf-8") as f:
        json.dump(clientes, f, indent=2)

def lista_clientes_ordenada():
    """Retorna os nomes de clientes ordenados alfabeticamente."""
    return sorted(clientes.keys(), key=str.lower)

# ==================== UI Principal ====================

def atualizar_lista():
    lista_clientes.delete(0, tk.END)
    for nome in lista_clientes_ordenada():
        lista_clientes.insert(tk.END, nome)

def mostrar_detalhes(event=None):
    selecao = lista_clientes.curselection()
    if not selecao:
        label_nome["text"] = "Selecione um cliente..."
        label_base["text"] = ""
        label_origem["text"] = ""
        return
    nome = lista_clientes.get(selecao[0])
    dados = clientes.get(nome, {})
    if isinstance(dados, dict):
        label_nome["text"] = f"Nome: {nome}"
        label_base["text"] = f"ID da pasta base: {dados.get('base','')}"
        label_origem["text"] = f"ID da pasta de origem (Com PDFs): {dados.get('origem','')}"
    else:
        label_nome["text"] = f"Nome: {nome}"
        label_base["text"] = f"ID da pasta base: {dados}"
        label_origem["text"] = f"ID da pasta de origem (Com PDFs): {dados}"

def eliminar_cliente():
    selecao = lista_clientes.curselection()
    if not selecao:
        messagebox.showwarning("Aviso", "Selecione um cliente para eliminar.")
        return
    nome = lista_clientes.get(selecao[0])
    if messagebox.askyesno("Confirmar", f"Deseja eliminar o cliente '{nome}'?"):
        clientes.pop(nome, None)
        guardar_clientes(clientes)
        atualizar_lista()
        label_nome["text"] = "Selecione um cliente..."
        label_base["text"] = ""
        label_origem["text"] = ""

# ==================== Pesquisa ====================

def procurar_cliente(event=None):
    termo = search_var.get().strip().lower()
    if not termo:
        lista_clientes.selection_clear(0, tk.END)
        return
    for i, nome in enumerate(lista_clientes_ordenada()):
        if nome.lower().startswith(termo):
            lista_clientes.selection_clear(0, tk.END)
            lista_clientes.selection_set(i)
            lista_clientes.activate(i)
            lista_clientes.see(i)
            mostrar_detalhes()
            return
    lista_clientes.selection_clear(0, tk.END)

# ==================== Modal ====================

def abrir_modal_cliente(modo="novo"):
    selecao = lista_clientes.curselection()
    nome_existente = None
    dados_existentes = {"base": "", "origem": ""}

    if modo == "editar":
        if not selecao:
            messagebox.showwarning("Aviso", "Selecione um cliente para editar.")
            return
        nome_existente = lista_clientes.get(selecao[0])
        d = clientes.get(nome_existente, {})
        dados_existentes = d if isinstance(d, dict) else {"base": d, "origem": d}

    modal = tk.Toplevel(root)
    modal.title("Editar Cliente" if modo == "editar" else "Novo Cliente")
    largura_modal = 500
    altura_modal = 250
    centralizar_janela(modal, largura_modal, altura_modal)
    modal.resizable(False, False)
    modal.grab_set()

    # Layout em grelha: coluna 0 = rótulo, coluna 1 = entrada, coluna 2 = botão (quando aplicável)
    modal.grid_columnconfigure(1, weight=1)

    tk.Label(modal, text="Nome do Cliente:").grid(row=0, column=0, sticky="e", padx=5, pady=10)
    nome_var = tk.StringVar(value=nome_existente or "")
    tk.Entry(modal, textvariable=nome_var, width=45).grid(row=0, column=1, pady=10, sticky="w")

    tk.Label(modal, text="ID da pasta base:").grid(row=1, column=0, sticky="e", padx=5, pady=10)
    base_var = tk.StringVar(value=dados_existentes.get("base", ""))
    entry_base = tk.Entry(modal, textvariable=base_var, width=45)
    entry_base.grid(row=1, column=1, pady=10, sticky="w")

    tk.Label(modal, text="ID da pasta de origem (Com PDFs):").grid(row=2, column=0, sticky="e", padx=5, pady=10)
    origem_var = tk.StringVar(value=dados_existentes.get("origem", ""))
    entry_origem = tk.Entry(modal, textvariable=origem_var, width=45)
    entry_origem.grid(row=2, column=1, pady=10, sticky="w")

    def escolher_pasta_para(var_alvo: tk.StringVar):
        pasta = filedialog.askdirectory(parent=modal, title="Selecionar pasta")
        if pasta:
            var_alvo.set(pasta)

    # Botões pequenos de procura ("...") à frente das entradas
    tk.Button(modal, text="...", width=3, command=lambda: escolher_pasta_para(base_var)).grid(
        row=1, column=2, padx=(6, 10), pady=10, sticky="w"
    )
    tk.Button(modal, text="...", width=3, command=lambda: escolher_pasta_para(origem_var)).grid(
        row=2, column=2, padx=(6, 10), pady=10, sticky="w"
    )

    def guardar_modal():
        nome = nome_var.get().strip()
        base = base_var.get().strip()
        origem = origem_var.get().strip() or base

        if not nome:
            messagebox.showwarning("Aviso", "O nome do cliente é obrigatório.", parent=modal)
            return
        if not base:
            messagebox.showwarning("Aviso", "O ID da pasta base é obrigatório.", parent=modal)
            return

        clientes[nome] = {"base": base, "origem": origem}
        guardar_clientes(clientes)
        atualizar_lista()
        modal.destroy()
        messagebox.showinfo("Sucesso", f"Cliente '{nome}' guardado com sucesso.")
        nomes_ordenados = lista_clientes_ordenada()
        idx = nomes_ordenados.index(nome)
        lista_clientes.selection_clear(0, tk.END)
        lista_clientes.selection_set(idx)
        lista_clientes.activate(idx)
        mostrar_detalhes()

    frame_btn_modal = tk.Frame(modal)
    frame_btn_modal.grid(row=3, column=1, pady=15, sticky="e")
    tk.Button(frame_btn_modal, text="Guardar", command=guardar_modal).pack(side="left", padx=5)
    tk.Button(frame_btn_modal, text="Cancelar", command=modal.destroy).pack(side="left", padx=5)

# ==================== Fechar Gestor ====================

def fechar_gestor():
    selecao = lista_clientes.curselection()
    if selecao:
        nome = lista_clientes.get(selecao[0])
        with open(ULTIMO_CLIENTE_FILE, "w", encoding="utf-8") as f:
            f.write(nome)
    else:
        if os.path.exists(ULTIMO_CLIENTE_FILE):
            os.remove(ULTIMO_CLIENTE_FILE)
    root.destroy()

# ==================== Interface Principal ====================

def main():
    global root, clientes, lista_clientes, label_nome, label_base, label_origem, search_var

    root = tk.Tk()
    root.title("Gestor de Clientes")
    largura_principal = 750
    altura_principal = 400
    centralizar_janela(root, largura_principal, altura_principal)
    root.resizable(False, False)

    clientes = carregar_clientes()

    # Coluna esquerda - Lista e Pesquisa
    frame_esq = tk.Frame(root, padx=10, pady=10)
    frame_esq.pack(side="left", fill="y")
    tk.Label(frame_esq, text="Clientes", font=("Segoe UI", 10, "bold")).pack(anchor="w")

    # 🆕 Barra de pesquisa
    search_var = tk.StringVar()
    entry_search = tk.Entry(frame_esq, textvariable=search_var, width=40)
    entry_search.pack(anchor="w", pady=(5, 8))
    entry_search.bind("<KeyRelease>", procurar_cliente)

    lista_clientes = tk.Listbox(frame_esq, width=40, height=15)
    lista_clientes.pack(fill="y", expand=True)
    lista_clientes.bind("<<ListboxSelect>>", mostrar_detalhes)

    frame_btn_esq = tk.Frame(frame_esq)
    frame_btn_esq.pack(fill="x", pady=5)
    tk.Button(frame_btn_esq, text="Novo", command=lambda: abrir_modal_cliente("novo")).pack(side="left", padx=2)
    tk.Button(frame_btn_esq, text="Editar", command=lambda: abrir_modal_cliente("editar")).pack(side="left", padx=2)
    tk.Button(frame_btn_esq, text="Eliminar", command=eliminar_cliente).pack(side="left", padx=2)

    # Coluna direita - Detalhes
    frame_dir = tk.Frame(root, padx=20, pady=20)
    frame_dir.pack(side="right", fill="both", expand=True)
    tk.Label(frame_dir, text="Detalhes do Cliente", font=("Segoe UI", 10, "bold")).pack(anchor="w", pady=(0, 10))

    label_nome = tk.Label(frame_dir, text="Selecione um cliente...", anchor="w", font=("Segoe UI", 9))
    label_nome.pack(anchor="w", pady=4)
    label_base = tk.Label(frame_dir, text="", anchor="w", font=("Segoe UI", 9))
    label_base.pack(anchor="w", pady=4)
    label_origem = tk.Label(frame_dir, text="", anchor="w", font=("Segoe UI", 9))
    label_origem.pack(anchor="w", pady=4)

    # Botão Fechar no canto inferior direito
    frame_btn_dir = tk.Frame(frame_dir, padx=20, pady=10)
    frame_btn_dir.pack(side="bottom", anchor="e", fill="x")
    tk.Button(frame_btn_dir, text="Fechar", command=fechar_gestor).pack(side="right")

    atualizar_lista()
    root.mainloop()

# ==================== Execução principal ====================

if __name__ == "__main__":
    main()
