"""
Arcádia Contábil - Motor de Contabilidade
Serviço FastAPI para processamento contábil
"""

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime, date
from decimal import Decimal
import json
import os
import re

app = FastAPI(
    title="Arcádia Contábil",
    description="Motor de Contabilidade - DRE, Balanço, Balancete, SPED ECD",
    version="1.0.0"
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=[os.getenv("APP_URL", "http://localhost:5000")],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# ========== Models ==========

class ContaContabil(BaseModel):
    codigo: str
    descricao: str
    tipo: str  # ativo, passivo, patrimonio, receita, despesa
    natureza: str  # devedora, credora
    nivel: int = 1
    contaPai: Optional[int] = None
    aceitaLancamento: bool = True

class Partida(BaseModel):
    contaId: int
    tipo: str  # debito, credito
    valor: float
    historico: Optional[str] = None
    centroCustoId: Optional[int] = None

class Lancamento(BaseModel):
    dataLancamento: str
    dataCompetencia: Optional[str] = None
    tipoDocumento: Optional[str] = None
    numeroDocumento: Optional[str] = None
    historico: str
    partidas: List[Partida]

class PeriodoRequest(BaseModel):
    ano: int
    mes: int
    tenantId: Optional[int] = None

class RelatorioRequest(BaseModel):
    tenantId: Optional[int] = None
    dataInicio: str
    dataFim: str
    centroCustoId: Optional[int] = None

# ========== Plano de Contas Padrão (Simplificado) ==========

PLANO_CONTAS_PADRAO = [
    # ATIVO
    {"codigo": "1", "descricao": "ATIVO", "tipo": "ativo", "natureza": "devedora", "nivel": 1},
    {"codigo": "1.1", "descricao": "ATIVO CIRCULANTE", "tipo": "ativo", "natureza": "devedora", "nivel": 2},
    {"codigo": "1.1.01", "descricao": "Caixa e Equivalentes", "tipo": "ativo", "natureza": "devedora", "nivel": 3},
    {"codigo": "1.1.01.001", "descricao": "Caixa Geral", "tipo": "ativo", "natureza": "devedora", "nivel": 4},
    {"codigo": "1.1.01.002", "descricao": "Bancos Conta Movimento", "tipo": "ativo", "natureza": "devedora", "nivel": 4},
    {"codigo": "1.1.02", "descricao": "Clientes", "tipo": "ativo", "natureza": "devedora", "nivel": 3},
    {"codigo": "1.1.02.001", "descricao": "Duplicatas a Receber", "tipo": "ativo", "natureza": "devedora", "nivel": 4},
    {"codigo": "1.1.03", "descricao": "Estoques", "tipo": "ativo", "natureza": "devedora", "nivel": 3},
    {"codigo": "1.1.03.001", "descricao": "Mercadorias para Revenda", "tipo": "ativo", "natureza": "devedora", "nivel": 4},
    {"codigo": "1.2", "descricao": "ATIVO NÃO CIRCULANTE", "tipo": "ativo", "natureza": "devedora", "nivel": 2},
    {"codigo": "1.2.01", "descricao": "Imobilizado", "tipo": "ativo", "natureza": "devedora", "nivel": 3},
    {"codigo": "1.2.01.001", "descricao": "Máquinas e Equipamentos", "tipo": "ativo", "natureza": "devedora", "nivel": 4},
    {"codigo": "1.2.01.002", "descricao": "Móveis e Utensílios", "tipo": "ativo", "natureza": "devedora", "nivel": 4},
    {"codigo": "1.2.01.003", "descricao": "Veículos", "tipo": "ativo", "natureza": "devedora", "nivel": 4},
    
    # PASSIVO
    {"codigo": "2", "descricao": "PASSIVO", "tipo": "passivo", "natureza": "credora", "nivel": 1},
    {"codigo": "2.1", "descricao": "PASSIVO CIRCULANTE", "tipo": "passivo", "natureza": "credora", "nivel": 2},
    {"codigo": "2.1.01", "descricao": "Fornecedores", "tipo": "passivo", "natureza": "credora", "nivel": 3},
    {"codigo": "2.1.01.001", "descricao": "Fornecedores Nacionais", "tipo": "passivo", "natureza": "credora", "nivel": 4},
    {"codigo": "2.1.02", "descricao": "Obrigações Trabalhistas", "tipo": "passivo", "natureza": "credora", "nivel": 3},
    {"codigo": "2.1.02.001", "descricao": "Salários a Pagar", "tipo": "passivo", "natureza": "credora", "nivel": 4},
    {"codigo": "2.1.02.002", "descricao": "INSS a Recolher", "tipo": "passivo", "natureza": "credora", "nivel": 4},
    {"codigo": "2.1.02.003", "descricao": "FGTS a Recolher", "tipo": "passivo", "natureza": "credora", "nivel": 4},
    {"codigo": "2.1.02.004", "descricao": "IRRF a Recolher", "tipo": "passivo", "natureza": "credora", "nivel": 4},
    {"codigo": "2.1.03", "descricao": "Obrigações Fiscais", "tipo": "passivo", "natureza": "credora", "nivel": 3},
    {"codigo": "2.1.03.001", "descricao": "ICMS a Recolher", "tipo": "passivo", "natureza": "credora", "nivel": 4},
    {"codigo": "2.1.03.002", "descricao": "PIS a Recolher", "tipo": "passivo", "natureza": "credora", "nivel": 4},
    {"codigo": "2.1.03.003", "descricao": "COFINS a Recolher", "tipo": "passivo", "natureza": "credora", "nivel": 4},
    
    # PATRIMÔNIO LÍQUIDO
    {"codigo": "3", "descricao": "PATRIMÔNIO LÍQUIDO", "tipo": "patrimonio", "natureza": "credora", "nivel": 1},
    {"codigo": "3.1", "descricao": "Capital Social", "tipo": "patrimonio", "natureza": "credora", "nivel": 2},
    {"codigo": "3.1.01", "descricao": "Capital Social Integralizado", "tipo": "patrimonio", "natureza": "credora", "nivel": 3},
    {"codigo": "3.2", "descricao": "Lucros ou Prejuízos Acumulados", "tipo": "patrimonio", "natureza": "credora", "nivel": 2},
    {"codigo": "3.2.01", "descricao": "Lucros Acumulados", "tipo": "patrimonio", "natureza": "credora", "nivel": 3},
    {"codigo": "3.2.02", "descricao": "Prejuízos Acumulados", "tipo": "patrimonio", "natureza": "devedora", "nivel": 3},
    
    # RECEITAS
    {"codigo": "4", "descricao": "RECEITAS", "tipo": "receita", "natureza": "credora", "nivel": 1},
    {"codigo": "4.1", "descricao": "Receita Operacional Bruta", "tipo": "receita", "natureza": "credora", "nivel": 2},
    {"codigo": "4.1.01", "descricao": "Vendas de Mercadorias", "tipo": "receita", "natureza": "credora", "nivel": 3},
    {"codigo": "4.1.02", "descricao": "Prestação de Serviços", "tipo": "receita", "natureza": "credora", "nivel": 3},
    {"codigo": "4.2", "descricao": "Deduções da Receita", "tipo": "receita", "natureza": "devedora", "nivel": 2},
    {"codigo": "4.2.01", "descricao": "Devoluções de Vendas", "tipo": "receita", "natureza": "devedora", "nivel": 3},
    {"codigo": "4.2.02", "descricao": "Impostos sobre Vendas", "tipo": "receita", "natureza": "devedora", "nivel": 3},
    
    # DESPESAS
    {"codigo": "5", "descricao": "DESPESAS", "tipo": "despesa", "natureza": "devedora", "nivel": 1},
    {"codigo": "5.1", "descricao": "Custos das Vendas", "tipo": "despesa", "natureza": "devedora", "nivel": 2},
    {"codigo": "5.1.01", "descricao": "CMV - Custo das Mercadorias Vendidas", "tipo": "despesa", "natureza": "devedora", "nivel": 3},
    {"codigo": "5.2", "descricao": "Despesas Operacionais", "tipo": "despesa", "natureza": "devedora", "nivel": 2},
    {"codigo": "5.2.01", "descricao": "Despesas com Pessoal", "tipo": "despesa", "natureza": "devedora", "nivel": 3},
    {"codigo": "5.2.01.001", "descricao": "Salários e Ordenados", "tipo": "despesa", "natureza": "devedora", "nivel": 4},
    {"codigo": "5.2.01.002", "descricao": "INSS Patronal", "tipo": "despesa", "natureza": "devedora", "nivel": 4},
    {"codigo": "5.2.01.003", "descricao": "FGTS", "tipo": "despesa", "natureza": "devedora", "nivel": 4},
    {"codigo": "5.2.02", "descricao": "Despesas Administrativas", "tipo": "despesa", "natureza": "devedora", "nivel": 3},
    {"codigo": "5.2.02.001", "descricao": "Aluguel", "tipo": "despesa", "natureza": "devedora", "nivel": 4},
    {"codigo": "5.2.02.002", "descricao": "Energia Elétrica", "tipo": "despesa", "natureza": "devedora", "nivel": 4},
    {"codigo": "5.2.02.003", "descricao": "Telefone e Internet", "tipo": "despesa", "natureza": "devedora", "nivel": 4},
]

# ========== Endpoints ==========

@app.get("/")
async def root():
    return {
        "service": "Arcádia Contábil",
        "version": "1.0.0",
        "status": "running",
        "modules": ["plano_contas", "lancamentos", "dre", "balanco", "balancete", "sped_ecd"]
    }

@app.get("/health")
async def health():
    return {"status": "healthy", "timestamp": datetime.now().isoformat()}

@app.get("/plano-contas/padrao")
async def get_plano_contas_padrao():
    """Retorna o plano de contas padrão para importação"""
    return {"planoContas": PLANO_CONTAS_PADRAO, "total": len(PLANO_CONTAS_PADRAO)}

@app.post("/validar-lancamento")
async def validar_lancamento(lancamento: Lancamento):
    """Valida se um lançamento está balanceado (débitos = créditos)"""
    total_debitos = sum(p.valor for p in lancamento.partidas if p.tipo == "debito")
    total_creditos = sum(p.valor for p in lancamento.partidas if p.tipo == "credito")
    
    balanceado = abs(total_debitos - total_creditos) < 0.01
    
    return {
        "valido": balanceado,
        "totalDebitos": round(total_debitos, 2),
        "totalCreditos": round(total_creditos, 2),
        "diferenca": round(total_debitos - total_creditos, 2),
        "mensagem": "Lançamento balanceado" if balanceado else "Lançamento desbalanceado"
    }

@app.post("/calcular-dre")
async def calcular_dre(request: RelatorioRequest):
    """Calcula a DRE (Demonstração do Resultado do Exercício)"""
    # Estrutura padrão da DRE
    dre = {
        "periodo": {"inicio": request.dataInicio, "fim": request.dataFim},
        "receitaBruta": 0,
        "deducoes": {
            "devolucoes": 0,
            "impostos": 0,
            "total": 0
        },
        "receitaLiquida": 0,
        "custoVendas": 0,
        "lucroBruto": 0,
        "despesasOperacionais": {
            "vendas": 0,
            "administrativas": 0,
            "pessoal": 0,
            "total": 0
        },
        "resultadoOperacional": 0,
        "receitasFinanceiras": 0,
        "despesasFinanceiras": 0,
        "resultadoAntesIR": 0,
        "provisaoIR": 0,
        "lucroLiquido": 0
    }
    
    return {
        "dre": dre,
        "observacao": "Valores serão calculados com base nos lançamentos do período"
    }

@app.post("/calcular-balanco")
async def calcular_balanco(request: RelatorioRequest):
    """Calcula o Balanço Patrimonial"""
    balanco = {
        "dataBase": request.dataFim,
        "ativo": {
            "circulante": {
                "caixaEquivalentes": 0,
                "contasReceber": 0,
                "estoques": 0,
                "total": 0
            },
            "naoCirculante": {
                "imobilizado": 0,
                "intangivel": 0,
                "total": 0
            },
            "total": 0
        },
        "passivo": {
            "circulante": {
                "fornecedores": 0,
                "obrigacoesTrabalhistas": 0,
                "obrigacoesFiscais": 0,
                "total": 0
            },
            "naoCirculante": {
                "emprestimos": 0,
                "total": 0
            },
            "total": 0
        },
        "patrimonioLiquido": {
            "capitalSocial": 0,
            "reservas": 0,
            "lucrosAcumulados": 0,
            "total": 0
        },
        "totalPassivoPL": 0
    }
    
    return {
        "balanco": balanco,
        "equilibrado": balanco["ativo"]["total"] == balanco["totalPassivoPL"]
    }

@app.post("/calcular-balancete")
async def calcular_balancete(request: PeriodoRequest):
    """Calcula o Balancete de Verificação"""
    balancete = {
        "periodo": {"ano": request.ano, "mes": request.mes},
        "contas": [],
        "totais": {
            "saldoAnteriorDebito": 0,
            "saldoAnteriorCredito": 0,
            "movimentoDebito": 0,
            "movimentoCredito": 0,
            "saldoAtualDebito": 0,
            "saldoAtualCredito": 0
        }
    }
    
    return {"balancete": balancete}

@app.post("/gerar-razao")
async def gerar_razao(request: RelatorioRequest):
    """Gera o Livro Razão para uma conta específica"""
    razao = {
        "periodo": {"inicio": request.dataInicio, "fim": request.dataFim},
        "conta": None,
        "saldoAnterior": 0,
        "lancamentos": [],
        "saldoFinal": 0
    }
    
    return {"razao": razao}

@app.post("/gerar-diario")
async def gerar_diario(request: RelatorioRequest):
    """Gera o Livro Diário"""
    diario = {
        "periodo": {"inicio": request.dataInicio, "fim": request.dataFim},
        "lancamentos": [],
        "totalDebitos": 0,
        "totalCreditos": 0
    }
    
    return {"diario": diario}

@app.get("/tabela-contas-referenciais")
async def get_tabela_contas_referenciais():
    """Retorna a tabela de contas referenciais do SPED ECD"""
    # Tabela simplificada - L100 (Balanço) e L300 (DRE)
    contas_referenciais = {
        "L100": [  # Balanço Patrimonial
            {"codigo": "1", "descricao": "ATIVO TOTAL"},
            {"codigo": "1.01", "descricao": "Ativo Circulante"},
            {"codigo": "1.02", "descricao": "Ativo Não Circulante"},
            {"codigo": "2", "descricao": "PASSIVO TOTAL"},
            {"codigo": "2.01", "descricao": "Passivo Circulante"},
            {"codigo": "2.02", "descricao": "Passivo Não Circulante"},
            {"codigo": "2.03", "descricao": "Patrimônio Líquido"},
        ],
        "L300": [  # DRE
            {"codigo": "3.01", "descricao": "Receita Líquida"},
            {"codigo": "3.02", "descricao": "Custo dos Bens e Serviços Vendidos"},
            {"codigo": "3.03", "descricao": "Resultado Bruto"},
            {"codigo": "3.04", "descricao": "Despesas Operacionais"},
            {"codigo": "3.05", "descricao": "Resultado Antes do IR"},
            {"codigo": "3.06", "descricao": "Lucro Líquido do Exercício"},
        ]
    }
    
    return contas_referenciais

@app.post("/exportar-sped-ecd")
async def exportar_sped_ecd(request: PeriodoRequest):
    """Gera arquivo SPED ECD (Escrituração Contábil Digital)"""
    # Estrutura do arquivo SPED ECD
    sped_ecd = {
        "registro0000": {
            "tipo_escrit": "G",  # G - Livro Diário Geral
            "ind_sit_esp": "0",  # 0 - Normal
            "dt_ini": f"{request.ano}-01-01",
            "dt_fin": f"{request.ano}-12-31",
        },
        "registroI010": {
            "ind_esc": "G",  # G - Diário Geral
        },
        "registroI050": [],  # Plano de Contas
        "registroI150": [],  # Saldos Periódicos
        "registroI200": [],  # Lançamentos
        "registroJ100": [],  # Balanço
        "registroJ150": [],  # DRE
    }
    
    return {
        "status": "estrutura_gerada",
        "arquivo": f"SPED_ECD_{request.ano}.txt",
        "estrutura": sped_ecd,
        "observacao": "Arquivo será gerado com base nos lançamentos contábeis"
    }

# ========== Integrações ==========

@app.post("/integrar-nfe")
async def integrar_nfe(nota: dict):
    """Gera lançamentos contábeis automáticos para NF-e"""
    tipo_operacao = nota.get("tipoOperacao", "saida")
    valor_total = float(nota.get("valorTotal", 0))
    
    if tipo_operacao == "saida":
        lancamento = {
            "historico": f"NF-e {nota.get('numero')} - Venda de mercadorias",
            "partidas": [
                {"conta": "1.1.01.001", "tipo": "debito", "valor": valor_total, "descricao": "Caixa"},
                {"conta": "4.1.01", "tipo": "credito", "valor": valor_total, "descricao": "Vendas"}
            ]
        }
    else:
        lancamento = {
            "historico": f"NF-e {nota.get('numero')} - Compra de mercadorias",
            "partidas": [
                {"conta": "1.1.03.001", "tipo": "debito", "valor": valor_total, "descricao": "Estoques"},
                {"conta": "2.1.01.001", "tipo": "credito", "valor": valor_total, "descricao": "Fornecedores"}
            ]
        }
    
    return {"lancamentoSugerido": lancamento}

@app.post("/integrar-folha")
async def integrar_folha(folha: dict):
    """Gera lançamentos contábeis automáticos para folha de pagamento"""
    total_bruto = float(folha.get("totalBruto", 0))
    total_inss = float(folha.get("totalInss", 0))
    total_irrf = float(folha.get("totalIrrf", 0))
    total_fgts = float(folha.get("totalFgts", 0))
    total_liquido = float(folha.get("totalLiquido", 0))
    
    lancamento = {
        "historico": f"Folha de Pagamento - Competência {folha.get('competencia')}",
        "partidas": [
            {"conta": "5.2.01.001", "tipo": "debito", "valor": total_bruto, "descricao": "Salários e Ordenados"},
            {"conta": "5.2.01.002", "tipo": "debito", "valor": total_inss * 0.2, "descricao": "INSS Patronal"},
            {"conta": "5.2.01.003", "tipo": "debito", "valor": total_fgts, "descricao": "FGTS"},
            {"conta": "2.1.02.001", "tipo": "credito", "valor": total_liquido, "descricao": "Salários a Pagar"},
            {"conta": "2.1.02.002", "tipo": "credito", "valor": total_inss, "descricao": "INSS a Recolher"},
            {"conta": "2.1.02.003", "tipo": "credito", "valor": total_fgts, "descricao": "FGTS a Recolher"},
            {"conta": "2.1.02.004", "tipo": "credito", "valor": total_irrf, "descricao": "IRRF a Recolher"},
        ]
    }
    
    return {"lancamentoSugerido": lancamento}

# ========== Importação de Balanço Patrimonial ==========

class BalancoImportRequest(BaseModel):
    texto: str
    dataBalanco: str
    criarContas: bool = True
    criarAbertura: bool = True

def parse_valor_contabil(valor_str: str) -> tuple:
    """Parseia valor contábil no formato brasileiro (ex: 1.234.567,89D ou 1.234.567,89C)"""
    if not valor_str or valor_str.strip() == "0,00" or valor_str.strip() == "0":
        return 0.0, None
    
    valor_str = valor_str.strip()
    natureza = None
    
    if valor_str.endswith("D"):
        natureza = "devedora"
        valor_str = valor_str[:-1]
    elif valor_str.endswith("C"):
        natureza = "credora"
        valor_str = valor_str[:-1]
    
    valor_str = valor_str.replace(".", "").replace(",", ".").strip()
    
    try:
        valor = float(valor_str)
        return valor, natureza
    except:
        return 0.0, None

def extrair_contas_balanco(texto: str) -> list:
    """Extrai estrutura hierárquica de contas do balanço patrimonial"""
    linhas = texto.split("\n")
    contas = []
    
    nivel_map = {
        "ATIVO": 1, "PASSIVO": 1, "PATRIMÔNIO LÍQUIDO": 1,
        "ATIVO CIRCULANTE": 2, "ATIVO NÃO-CIRCULANTE": 2, "ATIVO NÃO CIRCULANTE": 2,
        "PASSIVO CIRCULANTE": 2, "PASSIVO NÃO-CIRCULANTE": 2, "PASSIVO NÃO CIRCULANTE": 2,
    }
    
    tipo_map = {
        "ATIVO": "ativo", "ATIVO CIRCULANTE": "ativo", "ATIVO NÃO-CIRCULANTE": "ativo",
        "PASSIVO": "passivo", "PASSIVO CIRCULANTE": "passivo", 
        "PATRIMÔNIO LÍQUIDO": "patrimonio", "CAPITAL SOCIAL": "patrimonio",
        "LUCROS OU PREJUÍZOS ACUMULADOS": "patrimonio",
    }
    
    codigo_contador = {"1": 0, "2": 0, "3": 0}
    tipo_atual = "ativo"
    nivel_atual = 1
    codigo_pai = ""
    
    for linha in linhas:
        linha = linha.strip()
        if not linha or "Folha:" in linha or "C.N.P.J" in linha or "Balanço encerrado" in linha:
            continue
        if "BALANÇO PATRIMONIAL" in linha or "Descrição" in linha or "______" in linha:
            continue
        if "Assinado digitalmente" in linha or "SERGIO SZWEC" in linha or "ELOIR" in linha:
            continue
        
        partes = linha.split()
        if len(partes) < 2:
            continue
        
        descricao_partes = []
        valor_2024 = None
        valor_2023 = None
        
        for i, parte in enumerate(partes):
            if any(c.isdigit() for c in parte) and ("," in parte or parte.endswith("D") or parte.endswith("C")):
                valor_2024, natureza = parse_valor_contabil(parte)
                if i + 1 < len(partes):
                    valor_2023, _ = parse_valor_contabil(partes[i + 1])
                break
            else:
                descricao_partes.append(parte)
        
        descricao = " ".join(descricao_partes).strip()
        if not descricao or len(descricao) < 2:
            continue
        
        descricao_upper = descricao.upper()
        
        if descricao_upper in ["ATIVO", "PASSIVO"]:
            tipo_atual = "ativo" if descricao_upper == "ATIVO" else "passivo"
            nivel_atual = 1
            base_codigo = "1" if tipo_atual == "ativo" else "2"
            codigo = base_codigo
        elif "PATRIMÔNIO LÍQUIDO" in descricao_upper:
            tipo_atual = "patrimonio"
            nivel_atual = 1
            codigo = "3"
        elif descricao_upper in nivel_map:
            nivel_atual = nivel_map[descricao_upper]
            if tipo_atual == "ativo":
                codigo = f"1.{codigo_contador['1'] + 1}"
                codigo_contador['1'] += 1
            elif tipo_atual == "passivo":
                codigo = f"2.{codigo_contador['2'] + 1}"
                codigo_contador['2'] += 1
            else:
                codigo = f"3.{codigo_contador['3'] + 1}"
                codigo_contador['3'] += 1
        else:
            espacos = len(linha) - len(linha.lstrip())
            nivel = min(max(espacos // 2, 1), 5)
            if nivel <= 2:
                nivel = 3
            
            base = "1" if tipo_atual == "ativo" else ("2" if tipo_atual == "passivo" else "3")
            codigo_contador[base] = codigo_contador.get(base, 0) + 1
            codigo = f"{base}.{nivel}.{codigo_contador[base]:02d}"
        
        natureza_conta = "devedora" if tipo_atual == "ativo" else "credora"
        if "(-)" in descricao or "DEPRECIAÇÃO" in descricao_upper or "AMORTIZAÇÃO" in descricao_upper:
            natureza_conta = "credora" if tipo_atual == "ativo" else "devedora"
        
        if valor_2024 and valor_2024 > 0:
            contas.append({
                "codigo": codigo,
                "descricao": descricao,
                "tipo": tipo_atual,
                "natureza": natureza_conta,
                "nivel": nivel_atual if descricao_upper in nivel_map else 4,
                "saldo2024": valor_2024,
                "saldo2023": valor_2023 or 0,
                "aceitaLancamento": True
            })
    
    return contas

@app.post("/importar-balanco")
async def importar_balanco(request: BalancoImportRequest):
    """Importa balanço patrimonial e gera plano de contas + lançamentos de abertura"""
    try:
        contas = extrair_contas_balanco(request.texto)
        
        if not contas:
            texto_upper = request.texto.upper()
            has_structure = any(x in texto_upper for x in ["ATIVO", "PASSIVO", "PATRIMÔNIO"])
            has_values = bool(re.search(r'\d{1,3}(?:\.\d{3})*,\d{2}', request.texto))
            
            error_msg = "Não foi possível extrair contas do balanço. "
            if not has_structure:
                error_msg += "O texto não contém estrutura de balanço (ATIVO, PASSIVO, PATRIMÔNIO LÍQUIDO). "
            if not has_values:
                error_msg += "Valores não encontrados no formato brasileiro (ex: 1.234,56). "
            error_msg += "Verifique se o PDF contém os dados do balanço patrimonial."
            
            raise HTTPException(status_code=400, detail=error_msg)
        
        plano_contas = []
        lancamentos_abertura = []
        
        for conta in contas:
            plano_contas.append({
                "codigo": conta["codigo"],
                "descricao": conta["descricao"],
                "tipo": conta["tipo"],
                "natureza": conta["natureza"],
                "nivel": conta["nivel"],
                "aceitaLancamento": conta["aceitaLancamento"],
                "status": "ativo"
            })
            
            if request.criarAbertura and conta.get("saldo2024", 0) > 0:
                tipo_lancamento = "debito" if conta["natureza"] == "devedora" else "credito"
                lancamentos_abertura.append({
                    "conta": conta["codigo"],
                    "descricao": conta["descricao"],
                    "tipo": tipo_lancamento,
                    "valor": conta["saldo2024"],
                    "historico": f"Saldo de abertura - {conta['descricao']}"
                })
        
        total_debito = sum(l["valor"] for l in lancamentos_abertura if l["tipo"] == "debito")
        total_credito = sum(l["valor"] for l in lancamentos_abertura if l["tipo"] == "credito")
        
        return {
            "success": True,
            "planoContas": plano_contas,
            "lancamentosAbertura": lancamentos_abertura,
            "resumo": {
                "totalContas": len(plano_contas),
                "totalLancamentos": len(lancamentos_abertura),
                "totalDebito": total_debito,
                "totalCredito": total_credito,
                "diferenca": abs(total_debito - total_credito)
            }
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
    import uvicorn
    port = int(os.environ.get("CONTABIL_PORT", 8003))
    uvicorn.run(app, host="0.0.0.0", port=port)
