﻿# -*- coding: utf-8 -*-
from flask import Flask, render_template, jsonify, request, session, redirect, url_for
import mysql.connector
import decimal
import traceback
from pprint import pprint
import requests
import math
import sys
from functools import wraps

# Somente em Windows: pywin32 para impressão RAW
try:
    import win32print
    import win32api
except Exception:
    win32print = None
    win32api = None

app = Flask(__name__)
app.secret_key = 'novaloja_secret_key_2025_change_in_production'

# Decorador para proteger rotas
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'usuario_logado' not in session:
            return redirect(url_for('login_page'))
        return f(*args, **kwargs)
    return decorated_function

def conectar():
    return mysql.connector.connect(
        host="92.113.33.100",
        user="root",
        password="pctrim",
        port=3308,
        database="loja2001",
        autocommit=True
    )

# Coordenadas fixas da loja (ajuste conforme localização real)
#LOJA_LAT = -23.551234
#LOJA_LON = -46.634567
LOJA_LAT = -23.4861233
LOJA_LON = -46.6251525

def haversine_km(lat1, lon1, lat2, lon2):
    R = 6371.0
    dlat = math.radians(lat2 - lat1)
    dlon = math.radians(lon2 - lon1)
    a = math.sin(dlat/2)**2 + math.cos(math.radians(lat1))*math.cos(math.radians(lat2))*math.sin(dlon/2)**2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    return round(R * c, 2)

def geocodificar(endereco):
    if not endereco or len(endereco.strip()) < 5:
        return None, None
    url = "https://nominatim.openstreetmap.org/search"
    params = {"q": endereco, "format": "json", "limit": 1}
    headers = {"User-Agent": "novaloja-geocoder/1.0"}
    try:
        r = requests.get(url, params=params, headers=headers, timeout=8)
        if r.status_code != 200:
            return None, None
        data = r.json()
        if not data:
            return None, None
        return float(data[0]["lat"]), float(data[0]["lon"])
    except Exception as e:
        print("[GEOCODE ERRO]", e)
        return None, None

def distancia_osrm_km(lat_loja, lon_loja, lat_cli, lon_cli):
    try:
        base = "http://router.project-osrm.org/route/v1/driving"
        # OSRM usa ordem lon,lat
        url = f"{base}/{lon_loja},{lat_loja};{lon_cli},{lat_cli}?overview=false&alternatives=false&steps=false"
        r = requests.get(url, timeout=8, headers={"User-Agent": "novaloja-osrm/1.0"})
        if r.status_code != 200:
            return None
        data = r.json()
        if not data or data.get("code") != "Ok":
            return None
        routes = data.get("routes") or []
        if not routes:
            return None
        # distance vem em metros
        dist_m = routes[0].get("distance")
        if dist_m is None:
            return None
        return round(dist_m / 1000.0, 2)
    except Exception as e:
        print("[OSRM ERRO]", e)
        return None

def calcular_distancia_cliente(dados):
    partes = [
        dados.get("endereco", ""),
        dados.get("nrocasa", ""),
        dados.get("bairro", ""),
        dados.get("cidade", ""),
        dados.get("estado", ""),
        "Brasil"
    ]
    endereco_str = ", ".join([p for p in partes if p])
    lat_cli, lon_cli = geocodificar(endereco_str)
    if lat_cli is not None and lon_cli is not None:
        # Primeiro tenta percurso via OSRM
        dist_osrm = distancia_osrm_km(LOJA_LAT, LOJA_LON, lat_cli, lon_cli)
        if dist_osrm is not None:
            return dist_osrm, lat_cli, lon_cli
        # Fallback para Haversine (linha reta)
        try:
            dist_hav = haversine_km(LOJA_LAT, LOJA_LON, lat_cli, lon_cli)
            return dist_hav, lat_cli, lon_cli
        except Exception as e:
            print("[HAVERSINE ERRO]", e)
            return 0, lat_cli, lon_cli
    return 0, None, None

def calcular_taxa_entrega(distancia):
    """Calcula taxa de entrega baseado na distância usando tabela txentrega.
    Se distância for menor que faixa1_d, utiliza faixa1_v (taxa mínima).
    Retorna o valor da taxa ou 0.0 se erro."""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        cursor.execute("SELECT * FROM txentrega WHERE chave = 1")
        faixa = cursor.fetchone()
        
        if not faixa:
            print("[TAXA ENTREGA] Nenhuma faixa configurada em txentrega")
            return 0.0
        
        # Se distância for menor que faixa1_d, retorna faixa1_v
        faixa_1_d = faixa.get("faixa1_d")
        faixa_1_v = faixa.get("faixa1_v")
        
        if faixa_1_d is not None and distancia < faixa_1_d:
            taxa = float(faixa_1_v) if faixa_1_v is not None else 0.0
            print(f"[TAXA ENTREGA] Distância {distancia}km é menor que faixa1_d ({faixa_1_d}km), retornando taxa mínima: R$ {taxa}")
            return taxa
        
        # Testa cada faixa (1 a 10)
        for i in range(1, 11):
            faixa_d = faixa.get(f"faixa{i}_d")
            faixa_v = faixa.get(f"faixa{i}_v")
            
            if faixa_d is not None and distancia <= faixa_d:
                taxa = float(faixa_v) if faixa_v is not None else 0.0
                print(f"[TAXA ENTREGA] Distância {distancia}km cai na faixa {i}: R$ {taxa}")
                return taxa
        
        # Se ultrapassar todas as faixas, retorna a taxa da faixa 10
        faixa_10_v = faixa.get("faixa10_v")
        taxa_final = float(faixa_10_v) if faixa_10_v is not None else 0.0
        print(f"[TAXA ENTREGA] Distância {distancia}km ultrapassa todas as faixas: R$ {taxa_final}")
        return taxa_final
        
    except Exception as e:
        print("[TAXA ENTREGA ERRO]", e)
        return 0.0
    finally:
        try:
            if cursor:
                cursor.close()
        except Exception:
            pass
        try:
            if conn:
                conn.close()
        except Exception:
            pass

def convert_types(row):
    """Converte Decimal para float para que jsonify funcione."""
    if not row:
        return row
    out = {}
    for k, v in row.items():
        if isinstance(v, decimal.Decimal):
            out[k] = float(v)
        else:
            out[k] = v
    return out

# ===================== Impressão =====================

def get_printer_from_db():
    """Obtém o nome da impressora ativa da tabela impressoras (imprenro=1)."""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor()
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS impressoras (
                id INT AUTO_INCREMENT PRIMARY KEY,
                nomedaimpressora VARCHAR(255) NOT NULL,
                imprenro TINYINT NOT NULL DEFAULT 0
            )
        """)
        cursor.execute("SELECT nomedaimpressora FROM impressoras WHERE imprenro = 1 LIMIT 1")
        row = cursor.fetchone()
        return row[0] if row else None
    except Exception as e:
        print("[IMPRESSORA DB ERRO]", e)
        return None
    finally:
        try:
            if cursor:
                cursor.close()
        except Exception:
            pass
        try:
            if conn:
                conn.close()
        except Exception:
            pass

def send_to_printer(conteudo, printer_name=None):
    """Envia texto RAW para impressora no Windows. Retorna (True, None) em sucesso, (False, erro) em falha."""
    if sys.platform != "win32" or win32print is None:
        return False, "Impressão silenciosa disponível apenas no Windows (pywin32)."
    try:
        nome = printer_name or win32print.GetDefaultPrinter()
        # Abre job de impressão RAW
        hPrinter = win32print.OpenPrinter(nome)
        try:
            hJob = win32print.StartDocPrinter(hPrinter, 1, ("Pedido", None, "RAW"))
            try:
                win32print.StartPagePrinter(hPrinter)
                # Garantir que conteudo seja string simples
                if isinstance(conteudo, bytes):
                    data = conteudo
                else:
                    data = str(conteudo).encode("cp1252", errors="replace")
                win32print.WritePrinter(hPrinter, data)
                win32print.EndPagePrinter(hPrinter)
            finally:
                win32print.EndDocPrinter(hPrinter)
        finally:
            win32print.ClosePrinter(hPrinter)
        return True, None
    except Exception as e:
        return False, str(e)

def gravar_delivery_pendente(conteudo, produtos):
    """Grava dados do pedido na tabela deliverypendente"""
    conn = None
    cursor = None
    try:
        # Extrai dados do cliente do conteúdo
        linhas = conteudo.split('\n')
        cliente_data = {
            'telefone': '',
            'cep': '',
            'nome': '',
            'endereco': '',
            'nrocasa': '',
            'complemento': '',
            'nropedido': 0
        }
        
        for linha in linhas:
            if linha.startswith('Tel:'):
                cliente_data['telefone'] = linha.replace('Tel:', '').strip()
            elif linha.startswith('CEP:'):
                cliente_data['cep'] = linha.replace('CEP:', '').strip()
            elif linha.startswith('Nome:'):
                cliente_data['nome'] = linha.replace('Nome:', '').strip()
            elif linha.startswith('Compl:'):
                cliente_data['complemento'] = linha.replace('Compl:', '').strip()
            elif linha.startswith('End:'):
                end_info = linha.replace('End:', '').strip()
                partes = end_info.split(',')
                if len(partes) >= 1:
                    cliente_data['endereco'] = partes[0].strip()
                if len(partes) >= 2:
                    cliente_data['nrocasa'] = partes[1].strip()
            elif 'PEDIDO NRO:' in linha:
                nro_str = linha.replace('PEDIDO NRO:', '').strip()
                try:
                    cliente_data['nropedido'] = int(nro_str)
                except:
                    cliente_data['nropedido'] = 0
        
        # Se não temos telefone, não grava
        if not cliente_data['telefone']:
            print("[DELIVERY PENDENTE] Sem telefone, não gravando")
            return
        
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        # Grava um registro por produto
        for prod in produtos:
            prod_nome = prod.get("nome", "")
            prod_preco = float(prod.get("preco", 0))
            prod_qtd = int(prod.get("qtd", 1))
            prod_chave = prod.get("chave", "")
            prod_classe = prod.get("classe", "")
            
            # Se for taxa de entrega
            if "TAXA ENTREGA" in prod_nome:
                prod_chave = "TXENTREGA"
                prod_classe = "TXENTREGA"
            
            sql = """INSERT INTO deliverypendente 
                    (nropedido, telefone, cep, nome, endereco, nrocasa, complemento, produto, preco, quantidade, codigoproduto, classe, cliente)
                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
            valores = (
                cliente_data['nropedido'],
                cliente_data['telefone'],
                cliente_data['cep'],
                cliente_data['nome'],
                cliente_data['endereco'],
                cliente_data['nrocasa'],
                cliente_data['complemento'],
                prod_nome,
                prod_preco,
                prod_qtd,
                prod_chave,
                prod_classe,
                cliente_data.get('cliente', cliente_data['nome'])
            )
            cursor.execute(sql, valores)
            conn.commit()
            print(f"[DELIVERY PENDENTE] {prod_nome} (chave: {prod_chave}, classe: {prod_classe}) gravado para {cliente_data['telefone']}")
            
    except Exception as e:
        print(f"[DELIVERY PENDENTE ERRO] {e}")
        raise
    finally:
        if cursor:
            try:
                cursor.close()
            except:
                pass
        if conn:
            try:
                conn.close()
            except:
                pass

@app.route("/")
@login_required
def index():
    return render_template("casa.html")

@app.route("/login")
def login_page():
    """Página de login"""
    return render_template("login.html")

@app.route("/login", methods=["POST"])
def login():
    """Autentica o usuário usando a tabela usuarios"""
    dados = request.json or {}
    usuario = dados.get("usuario", "").strip()
    senha = dados.get("senha", "").strip()
    
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        # Busca o usuário na tabela
        cursor.execute("SELECT * FROM usuarios WHERE usuario = %s AND senha = %s", (usuario, senha))
        usuario_encontrado = cursor.fetchone()
        
        if usuario_encontrado:
            session['usuario_logado'] = usuario
            return jsonify({"sucesso": True, "mensagem": "Login realizado com sucesso"})
        else:
            return jsonify({"sucesso": False, "erro": "Usuário ou senha incorretos"}), 401
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR LOGIN]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao validar login"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/logout")
def logout():
    """Desloga o usuário"""
    session.pop('usuario_logado', None)
    return redirect(url_for('login_page'))

@app.route("/casa")
@login_required
def casa():
    """Página de pedidos (carrossel)"""
    return render_template("index.html")

@app.route("/delivery-pendente-view")
@login_required
def delivery_pendente_view():
    """Página para visualizar pedidos pendentes de entrega"""
    return render_template("delivery_pendente.html")

@app.route("/canceladas")
@login_required
def canceladas_view():
    """Página para visualizar pedidos cancelados"""
    return render_template("canceladas.html")

@app.route("/comandas")
@login_required
def comandas_view():
    """Página para visualizar comandas fechadas"""
    return render_template("comandas.html")

@app.route("/cadastrar-produto")
@login_required
def cadastrar_produto_view():
    """Página para cadastrar produtos"""
    return render_template("cadastrar_produto.html")

@app.route("/api/salvar-produto", methods=["POST"])
@login_required
def salvar_produto():
    """Salva um novo produto na tabela de produtos"""
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        produto = dados.get("produto", "").strip()
        preco = dados.get("preco", 0)
        classe = dados.get("classe", "").strip().upper()
        porkilo = dados.get("porkilo", "Nao")
        impressora = dados.get("impressora", 1)
        cfop = dados.get("cfop", "5102")
        ncm = dados.get("ncm", "")
        display = dados.get("display", 0)
        vendaliberada = dados.get("vendaliberada", "Sim")
        descricao = dados.get("descricao", "")
        
        if not classe or not produto:
            return jsonify({"sucesso": False, "erro": "Classe e nome do produto são obrigatórios"}), 400
        
        conn = conectar()
        cursor = conn.cursor()
        
        # Insere o produto (chave é auto_increment)
        cursor.execute("""
            INSERT INTO produtos (produto, preco, classe, porkilo, impressora, cfop, ncm, display, vendaliberada, descricao)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
        """, (produto, preco, classe, porkilo, impressora, cfop, ncm, display, vendaliberada, descricao))
        
        conn.commit()
        chave_gerada = cursor.lastrowid
        
        print(f"[PRODUTO CADASTRADO] {produto} (código: {chave_gerada}, classe: {classe})")
        return jsonify({
            "sucesso": True,
            "mensagem": f"Produto '{produto}' cadastrado com sucesso! (Código: {chave_gerada})"
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao salvar produto no banco de dados"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/listar-produtos", methods=["GET"])
@login_required
def listar_produtos():
    """Lista todos os produtos cadastrados"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("""
            SELECT chave, produto, preco, classe, porkilo, impressora, cfop, ncm, 
                   display, vendaliberada, descricao
            FROM produtos
            ORDER BY produto
        """)
        
        produtos = cursor.fetchall()
        
        return jsonify({
            "sucesso": True,
            "produtos": produtos
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao listar produtos"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/obter-produto/<int:chave>", methods=["GET"])
@login_required
def obter_produto(chave):
    """Obtém dados de um produto específico"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("""
            SELECT chave, produto, preco, classe, porkilo, impressora, cfop, ncm, 
                   display, vendaliberada, descricao
            FROM produtos
            WHERE chave = %s
        """, (chave,))
        
        produto = cursor.fetchone()
        
        if produto:
            return jsonify({
                "sucesso": True,
                "produto": produto
            })
        else:
            return jsonify({"sucesso": False, "erro": "Produto não encontrado"}), 404
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao obter produto"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/editar-produto/<int:chave>", methods=["PUT"])
@login_required
def editar_produto(chave):
    """Edita um produto existente"""
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        produto = dados.get("produto", "").strip()
        preco = dados.get("preco", 0)
        classe = dados.get("classe", "").strip().upper()
        porkilo = dados.get("porkilo", "Nao")
        impressora = dados.get("impressora", 1)
        cfop = dados.get("cfop", "5102")
        ncm = dados.get("ncm", "")
        display = dados.get("display", 0)
        vendaliberada = dados.get("vendaliberada", "Sim")
        descricao = dados.get("descricao", "")
        
        if not classe or not produto:
            return jsonify({"sucesso": False, "erro": "Classe e nome do produto são obrigatórios"}), 400
        
        conn = conectar()
        cursor = conn.cursor()
        
        cursor.execute("""
            UPDATE produtos 
            SET produto = %s, preco = %s, classe = %s, porkilo = %s, 
                impressora = %s, cfop = %s, ncm = %s, display = %s, 
                vendaliberada = %s, descricao = %s
            WHERE chave = %s
        """, (produto, preco, classe, porkilo, impressora, cfop, ncm, display, vendaliberada, descricao, chave))
        
        conn.commit()
        
        if cursor.rowcount > 0:
            print(f"[PRODUTO ATUALIZADO] {produto} (código: {chave})")
            return jsonify({
                "sucesso": True,
                "mensagem": f"Produto '{produto}' atualizado com sucesso!"
            })
        else:
            return jsonify({"sucesso": False, "erro": "Produto não encontrado"}), 404
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao editar produto"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/excluir-produto/<int:chave>", methods=["DELETE"])
@login_required
def excluir_produto(chave):
    """Exclui um produto"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        # Primeiro busca o nome do produto
        cursor.execute("SELECT produto FROM produtos WHERE chave = %s", (chave,))
        produto = cursor.fetchone()
        
        if not produto:
            return jsonify({"sucesso": False, "erro": "Produto não encontrado"}), 404
        
        # Exclui o produto
        cursor.execute("DELETE FROM produtos WHERE chave = %s", (chave,))
        conn.commit()
        
        print(f"[PRODUTO EXCLUÍDO] {produto['produto']} (código: {chave})")
        return jsonify({
            "sucesso": True,
            "mensagem": f"Produto '{produto['produto']}' excluído com sucesso!"
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao excluir produto"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

# ========== ENDPOINTS DE ENTREGADOR ==========

@app.route("/cadastrar-entregador")
@login_required
def cadastrar_entregador():
    """Página de cadastro de entregadores"""
    return render_template("cadastrar_entregador.html")

@app.route("/api/salvar-entregador", methods=["POST"])
@login_required
def salvar_entregador():
    """Salva um novo entregador na tabela de entregadores"""
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        nome = dados.get("nome", "").strip()
        telefone = dados.get("telefone", "").strip()
        endereco = dados.get("endereco", "").strip()
        
        if not nome:
            return jsonify({"sucesso": False, "erro": "Nome é obrigatório"}), 400
        
        conn = conectar()
        cursor = conn.cursor()
        
        # Insere o entregador (chave é auto_increment)
        cursor.execute("""
            INSERT INTO entregador (nome, telefone, endereco)
            VALUES (%s, %s, %s)
        """, (nome, telefone, endereco))
        
        conn.commit()
        chave_gerada = cursor.lastrowid
        
        print(f"[ENTREGADOR CADASTRADO] {nome} (código: {chave_gerada}, telefone: {telefone})")
        return jsonify({
            "sucesso": True,
            "mensagem": f"Entregador '{nome}' cadastrado com sucesso! (Código: {chave_gerada})"
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao salvar entregador no banco de dados"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/listar-entregadores", methods=["GET"])
@login_required
def listar_entregadores():
    """Lista todos os entregadores cadastrados"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("""
            SELECT chave, nome, telefone, endereco
            FROM entregador
            ORDER BY nome
        """)
        
        entregadores = cursor.fetchall()
        
        return jsonify({
            "sucesso": True,
            "entregadores": entregadores
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao listar entregadores"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/obter-entregador/<int:chave>", methods=["GET"])
@login_required
def obter_entregador(chave):
    """Obtém dados de um entregador específico"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("""
            SELECT chave, nome, telefone, endereco
            FROM entregador
            WHERE chave = %s
        """, (chave,))
        
        entregador = cursor.fetchone()
        
        if entregador:
            return jsonify({
                "sucesso": True,
                "entregador": entregador
            })
        else:
            return jsonify({"sucesso": False, "erro": "Entregador não encontrado"}), 404
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao obter entregador"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/editar-entregador/<int:chave>", methods=["PUT"])
@login_required
def editar_entregador(chave):
    """Edita um entregador existente"""
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        nome = dados.get("nome", "").strip()
        telefone = dados.get("telefone", "").strip()
        endereco = dados.get("endereco", "").strip()
        
        if not nome:
            return jsonify({"sucesso": False, "erro": "Nome é obrigatório"}), 400
        
        conn = conectar()
        cursor = conn.cursor()
        
        cursor.execute("""
            UPDATE entregador 
            SET nome = %s, telefone = %s, endereco = %s
            WHERE chave = %s
        """, (nome, telefone, endereco, chave))
        
        conn.commit()
        
        if cursor.rowcount > 0:
            print(f"[ENTREGADOR ATUALIZADO] {nome} (código: {chave})")
            return jsonify({
                "sucesso": True,
                "mensagem": f"Entregador '{nome}' atualizado com sucesso!"
            })
        else:
            return jsonify({"sucesso": False, "erro": "Entregador não encontrado"}), 404
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao editar entregador"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/excluir-entregador/<int:chave>", methods=["DELETE"])
@login_required
def excluir_entregador(chave):
    """Exclui um entregador"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        # Primeiro busca o nome do entregador
        cursor.execute("SELECT nome FROM entregador WHERE chave = %s", (chave,))
        entregador = cursor.fetchone()
        
        if not entregador:
            return jsonify({"sucesso": False, "erro": "Entregador não encontrado"}), 404
        
        # Exclui o entregador
        cursor.execute("DELETE FROM entregador WHERE chave = %s", (chave,))
        conn.commit()
        
        print(f"[ENTREGADOR EXCLUÍDO] {entregador['nome']} (código: {chave})")
        return jsonify({
            "sucesso": True,
            "mensagem": f"Entregador '{entregador['nome']}' excluído com sucesso!"
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro ao excluir entregador"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

# ========== ENDPOINTS DE CLASSIFICAÇÃO ==========

@app.route("/cadastrar-classificacao")
@login_required
def cadastrar_classificacao():
    """Página de cadastro de classificações"""
    return render_template("cadastrar_classificacao.html")

@app.route("/api/salvar-classificacao", methods=["POST"])
@login_required
def salvar_classificacao():
    """Salva uma nova classificação"""
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        nomeclassificacao = dados.get("nomeclassificacao", "").strip()
        quantidadepartes = dados.get("quantidadepartes")
        nrofoto = dados.get("nrofoto")
        
        if not nomeclassificacao:
            return jsonify({"sucesso": False, "mensagem": "Nome da classificação é obrigatório"}), 400
        
        conn = conectar()
        cursor = conn.cursor()
        
        cursor.execute("""
            INSERT INTO classificacao (nomeclassificacao, quantidadepartes, nrofoto)
            VALUES (%s, %s, %s)
        """, (nomeclassificacao, quantidadepartes, nrofoto))
        
        conn.commit()
        chave_gerada = cursor.lastrowid
        
        print(f"[CLASSIFICAÇÃO CADASTRADA] {nomeclassificacao} (código: {chave_gerada})")
        return jsonify({
            "sucesso": True,
            "mensagem": f"Classificação '{nomeclassificacao}' cadastrada com sucesso!"
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "mensagem": "Erro ao salvar classificação no banco de dados"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/listar-classificacoes", methods=["GET"])
@login_required
def listar_classificacoes():
    """Lista todas as classificações cadastradas"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("""
            SELECT chave, nomeclassificacao, quantidadepartes, nrofoto
            FROM classificacao
            ORDER BY nomeclassificacao
        """)
        
        classificacoes = cursor.fetchall()
        return jsonify(classificacoes)
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "mensagem": "Erro ao listar classificações"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/obter-classificacao/<int:chave>", methods=["GET"])
@login_required
def obter_classificacao(chave):
    """Obtém dados de uma classificação específica"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("""
            SELECT chave, nomeclassificacao, quantidadepartes, nrofoto
            FROM classificacao
            WHERE chave = %s
        """, (chave,))
        
        classificacao = cursor.fetchone()
        
        if classificacao:
            return jsonify(classificacao)
        else:
            return jsonify({"sucesso": False, "mensagem": "Classificação não encontrada"}), 404
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "mensagem": "Erro ao obter classificação"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/editar-classificacao/<int:chave>", methods=["PUT"])
@login_required
def editar_classificacao(chave):
    """Edita uma classificação existente"""
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        nomeclassificacao = dados.get("nomeclassificacao", "").strip()
        quantidadepartes = dados.get("quantidadepartes")
        nrofoto = dados.get("nrofoto")
        
        if not nomeclassificacao:
            return jsonify({"sucesso": False, "mensagem": "Nome da classificação é obrigatório"}), 400
        
        conn = conectar()
        cursor = conn.cursor()
        
        cursor.execute("""
            UPDATE classificacao 
            SET nomeclassificacao = %s, quantidadepartes = %s, nrofoto = %s
            WHERE chave = %s
        """, (nomeclassificacao, quantidadepartes, nrofoto, chave))
        
        conn.commit()
        
        if cursor.rowcount > 0:
            print(f"[CLASSIFICAÇÃO ATUALIZADA] {nomeclassificacao} (código: {chave})")
            return jsonify({
                "sucesso": True,
                "mensagem": f"Classificação '{nomeclassificacao}' atualizada com sucesso!"
            })
        else:
            return jsonify({"sucesso": False, "mensagem": "Classificação não encontrada"}), 404
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "mensagem": "Erro ao editar classificação"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/excluir-classificacao/<int:chave>", methods=["DELETE"])
@login_required
def excluir_classificacao(chave):
    """Exclui uma classificação"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        # Primeiro busca o nome da classificação
        cursor.execute("SELECT nomeclassificacao FROM classificacao WHERE chave = %s", (chave,))
        classificacao = cursor.fetchone()
        
        if not classificacao:
            return jsonify({"sucesso": False, "mensagem": "Classificação não encontrada"}), 404
        
        # Exclui a classificação
        cursor.execute("DELETE FROM classificacao WHERE chave = %s", (chave,))
        conn.commit()
        
        print(f"[CLASSIFICAÇÃO EXCLUÍDA] {classificacao['nomeclassificacao']} (código: {chave})")
        return jsonify({
            "sucesso": True,
            "mensagem": f"Classificação '{classificacao['nomeclassificacao']}' excluída com sucesso!"
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "mensagem": "Erro ao excluir classificação"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

# ========== ENDPOINTS DE TAXA DE ENTREGA ==========

@app.route("/cadastrar-taxa")
@login_required
def cadastrar_taxa():
    """Página de cadastro de taxas de entrega"""
    return render_template("cadastrar_taxa.html")

@app.route("/api/salvar-taxa", methods=["POST"])
@login_required
def salvar_taxa():
    """Salva ou atualiza as taxas de entrega"""
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        chave = dados.get("chave", 1)
        
        # Monta os valores das 10 faixas
        campos = []
        valores = []
        
        for i in range(1, 11):
            faixa_d = dados.get(f"faixa{i}_d")
            faixa_v = dados.get(f"faixa{i}_v")
            
            campos.append(f"faixa{i}_d = %s")
            campos.append(f"faixa{i}_v = %s")
            valores.append(faixa_d)
            valores.append(faixa_v)
        
        conn = conectar()
        cursor = conn.cursor()
        
        # Verifica se já existe registro com chave = 1
        cursor.execute("SELECT chave FROM txentrega WHERE chave = %s", (chave,))
        existe = cursor.fetchone()
        
        if existe:
            # Atualiza registro existente
            sql = f"UPDATE txentrega SET {', '.join(campos)} WHERE chave = %s"
            valores.append(chave)
            cursor.execute(sql, tuple(valores))
            print(f"[TAXA ENTREGA ATUALIZADA] chave {chave}")
        else:
            # Insere novo registro
            campos_insert = ["chave"] + [f"faixa{i}_d" for i in range(1, 11)] + [f"faixa{i}_v" for i in range(1, 11)]
            placeholders = ["%s"] * len(campos_insert)
            valores_insert = [chave]
            
            for i in range(1, 11):
                valores_insert.append(dados.get(f"faixa{i}_d"))
            for i in range(1, 11):
                valores_insert.append(dados.get(f"faixa{i}_v"))
            
            sql = f"INSERT INTO txentrega ({', '.join(campos_insert)}) VALUES ({', '.join(placeholders)})"
            cursor.execute(sql, tuple(valores_insert))
            print(f"[TAXA ENTREGA CRIADA] chave {chave}")
        
        conn.commit()
        
        return jsonify({
            "sucesso": True,
            "mensagem": "Taxas de entrega salvas com sucesso!"
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": str(db_err)}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/obter-taxa", methods=["GET"])
@login_required
def obter_taxa():
    """Obtém as taxas de entrega configuradas"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("SELECT * FROM txentrega WHERE chave = 1")
        taxa = cursor.fetchone()
        
        if taxa:
            return jsonify({"sucesso": True, "taxa": taxa})
        else:
            # Retorna estrutura vazia se não existir
            return jsonify({"sucesso": True, "taxa": None})
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": str(db_err)}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/imprimir", methods=["POST"])
def imprimir():
    """Endpoint de impressão silenciosa. Resolve nome da impressora pela ordem: parâmetro -> DB -> padrão do Windows.
    Retorna JSON com sucesso/erro e o nome da impressora utilizado.
    """
    dados = request.json or {}
    conteudo = dados.get("conteudo", "")
    printer_param = dados.get("printer")
    produtos = dados.get("produtos", [])

    # Extrai dados do cliente do conteúdo para gravar em deliverypendente
    if conteudo and produtos:
        try:
            gravar_delivery_pendente(conteudo, produtos)
        except Exception as e:
            print(f"[DELIVERY PENDENTE ERRO] {e}")
            traceback.print_exc()

    # Resolve impressora
    printer_db = get_printer_from_db()
    printer_resolved = printer_param or printer_db or (win32print.GetDefaultPrinter() if (sys.platform == "win32" and win32print) else None)

    ok, err = send_to_printer(conteudo, printer_resolved)
    if ok:
        return jsonify({"sucesso": True, "printer": printer_resolved})
    else:
        return jsonify({"sucesso": False, "erro": err, "printer": printer_resolved}), 500

@app.route("/testar-impressora", methods=["GET"])
def testar_impressora():
    """Envia uma linha de teste para a impressora configurada."""
    printer_db = get_printer_from_db()
    printer_resolved = printer_db or (win32print.GetDefaultPrinter() if (sys.platform == "win32" and win32print) else None)
    teste = "*** TESTE DE IMPRESSÃO - NOVALOJA ***\r\n"
    ok, err = send_to_printer(teste, printer_resolved)
    if ok:
        return jsonify({"sucesso": True, "printer": printer_resolved})
    else:
        return jsonify({"sucesso": False, "erro": err, "printer": printer_resolved}), 500

@app.route("/gerar-pdf", methods=["POST"])
def gerar_pdf():
    """Gera PDF do pedido e salva em c:\\novaloja1\\pedidos\\. Retorna o caminho relativo para download."""
    try:
        from reportlab.lib.pagesizes import A4
        from reportlab.pdfgen import canvas
        from reportlab.lib.units import mm
        import os
        from datetime import datetime
        
        dados = request.json or {}
        conteudo = dados.get("conteudo", "")
        produtos = dados.get("produtos", [])
        
        if not conteudo:
            return jsonify({"sucesso": False, "erro": "Conteúdo vazio"}), 400
        
        # Extrai dados do cliente do conteúdo para gravar em deliverypendente
        if produtos:
            try:
                gravar_delivery_pendente(conteudo, produtos)
            except Exception as e:
                print(f"[DELIVERY PENDENTE ERRO] {e}")
                traceback.print_exc()
        
        # Nome do arquivo com timestamp
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        nome_arquivo = f"pedido_{timestamp}.pdf"
        caminho_completo = os.path.join("c:\\novaloja1\\pedidos", nome_arquivo)
        
        # Criar PDF
        c = canvas.Canvas(caminho_completo, pagesize=A4)
        largura, altura = A4
        
        # Fonte monoespaçada para manter formatação
        c.setFont("Courier", 10)
        
        # Processar linhas
        linhas = conteudo.split('\n')
        y = altura - 40  # Margem superior
        for linha in linhas:
            if y < 40:  # Nova página se acabar espaço
                c.showPage()
                c.setFont("Courier", 10)
                y = altura - 40
            c.drawString(40, y, linha)
            y -= 14  # Espaçamento entre linhas
        
        c.save()
        
        # Retorna caminho relativo para servir via Flask
        return jsonify({
            "sucesso": True, 
            "arquivo": f"/pedidos/{nome_arquivo}",
            "caminho_completo": caminho_completo
        })
        
    except Exception as e:
        print("[GERAR PDF ERRO]", e)
        traceback.print_exc()
        return jsonify({"sucesso": False, "erro": str(e)}), 500

@app.route("/carrossel-imagens")
def carrossel_imagens():
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        cursor.execute("SELECT chave, nomeclassificacao, quantidadepartes, nrofoto AS nro_da_foto FROM classificacao")
        linhas = cursor.fetchall() or []

        imagens = []
        for row in linhas:
            classe = row.get("chave")
            nomeclassificacao = row.get("nomeclassificacao")
            nro = row.get("nro_da_foto")
            if nro is None:
                continue
            arquivo = f"/static/img/{int(nro)}.jpeg"
            imagens.append({
                "arquivo": arquivo,
                "classe": str(classe) if classe is not None else "",
                "nome": nomeclassificacao or "",
                "max": int(row.get("quantidadepartes") or 0)
            })

        print("[CARROSSEL] imagens montadas:")
        try:
            pprint(imagens)
        except Exception:
            pass
        return jsonify(imagens)
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500
    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500
    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexÃ£o:", e)
def produtos_filtrar():
    """Retorna produtos onde produtos.classe = nomeclassificacao recebido em 'nome'."""
    nome = request.args.get("nome")
    conn = None
    cursor = None
    try:
        if not nome:
            return jsonify([])

        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        cursor.execute("SELECT produto, preco, classe FROM produtos WHERE classe = %s", (nome,))
        resultados = cursor.fetchall() or []

        resultados = [convert_types(r) for r in resultados]
        return jsonify(resultados)

    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500

    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500

    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexÃ£o:", e)

@app.route("/produtos-filtrar")
def produtos_filtrar():
    """Retorna produtos onde produtos.classe = nomeclassificacao recebido em 'nome'."""
    nome = request.args.get("nome")
    conn = None
    cursor = None
    try:
        if not nome:
            return jsonify([])

        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        cursor.execute("SELECT produto, preco, classe, chave FROM produtos WHERE classe = %s", (nome,))
        resultados = cursor.fetchall() or []

        resultados = [convert_types(r) for r in resultados]
        return jsonify(resultados)

    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500

    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500

    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexÃ£o:", e)

@app.route("/produto/<classe>")
def produto(classe):
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)

        # Debug log no servidor
        print(f"[DEBUG] Consulta produto pela classe: {classe}")
        cursor.execute("SELECT * FROM produtos WHERE classe = %s", (classe,))
        
        resultado = cursor.fetchone()
        cursor.fetchall()  # Limpa qualquer resultado pendente
        pprint(resultado)
        resultado = convert_types(resultado)
       

        if resultado:
            
            return jsonify(resultado)  # 200
        else:
            return jsonify({"erro": "Produto nÃ£o encontrado", "classe": classe}), 404

    except mysql.connector.Error as db_err:
        # log detalhado no servidor
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500

    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500

    finally:
        # Fecha cursor/conn apenas se existirem
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)

        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexÃ£o:", e)


@app.route("/buscar-cliente")
def buscar_cliente():
    telefone = request.args.get("telefone")
    conn = None
    cursor = None
    try:
        if not telefone:
            return jsonify({"erro": "Telefone não fornecido"}), 400

        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        cursor.execute("SELECT * FROM clientes WHERE telefone = %s", (telefone,))
        resultado = cursor.fetchone()
        cursor.fetchall()

        if resultado:
            resultado = convert_types(resultado)
            return jsonify(resultado)
        else:
            return jsonify({"erro": "Cliente não encontrado"}), 404

    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500

    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500

    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexão:", e)

@app.route("/forma-cobrar")
def forma_cobrar():
    nome = request.args.get("nome", "")
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        cursor.execute("SELECT formadecobrar FROM classificacao WHERE nomeclassificacao = %s", (nome,))
        resultado = cursor.fetchone()
        cursor.fetchall()
        
        if resultado and resultado.get("formadecobrar"):
            forma = str(resultado["formadecobrar"]).lower().strip()
            return jsonify({"forma": forma})
        else:
            return jsonify({"forma": "normal"})
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500
    
    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500
    
    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexão:", e)

@app.route("/proximo-pedido", methods=["GET"])
def proximo_pedido():
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        # Cria tabela se não existir
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS contadorpedido (
                chave INT PRIMARY KEY,
                contador INT NOT NULL DEFAULT 0
            )
        """)
        
        # Verifica se existe registro
        cursor.execute("SELECT contador FROM contadorpedido WHERE chave = 1")
        resultado = cursor.fetchone()
        
        if resultado:
            # Incrementa o contador existente
            novo_numero = resultado["contador"] + 1
            cursor.execute("UPDATE contadorpedido SET contador = %s WHERE chave = 1", (novo_numero,))
            numero = novo_numero
        else:
            # Cria o registro inicial
            cursor.execute("INSERT INTO contadorpedido (chave, contador) VALUES (1, 1)")
            numero = 1
        
        conn.commit()
        return jsonify({"numero": numero})
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        if conn:
            conn.rollback()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500
    
    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500
    
    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexão:", e)

@app.route("/delivery-pendente", methods=["GET"])
def listar_delivery_pendente():
    """Lista todos os registros pendentes de entrega, agrupados por nropedido"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        # Busca registros agrupados por pedido
        cursor.execute("""
            SELECT 
                MIN(chave) as chave,
                nropedido,
                telefone,
                cep,
                nome,
                endereco,
                nrocasa,
                complemento,
                MAX(entregador) as entregador,
                SUM(CAST(preco AS DECIMAL(10,2))) as total_preco,
                COUNT(*) as total_produtos
            FROM deliverypendente
            GROUP BY nropedido, telefone, cep, nome, endereco, nrocasa, complemento
            ORDER BY MIN(chave) DESC
        """)
        
        registros = cursor.fetchall() or []
        registros = [convert_types(r) for r in registros]
        
        return jsonify({
            "sucesso": True,
            "total": len(registros),
            "registros": registros
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500
    
    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500
    
    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexão:", e)

@app.route("/atribuir-entregador", methods=["POST"])
def atribuir_entregador():
    """Atribui um entregador a um pedido na tabela deliverypendente"""
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        nropedido = dados.get("nropedido")
        entregador = dados.get("entregador", "").strip()
        
        if not nropedido:
            return jsonify({"erro": "Número do pedido é obrigatório"}), 400
        
        if not entregador:
            return jsonify({"erro": "Nome do entregador é obrigatório"}), 400
        
        conn = conectar()
        cursor = conn.cursor()
        
        # Atualiza o entregador em todos os produtos do pedido
        cursor.execute("""
            UPDATE deliverypendente 
            SET entregador = %s 
            WHERE nropedido = %s
        """, (entregador, nropedido))
        
        conn.commit()
        
        print(f"[ENTREGADOR] {entregador} atribuído ao pedido {nropedido}")
        
        return jsonify({
            "sucesso": True,
            "mensagem": f"Entregador {entregador} atribuído ao pedido {nropedido}"
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500
    
    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500
    
    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexão:", e)

@app.route("/fechar-comanda", methods=["POST"])
def fechar_comanda():
    """Transfere um pedido de deliverypendente para comanda (fecha a comanda)"""
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        nropedido = dados.get("nropedido")
        
        if not nropedido:
            return jsonify({"erro": "Número do pedido é obrigatório"}), 400
        
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        # Verifica se o pedido tem entregador atribuído
        cursor.execute("""
            SELECT entregador 
            FROM deliverypendente 
            WHERE nropedido = %s 
            LIMIT 1
        """, (nropedido,))
        
        resultado = cursor.fetchone()
        
        if not resultado:
            return jsonify({"erro": "Pedido não encontrado"}), 404
        
        entregador = resultado.get('entregador', '')
        
        if not entregador or entregador.strip() == '':
            return jsonify({"erro": "Não é possível fechar a comanda sem atribuir um entregador"}), 400
        
        # Transfere os dados de deliverypendente para comanda
        cursor.execute("""
            INSERT INTO comanda 
            (nropedido, telefone, nome, cep, endereco, nrocasa, complemento, 
             codigoproduto, produto, preco, quantidade, classe, entregador, cliente)
            SELECT nropedido, telefone, nome, cep, endereco, nrocasa, complemento,
                   codigoproduto, produto, preco, quantidade, classe, entregador, cliente
            FROM deliverypendente
            WHERE nropedido = %s
        """, (nropedido,))
        
        registros_transferidos = cursor.rowcount
        
        # Remove os registros de deliverypendente após transferir
        cursor.execute("""
            DELETE FROM deliverypendente 
            WHERE nropedido = %s
        """, (nropedido,))
        
        conn.commit()
        
        print(f"[FECHAR COMANDA] Pedido {nropedido} transferido para comanda ({registros_transferidos} registros)")
        
        return jsonify({
            "sucesso": True,
            "mensagem": f"Comanda do pedido {nropedido} fechada com sucesso",
            "registros_transferidos": registros_transferidos
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500
    
    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500
    
    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexão:", e)

@app.route("/cancelar-pedido", methods=["POST"])
def cancelar_pedido():
    """Transfere um pedido de deliverypendente para canceladas"""
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        nropedido = dados.get("nropedido")
        
        if not nropedido:
            return jsonify({"erro": "Número do pedido é obrigatório"}), 400
        
        conn = conectar()
        cursor = conn.cursor()
        
        # Transfere os dados de deliverypendente para canceladas
        cursor.execute("""
            INSERT INTO canceladas 
            (nropedido, cliente, telefone, nome, cep, endereco, nrocasa, complemento, 
             codigoproduto, produto, preco, quantidade, classe, entregador)
            SELECT nropedido, cliente, telefone, nome, cep, endereco, nrocasa, complemento,
                   codigoproduto, produto, preco, quantidade, classe, entregador
            FROM deliverypendente
            WHERE nropedido = %s
        """, (nropedido,))
        
        registros_transferidos = cursor.rowcount
        
        # Remove os registros de deliverypendente após transferir
        cursor.execute("""
            DELETE FROM deliverypendente 
            WHERE nropedido = %s
        """, (nropedido,))
        
        conn.commit()
        
        print(f"[CANCELAR PEDIDO] Pedido {nropedido} transferido para canceladas ({registros_transferidos} registros)")
        
        return jsonify({
            "sucesso": True,
            "mensagem": f"Pedido {nropedido} cancelado com sucesso",
            "registros_transferidos": registros_transferidos
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500
    
    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500
    
    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexão:", e)

@app.route("/salvar-cliente", methods=["POST"])
def salvar_cliente():
    conn = None
    cursor = None
    try:
        dados = request.json or {}
        telefone = dados.get("telefone")
        
        if not telefone:
            return jsonify({"erro": "Telefone é obrigatório"}), 400

        # Distância: usa valor manual se enviado (>0), senão calcula automático
        distancia_bruta = dados.get("distancia", 0)
        try:
            distancia_bruta = float(distancia_bruta)
        except Exception:
            distancia_bruta = 0
        distancia_calc, lat_cli, lon_cli = calcular_distancia_cliente(dados)
        distancia_final = distancia_bruta if distancia_bruta > 0 else distancia_calc
        
        # Calcula taxa de entrega baseado na distância
        taxa_entrega = calcular_taxa_entrega(distancia_final)

        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        # Verificar se o cliente já existe
        cursor.execute("SELECT chave FROM clientes WHERE telefone = %s", (telefone,))
        cliente_existente = cursor.fetchone()
        
        # Verificar se as colunas lat_cliente e lon_cliente existem
        cursor.execute("SHOW COLUMNS FROM clientes LIKE 'lat_cliente'")
        tem_lat_lon = cursor.fetchone() is not None
        # Verificar se coluna CEP existe
        cursor.execute("SHOW COLUMNS FROM clientes LIKE 'cep'")
        tem_cep = cursor.fetchone() is not None
        
        if cliente_existente:
            # Atualizar cliente existente
            if tem_lat_lon and tem_cep:
                sql = """UPDATE clientes SET 
                         nome = %s, endereco = %s, nrocasa = %s, complemento = %s,
                         referencia = %s, bairro = %s, cidade = %s, estado = %s,
                         taxaentrega = %s, distancia = %s, lat_cliente = %s, lon_cliente = %s, cep = %s
                         WHERE telefone = %s"""
                valores = (
                    dados.get("nome", ""),
                    dados.get("endereco", ""),
                    dados.get("nrocasa", ""),
                    dados.get("complemento", ""),
                    dados.get("referencia", ""),
                    dados.get("bairro", ""),
                    dados.get("cidade", ""),
                    dados.get("estado", ""),
                    taxa_entrega,
                    distancia_final,
                    lat_cli,
                    lon_cli,
                    dados.get("cep", ""),
                    telefone
                )
            elif tem_lat_lon and not tem_cep:
                sql = """UPDATE clientes SET 
                         nome = %s, endereco = %s, nrocasa = %s, complemento = %s,
                         referencia = %s, bairro = %s, cidade = %s, estado = %s,
                         taxaentrega = %s, distancia = %s, lat_cliente = %s, lon_cliente = %s
                         WHERE telefone = %s"""
                valores = (
                    dados.get("nome", ""),
                    dados.get("endereco", ""),
                    dados.get("nrocasa", ""),
                    dados.get("complemento", ""),
                    dados.get("referencia", ""),
                    dados.get("bairro", ""),
                    dados.get("cidade", ""),
                    dados.get("estado", ""),
                    taxa_entrega,
                    distancia_final,
                    lat_cli,
                    lon_cli,
                    telefone
                )
            elif tem_cep and not tem_lat_lon:
                sql = """UPDATE clientes SET 
                         nome = %s, endereco = %s, nrocasa = %s, complemento = %s,
                         referencia = %s, bairro = %s, cidade = %s, estado = %s,
                         taxaentrega = %s, distancia = %s, cep = %s
                         WHERE telefone = %s"""
                valores = (
                    dados.get("nome", ""),
                    dados.get("endereco", ""),
                    dados.get("nrocasa", ""),
                    dados.get("complemento", ""),
                    dados.get("referencia", ""),
                    dados.get("bairro", ""),
                    dados.get("cidade", ""),
                    dados.get("estado", ""),
                    taxa_entrega,
                    distancia_final,
                    dados.get("cep", ""),
                    telefone
                )
            else:
                sql = """UPDATE clientes SET 
                         nome = %s, endereco = %s, nrocasa = %s, complemento = %s,
                         referencia = %s, bairro = %s, cidade = %s, estado = %s,
                         taxaentrega = %s, distancia = %s
                         WHERE telefone = %s"""
                valores = (
                    dados.get("nome", ""),
                    dados.get("endereco", ""),
                    dados.get("nrocasa", ""),
                    dados.get("complemento", ""),
                    dados.get("referencia", ""),
                    dados.get("bairro", ""),
                    dados.get("cidade", ""),
                    dados.get("estado", ""),
                    taxa_entrega,
                    distancia_final,
                    telefone
                )
            cursor.execute(sql, valores)
            conn.commit()
            return jsonify({"sucesso": True, "mensagem": "Cliente atualizado com sucesso", "chave": cliente_existente["chave"], "distancia_calculada": distancia_final, "taxa_calculada": taxa_entrega})
        else:
            # Inserir novo cliente conforme colunas disponíveis
            if tem_lat_lon and tem_cep:
                sql = """INSERT INTO clientes 
                         (telefone, nome, endereco, nrocasa, complemento, referencia, 
                          bairro, cidade, estado, taxaentrega, distancia, lat_cliente, lon_cliente, cep)
                         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
                valores = (
                    telefone,
                    dados.get("nome", ""),
                    dados.get("endereco", ""),
                    dados.get("nrocasa", ""),
                    dados.get("complemento", ""),
                    dados.get("referencia", ""),
                    dados.get("bairro", ""),
                    dados.get("cidade", ""),
                    dados.get("estado", ""),
                    taxa_entrega,
                    distancia_final,
                    lat_cli,
                    lon_cli,
                    dados.get("cep", "")
                )
            elif tem_lat_lon and not tem_cep:
                sql = """INSERT INTO clientes 
                         (telefone, nome, endereco, nrocasa, complemento, referencia, 
                          bairro, cidade, estado, taxaentrega, distancia, lat_cliente, lon_cliente)
                         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
                valores = (
                    telefone,
                    dados.get("nome", ""),
                    dados.get("endereco", ""),
                    dados.get("nrocasa", ""),
                    dados.get("complemento", ""),
                    dados.get("referencia", ""),
                    dados.get("bairro", ""),
                    dados.get("cidade", ""),
                    dados.get("estado", ""),
                    taxa_entrega,
                    distancia_final,
                    lat_cli,
                    lon_cli
                )
            elif tem_cep and not tem_lat_lon:
                sql = """INSERT INTO clientes 
                         (telefone, nome, endereco, nrocasa, complemento, referencia, 
                          bairro, cidade, estado, taxaentrega, distancia, cep)
                         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
                valores = (
                    telefone,
                    dados.get("nome", ""),
                    dados.get("endereco", ""),
                    dados.get("nrocasa", ""),
                    dados.get("complemento", ""),
                    dados.get("referencia", ""),
                    dados.get("bairro", ""),
                    dados.get("cidade", ""),
                    dados.get("estado", ""),
                    taxa_entrega,
                    distancia_final,
                    dados.get("cep", "")
                )
            else:
                sql = """INSERT INTO clientes 
                         (telefone, nome, endereco, nrocasa, complemento, referencia, 
                          bairro, cidade, estado, taxaentrega, distancia)
                         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
                valores = (
                    telefone,
                    dados.get("nome", ""),
                    dados.get("endereco", ""),
                    dados.get("nrocasa", ""),
                    dados.get("complemento", ""),
                    dados.get("referencia", ""),
                    dados.get("bairro", ""),
                    dados.get("cidade", ""),
                    dados.get("estado", ""),
                    taxa_entrega,
                    distancia_final
                )
            cursor.execute(sql, valores)
            conn.commit()
            return jsonify({"sucesso": True, "mensagem": "Cliente cadastrado com sucesso", "chave": cursor.lastrowid, "distancia_calculada": distancia_final, "taxa_calculada": taxa_entrega})
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        traceback.print_exc()
        if conn:
            conn.rollback()
        return jsonify({"erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500
    
    except Exception as e:
        print("[ERROR]", e)
        traceback.print_exc()
        return jsonify({"erro": "Erro interno no servidor", "detalhes": str(e)}), 500
    
    finally:
        try:
            if cursor:
                cursor.close()
        except Exception as e:
            print("[WARN] falha ao fechar cursor:", e)
        try:
            if conn:
                conn.close()
        except Exception as e:
            print("[WARN] falha ao fechar conexão:", e)

@app.route("/api/comandas", methods=["GET"])
def api_comandas():
    """Retorna todos os registros da tabela comanda em JSON"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("SELECT * FROM comanda")
        registros = cursor.fetchall() or []
        
        return jsonify({
            "sucesso": True,
            "registros": registros
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro de banco de dados"}), 500
    
    except Exception as e:
        print("[ERROR]", e)
        return jsonify({"sucesso": False, "erro": "Erro interno no servidor"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/api/canceladas", methods=["GET"])
def api_canceladas():
    """Retorna todos os registros da tabela canceladas em JSON"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("SELECT * FROM canceladas")
        registros = cursor.fetchall() or []
        
        return jsonify({
            "sucesso": True,
            "registros": registros
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro de banco de dados"}), 500
    
    except Exception as e:
        print("[ERROR]", e)
        return jsonify({"sucesso": False, "erro": "Erro interno no servidor"}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/criar-coluna-cliente-canceladas", methods=["POST"])
def criar_coluna_cliente_canceladas():
    """Adiciona as colunas cliente nas tabelas canceladas, comanda e deliverypendente se não existir"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor()
        
        # Verifica e adiciona coluna cliente na tabela canceladas
        cursor.execute("SHOW COLUMNS FROM canceladas LIKE 'cliente'")
        if cursor.fetchone() is None:
            cursor.execute("ALTER TABLE canceladas ADD COLUMN cliente VARCHAR(255) NULL")
            print("[INFO] Coluna 'cliente' adicionada à tabela canceladas")
        
        # Verifica e adiciona coluna cliente na tabela comanda
        cursor.execute("SHOW COLUMNS FROM comanda LIKE 'cliente'")
        if cursor.fetchone() is None:
            cursor.execute("ALTER TABLE comanda ADD COLUMN cliente VARCHAR(255) NULL")
            print("[INFO] Coluna 'cliente' adicionada à tabela comanda")
        
        # Verifica e adiciona coluna cliente na tabela deliverypendente
        cursor.execute("SHOW COLUMNS FROM deliverypendente LIKE 'cliente'")
        if cursor.fetchone() is None:
            cursor.execute("ALTER TABLE deliverypendente ADD COLUMN cliente VARCHAR(255) NULL")
            print("[INFO] Coluna 'cliente' adicionada à tabela deliverypendente")
        
        # Verifica e adiciona coluna telefone na tabela canceladas (se não existir)
        cursor.execute("SHOW COLUMNS FROM canceladas LIKE 'telefone'")
        if cursor.fetchone() is None:
            # Adiciona após nropedido
            cursor.execute("ALTER TABLE canceladas ADD COLUMN telefone VARCHAR(20) NULL AFTER nropedido")
            print("[INFO] Coluna 'telefone' adicionada à tabela canceladas")
        
        return jsonify({"sucesso": True, "mensagem": "Colunas adicionadas com sucesso"})
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": "Erro de banco de dados", "detalhes": str(db_err)}), 500
    
    except Exception as e:
        print("[ERROR]", e)
        return jsonify({"sucesso": False, "erro": "Erro interno", "detalhes": str(e)}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

# Servir arquivos PDF estáticos da pasta pedidos
@app.route("/pedidos/<path:filename>")
def servir_pdf(filename):
    """Serve PDFs gerados da pasta pedidos."""
    from flask import send_from_directory
    return send_from_directory("c:\\novaloja1\\pedidos", filename)

@app.route("/criar-tabela-usuarios", methods=["POST"])
def criar_tabela_usuarios():
    """Cria a tabela de usuários para login"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor()
        
        # Criar tabela
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS usuarios (
                chave INT AUTO_INCREMENT PRIMARY KEY,
                usuario VARCHAR(100) NOT NULL UNIQUE,
                senha VARCHAR(255) NOT NULL,
                data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        """)
        
        # Inserir usuário padrão
        cursor.execute("SELECT COUNT(*) FROM usuarios WHERE usuario = 'admin'")
        if cursor.fetchone()[0] == 0:
            cursor.execute("INSERT INTO usuarios (usuario, senha) VALUES ('admin', 'admin')")
        
        conn.commit()
        
        print("[INFO] Tabela 'usuarios' criada com sucesso")
        return jsonify({"sucesso": True, "mensagem": "Tabela de usuários criada com sucesso"})
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": str(db_err)}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/atualizar-cliente-comanda", methods=["POST"])
def atualizar_cliente_comanda():
    """Atualiza o campo cliente na tabela comanda copiando de nome"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor()
        
        # Atualiza registros onde cliente está vazio
        cursor.execute("UPDATE comanda SET cliente = nome WHERE cliente IS NULL OR cliente = ''")
        registros_atualizados = cursor.rowcount
        
        conn.commit()
        
        print(f"[INFO] {registros_atualizados} registros atualizados na tabela comanda")
        return jsonify({
            "sucesso": True, 
            "mensagem": f"{registros_atualizados} registros atualizados com sucesso"
        })
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": str(db_err)}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route("/verificar-estrutura-produtos", methods=["GET"])
def verificar_estrutura_produtos():
    """Retorna a estrutura da tabela produtos"""
    conn = None
    cursor = None
    try:
        conn = conectar()
        cursor = conn.cursor(dictionary=True)
        
        # Mostra as colunas da tabela
        cursor.execute("DESCRIBE produtos")
        colunas = cursor.fetchall()
        
        return jsonify({"sucesso": True, "colunas": colunas})
    
    except mysql.connector.Error as db_err:
        print("[DB ERROR]", db_err)
        return jsonify({"sucesso": False, "erro": str(db_err)}), 500
    
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=2001, debug=True)

