import sys
import json
import os
import subprocess
import tempfile
import shutil
from datetime import datetime
from docx import Document
import re
import traceback
import time
import unicodedata

# -------------------------------------------------
# BASE
# -------------------------------------------------
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

# -------------------------------------------------
# LOG
# -------------------------------------------------
LOG_FILE = os.path.join(BASE_DIR, "log.txt")

def log(msg):
    with open(LOG_FILE, "a", encoding="utf-8") as f:
        f.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {msg}\n")

# -------------------------------------------------
# LIBREOFFICE
# -------------------------------------------------
SOFFICE = shutil.which("soffice")
if not SOFFICE:
    raise RuntimeError("LibreOffice não encontrado")

PROFILE_DIR = tempfile.mkdtemp(prefix="lo-profile-")

# -------------------------------------------------
# SAÍDA
# -------------------------------------------------
DATA_HOJE = datetime.now().strftime("%Y%m%d")
PASTA_DIA = os.path.join(BASE_DIR, "fichas", DATA_HOJE)
os.makedirs(PASTA_DIA, exist_ok=True)

# -------------------------------------------------
def normalizar_nome(nome):
    if not nome:
        return "SEM_NOME"

    nome = unicodedata.normalize('NFKD', nome)
    nome = nome.encode('ascii', 'ignore').decode('ascii')
    nome = re.sub(r'[^A-Za-z0-9]+', '_', nome)
    return nome.upper().strip('_')

# -------------------------------------------------
def ler_docx_como_texto(caminho):
    doc = Document(caminho)
    texto = []
    for p in doc.paragraphs:
        texto.append(p.text)
    return "\n".join(texto)

def extrair_variaveis(texto):
    resultado = []
    for match in re.finditer(r'\$\{[^}]+\}', texto):
        resultado.append((match.group(), match.start()))
    return resultado

def sobrescrever_em_posicao(texto, posicao, valor):
    chars = list(texto)
    for i, c in enumerate(valor):
        idx = posicao + i
        if idx >= len(chars):
            break
        chars[idx] = c
    return "".join(chars)

def substituir_variaveis_por_posicao(texto, valores):
    variaveis = extrair_variaveis(texto)
    novo_texto = texto

    for variavel, posicao in variaveis:
        if variavel not in valores:
            continue

        novo_texto = sobrescrever_em_posicao(
            novo_texto, posicao, " " * len(variavel)
        )
        novo_texto = sobrescrever_em_posicao(
            novo_texto, posicao, valores[variavel]
        )

    return novo_texto

def substituir_variaveis_docx_por_posicao(entrada, saida, valores):
    doc = Document(entrada)

    for p in doc.paragraphs:
        if not p.runs:
            continue

        texto_completo = "".join(run.text for run in p.runs)

        if not re.search(r'\$\{[^}]+\}', texto_completo):
            continue

        novo_texto = substituir_variaveis_por_posicao(
            texto_completo, valores
        )

        for run in p.runs:
            run.text = ""

        p.runs[0].text = novo_texto

    doc.save(saida)

# -------------------------------------------------
def converter_para_pdf(docx_path):
    log("Iniciando conversão para PDF")

    result = subprocess.run(
        [
            SOFFICE,
            "--headless",
            f"-env:UserInstallation=file://{PROFILE_DIR}",
            "--convert-to", "pdf",
            docx_path,
            "--outdir", os.path.dirname(docx_path)
        ],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True
    )

    if result.returncode != 0:
        raise RuntimeError(result.stderr)

    os.remove(docx_path)
    log(f"DOCX removido: {docx_path}")

# -------------------------------------------------
# MAIN
# -------------------------------------------------
try:
    raw = sys.stdin.read()
    if not raw.strip():
        raise RuntimeError("Dados não recebidos do PHP")

    dados = json.loads(raw)
    log(f"Dados recebidos: {dados}")

    valores = {f"${{{k}}}": str(v) for k, v in dados.items()}

    nome_pessoa = normalizar_nome(dados.get("nome"))
    base_nome = f"ficha_{nome_pessoa}"

    caminho = os.path.join(BASE_DIR, "template.docx")
    saida = os.path.join(PASTA_DIA, base_nome + ".docx")
    pdf_gerado = os.path.join(PASTA_DIA, base_nome + ".pdf")

    substituir_variaveis_docx_por_posicao(caminho, saida, valores)
    converter_para_pdf(saida)

    print(pdf_gerado)

except Exception as e:
    print("ERRO:", e)
    print(traceback.format_exc())
    sys.exit(1)