import sys
import unicodedata
import spacy
import mysql.connector
from mysql.connector import Error
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords

# Baixa os recursos necessários
nltk.download('punkt')
nltk.download('stopwords')

# Configuração do banco de dados
from identifica_cripto import dbname, username, password

# Dicionário de classificação de tokens
TOKEN_CLASSES = {
    "ADJ": "adjetivo",
    "ADV": "adverbio",
    "DET": "artigo",
    "NUM": "numeral",
    "CONJ": "conjuncao",
    "INTJ": "interjeicao",
    "NOUN": "substantivo",
    "PRON": "pronome",
    "PROPN": "substantivo",
    "PUNCT": "pontuacao",
    "SYM": "sigla",
    "ADP": "preposicao",
    "VERB": "verbo"
}

# Lista de palavras que devem ser substantivos
CORRECAO_MANUAL = {
    "facilitador": "NOUN",
    "coordenador": "NOUN",
    "engenheiro": "NOUN",
    "analista": "NOUN",
    "gestor": "NOUN",
    "supervisor": "NOUN",
    "desincrustador": "NOUN",
    "detergente": "NOUN"
}

# Conectar ao banco de dados
def connect_db():
    try:
        conn = mysql.connector.connect(host="localhost", database=dbname, user=username, password=password)
        return conn
    except Error as e:
        print(f"Erro ao conectar ao banco de dados: {e}")
        sys.exit(1)

# Normalizar texto removendo acentos
def normalize_text(text):
    return ''.join(c for c in unicodedata.normalize('NFD', text.lower()) if unicodedata.category(c) != 'Mn')

# Obter `id_chave_tipo_token` para um tipo de token
def get_tipo_token_id(conn, tipo_token):
    with conn.cursor(buffered=True) as cursor:
        cursor.execute("SELECT id_chave_tipo_token FROM tipos_tokens WHERE nome_tipo_token = %s", (tipo_token,))
        result = cursor.fetchone()
        return result[0] if result else None

# Obter `id_chave_token` a partir do `acentuada`
def get_token_id(conn, acentuada):
    with conn.cursor(buffered=True) as cursor:
        cursor.execute("SELECT id_chave_token FROM tokens WHERE acentuada = %s", (acentuada,))
        result = cursor.fetchone()
        return result[0] if result else None

# Obter `id_chave_ocupacao` a partir de `codigo_justaposto`
def get_ocupacao_id(conn, codigo_justaposto):
    with conn.cursor(buffered=True) as cursor:
        cursor.execute("SELECT id_chave_ocupacao FROM ocupacoes WHERE codigo_justaposto = %s", (codigo_justaposto,))
        result = cursor.fetchone()
        return result[0] if result else None

# Excluir registros com data_insercao maior ou igual a 2025-03-07 21:56:12
def excluir_dados_recentes(conn):
    with conn.cursor() as cursor:
        cursor.execute("DELETE FROM tokens WHERE data_insercao >= '2025-03-07 21:56:12'")
        cursor.execute("DELETE FROM tokens_ocupacoes WHERE data_insercao >= '2025-03-07 21:56:12'")
        conn.commit()

# Processar ocupações e gerar INSERT IGNORE ou UPDATE
def processar_ocupacoes(output_file):
    conn = connect_db()
    try:
        #excluir_dados_recentes(conn)
        with conn.cursor(buffered=True) as cursor:
            # Carregar modelo spaCy para POS tagging
            nlp = spacy.load("pt_core_news_lg")

            # Pega todas as ocupações
            cursor.execute("SELECT id_chave_ocupacao, codigo_justaposto, nome_ocupacao FROM ocupacoes")
            ocupacoes = cursor.fetchall()

            inserts_tokens = []
            updates_tokens_ocupacoes = []

            for id_ocupacao, codigo_justaposto, nome_ocupacao in ocupacoes:
                tokens = word_tokenize(nome_ocupacao.lower(), language='portuguese')
                tokens = [t for t in tokens if t.isalpha() and t not in stopwords.words('portuguese')]

                doc = nlp(nome_ocupacao)
                for token in doc:
                    token_acentuado = token.text.lower()
                    token_normalizado = normalize_text(token_acentuado)
                    token_pos = CORRECAO_MANUAL.get(token_acentuado, token.pos_) # se estiver na lista de correcao, usa o valor da lista, senão usa o valor do token.pos_
                    tipo_token = TOKEN_CLASSES.get(token_pos, "substantivo")     # se não encontrar o token_pos, usa substantivo
                    if token_acentuado in stopwords.words('portuguese'):
                        continue  # Ignora stopwords

                    id_tipo_token = get_tipo_token_id(conn, tipo_token)
                    if not id_tipo_token:
                        tipo_token = "tipo token nao encontrado"
                        #continue  # Se não encontrou tipo de token, pula

                    insert_token = f"INSERT IGNORE INTO tokens (nome_token, acentuada, id_tipo_token, id_tipo_token_spaCy) VALUES ('{token_normalizado}', '{token_acentuado}', (SELECT id_chave_tipo_token FROM tipos_tokens WHERE nome_tipo_token = '{tipo_token}'), (SELECT id_chave_tipo_token FROM tipos_tokens WHERE nome_tipo_token = '{tipo_token}')); # {token.pos_}"
                    inserts_tokens.append(insert_token)

                    id_token = get_token_id(conn, token_acentuado)
                    id_ocupacao_db = get_ocupacao_id(conn, codigo_justaposto)

                    if id_token and id_ocupacao_db:
                        update_token_ocupacao = (f"INSERT INTO tokens_ocupacoes (id_token, id_ocupacao, conta) VALUES ((SELECT id_chave_token FROM tokens WHERE acentuada = '{token_acentuado}' and id_tipo_token_spaCy = (SELECT id_chave_tipo_token FROM tipos_tokens WHERE nome_tipo_token = '{tipo_token}')), (SELECT id_chave_ocupacao FROM ocupacoes WHERE codigo_justaposto = '{codigo_justaposto}'), 1) "
                                                 f"ON DUPLICATE KEY UPDATE conta = conta + 1;")
                        updates_tokens_ocupacoes.append(update_token_ocupacao)
    finally:
        conn.close()

    # Escreve os INSERTs e UPDATES no arquivo SQL
    with open(output_file, "w", encoding="utf-8") as f:
        f.write("-- INSERTS PARA A TABELA tokens\n")
        f.write("\n".join(set(inserts_tokens)))
        f.write("\n\n-- INSERTS/UPDATES PARA A TABELA tokens_ocupacoes\n")
        f.write("\n".join(set(updates_tokens_ocupacoes)))

    print(f"Arquivo SQL '{output_file}' gerado com sucesso.")

# Verificar argumentos da linha de comando
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Uso: python processa_tokens.py <arquivo_de_saida.sql>")
        sys.exit(1)

    output_file = sys.argv[1]
    processar_ocupacoes(output_file)

