# -*- coding: utf-8 -*-
"""
COMPROVEI ROBÔ MONITORADO
Versão com:
- log em arquivo
- monitoramento em tempo real
- screenshot automático de erro
- tempo de execução por etapa
- pausa final para leitura
- correção rename mesmo arquivo
- correção seleção CSV antigo
- aguarda CSV finalizar download antes de prosseguir
- log de arquivos na pasta para debug
"""

import time
import os
import glob
import traceback
from datetime import datetime, timedelta
from ftplib import FTP
import requests
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager

# =====================================================
# CONFIGURAÇÕES

DEBUG = True

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
LOG_ARQUIVO = os.path.join(BASE_DIR, "comprovei_log.txt")
SCREENSHOT_ERRO = os.path.join(BASE_DIR, "erro_selenium.png")

# =====================================================
# LOGIN COMPROVEI

DOMINIO = "suvinil"
USUARIO = "BrandaoMFassi"
SENHA = "1234"
URL_LOGIN = "https://ct.comprovei.com/"

# =====================================================
# PASTA DOWNLOAD

PASTA_DOWNLOADS = r"C:\Users\kreat\Downloads\Comprovei"
ARQUIVO_PADRAO = "ultimo_arquivo.csv"

# =====================================================
# FTP

FTP_HOST = "ftp.ksoftlog.com.br"
FTP_PORT = 21
FTP_USER = "ksoftlogcom"
FTP_PASS = "#$!@2024_KS_TransportWeb"
FTP_REMOTE_PATH = "/comprovei/comprovei_csv/fassilog"

# =====================================================
# PHP IMPORTADOR

URL_PHP_IMPORTADOR = "https://moscassw.ksoftlog.com.br/send_ftp_ssw.php"

# =====================================================
# EMAIL

SMTP_HOST = "mail.ksoftlog.com.br"
SMTP_PORT = 587
SMTP_USER = "integracao@ksoftlog.com.br"
SMTP_PASS = "XR1KN792WR"
FROM_EMAIL = "integracao@ksoftlog.com.br"
TO_EMAIL = ["fabio@kreativesistemas.com.br"]

# =====================================================
# UTILIDADES


def log(msg):
    hora = datetime.now().strftime("%H:%M:%S")
    linha = f"[{hora}] {msg}"
    print(linha)

    with open(LOG_ARQUIVO, "a", encoding="utf-8") as f:
        f.write(linha + "\n")


def pausa_final():
    if DEBUG:
        input("\nPressione ENTER para fechar...")


def medir_tempo(nome, inicio):
    tempo = round(time.time() - inicio, 2)
    log(f"{nome} concluído em {tempo}s")


# =====================================================
# EMAIL ERRO


def enviar_email_erro(assunto, mensagem):
    try:
        msg = MIMEMultipart()
        msg["From"] = FROM_EMAIL
        msg["To"] = ", ".join(TO_EMAIL)
        msg["Subject"] = assunto

        corpo = f"""
ALERTA AUTOMAÇÃO COMPROVEI

Data/Hora: {datetime.now().strftime('%d/%m/%Y %H:%M:%S')}

{mensagem}
"""

        msg.attach(MIMEText(corpo, "plain", "utf-8"))

        server = smtplib.SMTP(SMTP_HOST, SMTP_PORT)
        server.starttls()
        server.login(SMTP_USER, SMTP_PASS)
        server.send_message(msg)
        server.quit()

        log("📧 Email de erro enviado.")

    except Exception as e:
        log(f"Falha ao enviar email: {e}")


# =====================================================
# CSV


def limpar_arquivo_padrao_antigo():
    """
    Remove ultimo_arquivo.csv antigo antes de novo processo.
    """
    try:
        destino = os.path.join(PASTA_DOWNLOADS, ARQUIVO_PADRAO)

        if os.path.exists(destino):
            os.remove(destino)
            log("Arquivo padrão antigo removido.")

    except Exception as e:
        log(f"Falha ao remover arquivo antigo: {e}")


def aguardar_csv(timeout=60):
    """
    Aguarda o arquivo CSV finalizar o download na pasta.
    Verifica a cada 2 segundos até o timeout (padrão 60s).
    Ignora arquivos .crdownload (ainda baixando) e o arquivo padrão.
    """
    log("Aguardando arquivo CSV finalizar download...")
    inicio = time.time()

    while time.time() - inicio < timeout:
        # Verifica se ainda há arquivos temporários de download
        crdownloads = glob.glob(os.path.join(PASTA_DOWNLOADS, "*.crdownload"))
        if crdownloads:
            log("Arquivo ainda baixando (.crdownload detectado)... aguardando.")
            time.sleep(2)
            continue

        arquivos = glob.glob(os.path.join(PASTA_DOWNLOADS, "*.csv"))
        validos = [
            f for f in arquivos
            if "relatorio" not in os.path.basename(f).lower()
            and os.path.basename(f).lower() != ARQUIVO_PADRAO.lower()
        ]

        if validos:
            log(f"CSV detectado: {os.path.basename(validos[0])}")
            return True

        time.sleep(2)

    log(f"Timeout de {timeout}s atingido — CSV não apareceu.")
    return False


def pegar_ultimo_csv():
    """
    Busca último CSV baixado ignorando:
    - ultimo_arquivo.csv
    - arquivos com relatorio no nome
    """
    arquivos = glob.glob(os.path.join(PASTA_DOWNLOADS, "*.csv"))

    arquivos_validos = [
        f for f in arquivos
        if "relatorio" not in os.path.basename(f).lower()
        and os.path.basename(f).lower() != ARQUIVO_PADRAO.lower()
    ]

    return max(arquivos_validos, key=os.path.getctime) if arquivos_validos else None


def renomear_para_padrao(arquivo):
    destino = os.path.join(PASTA_DOWNLOADS, ARQUIVO_PADRAO)

    # Se já for o mesmo arquivo, não faz nada
    if os.path.abspath(arquivo) == os.path.abspath(destino):
        log("Arquivo já está no nome padrão.")
        return destino

    if os.path.exists(destino):
        os.remove(destino)

    os.rename(arquivo, destino)
    log("Arquivo renomeado para padrão.")

    return destino


# =====================================================
# FTP


def enviar_ftp(arquivo):
    inicio = time.time()

    log("Conectando FTP...")

    ftp = FTP()
    ftp.connect(FTP_HOST, FTP_PORT)
    ftp.login(FTP_USER, FTP_PASS)
    ftp.cwd(FTP_REMOTE_PATH)

    with open(arquivo, "rb") as f:
        ftp.storbinary(f"STOR {os.path.basename(arquivo)}", f)

    ftp.quit()

    medir_tempo("FTP", inicio)


# =====================================================
# PHP


def executar_php_online():
    inicio = time.time()

    log("Chamando PHP importador...")

    resposta = requests.get(URL_PHP_IMPORTADOR, timeout=120)

    log(f"Retorno PHP: {resposta.text}")

    medir_tempo("PHP", inicio)


# =====================================================
# SELENIUM


def baixar_relatorio():
    inicio_total = time.time()

    log("Abrindo Chrome...")

    options = Options()

    prefs = {
        "download.default_directory": PASTA_DOWNLOADS,
        "download.prompt_for_download": False,
        "download.directory_upgrade": True,
        "safebrowsing.enabled": True
    }

    options.add_experimental_option("prefs", prefs)
    options.add_argument("--window-size=1600,1200")

    driver = webdriver.Chrome(
        service=Service(ChromeDriverManager().install()),
        options=options
    )

    try:
        driver.get(URL_LOGIN)
        time.sleep(5)

        log("Realizando login...")

        driver.find_element(By.ID, "code").send_keys(DOMINIO)
        driver.find_element(By.ID, "username").send_keys(USUARIO)
        driver.find_element(By.ID, "password").send_keys(SENHA)
        driver.find_element(By.ID, "login-button").click()

        wait = WebDriverWait(driver, 30)

        log("Abrindo menu SAC...")

        menu_sac = wait.until(
            EC.presence_of_element_located((By.ID, "item_menu_sac"))
        )

        driver.execute_script("arguments[0].click();", menu_sac)

        log("Aplicando filtro...")

        wait.until(
            EC.element_to_be_clickable(
                (By.ID, "show_filter_modal_button")
            )
        ).click()

        campo_inicio = wait.until(
            EC.presence_of_element_located((By.ID, "DocumentDateE1"))
        )

        data_inicial = (
            datetime.today() - timedelta(days=90)
        ).strftime("%d/%m/%Y")

        campo_inicio.clear()
        campo_inicio.send_keys(data_inicial)

        wait.until(
            EC.element_to_be_clickable((By.ID, "filterButton"))
        ).click()

        time.sleep(8)

        log("Exportando CSV...")

        wait.until(
            EC.element_to_be_clickable((By.ID, "dropdownMenuLink"))
        ).click()

        wait.until(
            EC.element_to_be_clickable(
                (By.CSS_SELECTOR, "#sac_export_button a")
            )
        ).click()

        # Aguarda o download finalizar de verdade (substitui o time.sleep fixo)
        time.sleep(5)  # pequena pausa para o Chrome iniciar o download

        medir_tempo("Download CSV", inicio_total)

    except Exception as e:
        log("ERRO no Selenium — salvando screenshot...")
        driver.save_screenshot(SCREENSHOT_ERRO)
        raise e

    finally:
        driver.quit()
        log("Chrome fechado.")


# =====================================================
# MAIN


if __name__ == "__main__":

    log("========== INÍCIO DO PROCESSO ==========")

    try:
        # remove antigo
        limpar_arquivo_padrao_antigo()

        # baixa novo
        baixar_relatorio()

        # aguarda CSV finalizar o download (até 60 segundos)
        if not aguardar_csv(timeout=60):
            # loga arquivos presentes na pasta para debug
            try:
                arquivos_presentes = os.listdir(PASTA_DOWNLOADS)
                log(f"Arquivos na pasta após timeout: {arquivos_presentes}")
            except Exception:
                log("Não foi possível listar arquivos da pasta.")

            raise Exception("Timeout — CSV não apareceu após download.")

        # pega último baixado
        arquivo = pegar_ultimo_csv()

        if not arquivo:
            # loga arquivos presentes na pasta para debug
            try:
                arquivos_presentes = os.listdir(PASTA_DOWNLOADS)
                log(f"Arquivos encontrados na pasta: {arquivos_presentes}")
            except Exception:
                log("Não foi possível listar arquivos da pasta.")

            raise Exception("CSV não encontrado após download.")

        log(f"CSV localizado: {arquivo}")

        # renomeia
        arquivo_final = renomear_para_padrao(arquivo)

        # envia ftp
        enviar_ftp(arquivo_final)

        # chama php
        executar_php_online()

        log("✅ PROCESSO FINALIZADO COM SUCESSO")

    except Exception as e:
        erro = traceback.format_exc()

        log("❌ ERRO GERAL:\n" + erro)

        enviar_email_erro(
            "ERRO ROBÔ COMPROVEI",
            erro
        )

    finally:
        pausa_final()