import pygame
import time
import mysql.connector
from plyer import notification
import pyttsx3  # Importa a biblioteca de fala

# Variáveis para armazenar o status anterior e o ID do último registro processado
ultimo_status = None
ultimo_usuario = None
ultimo_id = None  # Variável para armazenar o último ID processado
ultimo_arrival_time = None  # Variável para armazenar o último timestamp de arrival_time

# Fluxo de status normal e alternativo
fluxoStatusNormal = [
    "Aguardando entrada",
    "Autorizado",
    "Liberado Entrada",
    "Entrada Veiculo",
    "Pesagem Inicial concluída",
    "Inicio de processo",
    "Fim do processo",
    "Liberado Saida",
    "Pesagem final concluída",
    "Saída veiculo"
]

fluxoStatusAlternativo = [
    "Aguardando entrada",
    "Autorizado",
    "Entrada Veiculo",
    "Inicio de processo",  # Pula a pesagem inicial
    "Fim do processo",
    "Saída veiculo"
]

# Conectar ao banco de dados MySQL
def conectar_banco():
    try:
        connection = mysql.connector.connect(
            host='localhost',      # Altere conforme necessário
            user='yms',             # Seu usuário do banco de dados
            password='@novo2025',  # Sua senha do banco de dados
            database='balanca'     # Nome do banco de dados
        )
        if connection.is_connected():
            print("Conexão bem-sucedida ao banco de dados.")
        return connection
    except mysql.connector.Error as err:
        print(f"Erro ao conectar ao banco de dados: {err}")
        return None

# Função para inicializar o mecanismo de fala
def inicializar_fala():
    engine = pyttsx3.init()
    engine.setProperty('rate', 140)  # Ajusta a velocidade da fala (opcional)
    engine.setProperty('volume', 1)  # Ajusta o volume (0.0 a 1.0)
    return engine

# Função para tocar o som da sineta e garantir que a fala só aconteça depois
def tocar_som_sineta():
    pygame.mixer.init()  # Inicializa o mixer do pygame para tocar o som
    pygame.mixer.music.load("sineta.mp3")  # Carrega o arquivo de áudio (substitua pelo caminho do seu arquivo de sineta)
    pygame.mixer.music.play()  # Toca o áudio
    
    # Aguarda até que o som termine de tocar
    while pygame.mixer.music.get_busy():  # Enquanto a música (sineta) estiver tocando
        time.sleep(0.1)  # Dá uma pausa de 0.1 segundo para evitar uso excessivo de CPU

# Função para verificar o status e enviar notificação
def verificar_status():
    global ultimo_status, ultimo_usuario, ultimo_id, ultimo_arrival_time  # Usar as variáveis globais para armazenar os valores anteriores

    connection = conectar_banco()
    if connection is None:
        return

    cursor = connection.cursor(dictionary=True)  # Para obter resultados como dicionário
    try:
        # Consulta para obter o último status
        cursor.execute("SELECT * FROM entrada_veiculo WHERE frota IS NULL OR TRIM(frota) = '' ORDER BY arrival_time DESC LIMIT 1;")
        resultado = cursor.fetchone()

        if resultado:
            # Recupera os valores do banco de dados
            status_atual = resultado['status']
            usuario_atual = resultado['update_by']
            id_atual = resultado['id']  # Supondo que 'id' seja o campo identificador único
            arrival_time_atual = resultado['arrival_time']  # Timestamp da chegada
            carrier = resultado['carrier']  # Nome da empresa
            driver_name = resultado['driver_name']  # Nome do condutor
            finalidade = resultado['finalidade']  # Recupera o valor da coluna 'finalidade'
            setorautoriza = resultado['setorautoriza']  # Recupera o valor da coluna 'setorautoriza'
            
            # Exibe os dados recuperados para depuração
            print(f"Status atual: {status_atual} por {usuario_atual}, ID: {id_atual}, arrival_time: {arrival_time_atual}, "
                  f"Carrier: {carrier}, Driver: {driver_name}, Finalidade: {finalidade}, Aguardando autorização: {setorautoriza}")

            # Verifica se o status atual está dentro do fluxo esperado
            if status_atual not in fluxoStatusNormal and status_atual not in fluxoStatusAlternativo:
                print("Status não reconhecido, ignorando...")
                return  # Ignora se o status não estiver no fluxo

            # Se o status for "Aguardando entrada", notifique de forma personalizada
            if status_atual == "Aguardando entrada":
                # Usamos o valor do campo 'finalidade' aqui
                finalidade_mensagem = (f"Acabou de chegar, um veículo da empresa {carrier}, "
                                       f"conduzido por {driver_name}. Finalidade: {finalidade}, "
                                       f"Aguardando autorização do setor {setorautoriza}.")
            # Se o status for "Autorizado", notifique com o update_by
            elif status_atual == "Autorizado":
                finalidade_mensagem = (f"Autorizado pelo {usuario_atual}, "
                                       f"Aguardando autorização do Fiscal de Pesagem.")
            # Se o status for "Liberado Entrada", notifique com a entrada liberada
            elif status_atual == "Liberado Entrada":
                finalidade_mensagem = (f"Entrada Liberada pelo Fiscal de Pesagem, "
                                       f"{usuario_atual}, Aguardando Entrada do veículo.")
            # Se o status for "Entrada Veiculo", notifique sobre a entrada do veículo
            elif status_atual == "Entrada Veiculo":
                finalidade_mensagem = (f"Veículo acabou de entrar, seguiu para pesagem inicial.")
            # Se o status for "Pesagem Inicial Concluída", notifique e verifique a finalidade
            elif status_atual == "Pesagem Inicial concluída":
                if finalidade == "coleta":
                    finalidade_mensagem = (f"Pesagem inicial concluída, seguindo para o setor {setorautoriza}. "
                                           f"Segue para Carregamento da carga.")
                elif finalidade == "entrega":
                    finalidade_mensagem = (f"Pesagem inicial concluída, seguindo para o setor {setorautoriza}. "
                                           f"Segue para Descarregamento de carga.")
                else:
                    finalidade_mensagem = (f"Pesagem inicial concluída, seguindo para o setor {setorautoriza}. "
                                           f"Finalidade não especificada.")
            # Se o status for "Inicio de processo", verifique a finalidade
            elif status_atual == "Inicio de processo":
                if finalidade == "coleta":
                    finalidade_mensagem = "Iniciado o processo de carregamento."
                elif finalidade == "entrega":
                    finalidade_mensagem = "Iniciado o processo de descarregamento."
                else:
                    finalidade_mensagem = "Iniciado o processo, finalidade não especificada."
            # Se o status for "Fim do processo", verifique a finalidade
            elif status_atual == "Fim do processo":
                if finalidade == "coleta":
                    finalidade_mensagem = "Fim do carregamento do veículo."
                elif finalidade == "entrega":
                    finalidade_mensagem = "Fim do descarregamento do veículo, aguardando autorização de pesagem final."
                else:
                    finalidade_mensagem = "Fim do processo, finalidade não especificada."
            # Se o status for "Liberado Saida", notifique sobre a saída liberada
            elif status_atual == "Liberado Saida":
                finalidade_mensagem = "Liberado saída para pesagem final."
            # Se o status for "Pesagem final concluída", fale sobre a pesagem final
            elif status_atual == "Pesagem final concluída":
                finalidade_mensagem = "Pesagem final concluída, aguardando saída."
            # Se o status for "Saída veiculo", notifique sobre a saída do veículo
            elif status_atual == "Saída veiculo":
                finalidade_mensagem = "Veículo foi inspecionado e acabou de sair."
            else:
                finalidade_mensagem = f"Status: {status_atual}\nAtualizado por: {usuario_atual}"

            # Verifica se houve atualização no status ou no usuário, e se o ID é diferente do último processado
            if (status_atual != ultimo_status or usuario_atual != ultimo_usuario or id_atual != ultimo_id or arrival_time_atual != ultimo_arrival_time):
                # Se houve atualização, notifica e emite som
                notification.notify(
                    title="Status Atualizado",
                    message=finalidade_mensagem,
                    timeout=10  # Tempo que a notificação ficará visível
                )

                # Toca o som da sineta
                tocar_som_sineta()

                # Inicializa o motor de fala
                engine = inicializar_fala()
                engine.say(finalidade_mensagem)  # Fala a mensagem
                engine.runAndWait()  # Espera a fala terminar

                # Atualiza os valores armazenados
                ultimo_status = status_atual
                ultimo_usuario = usuario_atual
                ultimo_id = id_atual  # Atualiza o último ID processado
                ultimo_arrival_time = arrival_time_atual  # Atualiza o último timestamp de arrival_time
            else:
                print("Sem atualização no status ou no usuário, ou registro já processado.")
        else:
            print("Nenhuma atualização encontrada no banco de dados.")
    
    except mysql.connector.Error as err:
        print(f"Erro na consulta ao banco de dados: {err}")
    
    finally:
        cursor.close()
        connection.close()

# Função principal que executa o script continuamente
if __name__ == "__main__":
    while True:
        verificar_status()
        time.sleep(10)  # Intervalo de 10 segundos entre as verificações
