<?php
require_once(dirname(__DIR__) . '/config/db.php');
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

$acao = $_GET['ajax'] ?? null;

/**
 * ============================================================
 * LISTAR ÁRVORE
 * ============================================================
 */
if ($acao === 'tree') {
    header('Content-Type: application/json; charset=utf-8');
    try {
        $busca = trim($_GET['busca'] ?? '');
        $somenteAtivos = !empty($_GET['ativos']);
        $filtroAtivo = $somenteAtivos ? ' AND flativo = 0' : '';
        if ($busca) {
            $stmt = $pdo->prepare("
                SELECT cdcontacontabil, cdconta, cdcontapai, dsconta, flnatureza, 
                       dsclassificacao, flativo, fltipo, flmatriz, pcideal
                  FROM back.planocontabil
                 WHERE (dsconta ILIKE :b OR cdconta ILIKE :b){$filtroAtivo}
              ORDER BY cdconta ASC
            ");
            $stmt->execute([':b' => "%$busca%"]);
            echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC));
            exit;
        }

        $whereAtivo = $somenteAtivos ? ' WHERE flativo = 0' : '';
        $sql = "
            SELECT cdcontacontabil, cdconta, cdcontapai, dsconta, flnatureza, 
                   dsclassificacao, flativo, fltipo, flmatriz, pcideal
              FROM back.planocontabil{$whereAtivo}
          ORDER BY cdconta ASC
        ";
        $dados = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);

        // Monta a árvore hierárquica
        $itens = [];
        foreach ($dados as $d) {
            $itens[$d['cdconta']] = $d + ['children' => []];
        }
        $raiz = [];
        foreach ($itens as $cd => &$item) {
            if ($item['cdcontapai']) {
                $itens[$item['cdcontapai']]['children'][] = &$item;
            } else {
                $raiz[] = &$item;
            }
        }
        echo json_encode($raiz);
    } catch (Exception $e) {
        echo json_encode(['ok' => false, 'msg' => $e->getMessage()]);
    }
    exit;
}

/**
 * ============================================================
 * BUSCAR NÍVEL MÁXIMO DO PARÂMETRO
 * ============================================================
 */
function getNivelMaximo($pdo) {
    $stmt = $pdo->prepare("SELECT valor FROM back.parametro WHERE dspadrao = 'NIVEL_PLANO_CONTABIL'");
    $stmt->execute();
    return (int)($stmt->fetchColumn() ?: 5);
}

/**
 * ============================================================
 * GERAR PRÓXIMO CÓDIGO
 * ============================================================
 */
if ($acao === 'nextcode') {
    header('Content-Type: application/json; charset=utf-8');
    try {
        $pai = $_GET['pai'] ?? null;
        $nivelMax = getNivelMaximo($pdo);

        if (!$pai) {
            // Novo PAI (nível 1)
            $sql = "SELECT MAX(CAST(cdconta AS NUMERIC)) FROM back.planocontabil WHERE POSITION('.' IN cdconta)=0";
            $prox = $pdo->query($sql)->fetchColumn();
            $codigo = (string)(($prox ?? 0) + 1);
        } else {
            $nivelAtual = substr_count($pai, '.') + 1;
            if ($nivelAtual >= $nivelMax) {
                echo json_encode(['ok' => false, 'msg' => "⚠️ Limite de $nivelMax níveis atingido."]);
                exit;
            }

            $sql = "SELECT cdconta FROM back.planocontabil WHERE cdcontapai = :pai ORDER BY cdconta DESC LIMIT 1";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([':pai' => $pai]);
            $ultimo = $stmt->fetchColumn();

            if ($ultimo) {
                $partes = explode('.', $ultimo);
                $ultimoNivel = end($partes);
                $novoNivel = str_pad((int)$ultimoNivel + 1, strlen($ultimoNivel), '0', STR_PAD_LEFT);
                $partes[count($partes) - 1] = $novoNivel;
                $codigo = implode('.', $partes);
            } else {
                $nivel = substr_count($pai, '.') + 1;
                $novo = match ($nivel) {
                    1 => '01',
                    2 => '001',
                    3 => '0001',
                    default => '00001'
                };
                $codigo = $pai . '.' . $novo;
            }
        }

        echo json_encode(['ok' => true, 'codigo' => $codigo, 'msg' => 'Código gerado com sucesso.']);
    } catch (Exception $e) {
        echo json_encode(['ok' => false, 'msg' => $e->getMessage()]);
    }
    exit;
}

/**
 * ============================================================
 * SALVAR CONTA
 * ============================================================
 */
if ($acao === 'salvar') {
    header('Content-Type: application/json; charset=utf-8');
    try {
        $input = json_decode(file_get_contents('php://input'), true);
        if (!$input) throw new Exception('Dados inválidos.');

        $codigo     = $input['cdconta'] ?? null;
        $descricao  = trim($input['dsconta'] ?? '');
        $pai        = $input['cdcontapai'] ?? null;
        $natureza   = $input['flnatureza'] ?? '';
        $classif    = $input['dsclassificacao'] ?? '';
        $flmatriz   = !empty($input['flmatriz']) ? 'true' : 'false';
       $pcideal    = is_numeric($input['pcideal']) ? $input['pcideal'] : 0;
        $ativo      = 0;

        if (!$codigo || !$descricao)
            throw new Exception('Preencha o código e a descrição.');

        $nivel = substr_count($codigo, '.') + 1;
        $nivelMax = getNivelMaximo($pdo);

        if (!$natureza)
            throw new Exception('O campo "Natureza" é obrigatório.');

        if ($nivel === $nivelMax && !$classif)
            throw new Exception('Conta Analítica, Classificação necessária.');

        // Define tipo
        $fltipo = ($nivel === $nivelMax) ? 'A' : 'S';

        // Atualiza o pai (se existir)
        if (!empty($pai)) {
            $pdo->prepare("UPDATE back.planocontabil SET fltipo = 'S' WHERE cdconta = :p")
                ->execute([':p' => $pai]);
        }

        // Regra de matriz
        if ($flmatriz === 'true') {
            $stmt = $pdo->prepare("
                SELECT cdconta, dsconta 
                  FROM back.planocontabil 
                 WHERE flnatureza = :n 
                   AND flmatriz = TRUE 
                   AND cdconta <> :c
                 LIMIT 1
            ");
            $stmt->execute([':n' => $natureza, ':c' => $codigo]);
            $existente = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($existente) {
                throw new Exception("Já existe uma conta matriz para a natureza '{$natureza}': {$existente['cdconta']} - {$existente['dsconta']}.");
            }
        }

        // 🔹 Insere ou atualiza com o novo campo pcideal
        $sql = "
            INSERT INTO back.planocontabil 
                (cdconta, cdcontapai, dsconta, flnatureza, dsclassificacao, 
                 flativo, fltipo, flmatriz, pcideal)
            VALUES (:c, :p, :d, :n, :cl, :a, :t, :m, :pi)
            ON CONFLICT (cdconta) DO UPDATE SET 
                dsconta = EXCLUDED.dsconta,
                flnatureza = EXCLUDED.flnatureza,
                dsclassificacao = EXCLUDED.dsclassificacao,
                flativo = EXCLUDED.flativo,
                fltipo = EXCLUDED.fltipo,
                flmatriz = EXCLUDED.flmatriz,
                pcideal = EXCLUDED.pcideal
        ";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            ':c' => $codigo,
            ':p' => $pai,
            ':d' => $descricao,
            ':n' => $natureza,
            ':cl' => $classif,
            ':a' => $ativo,
            ':t' => $fltipo,
            ':m' => $flmatriz,
            ':pi' => $pcideal
        ]);

        echo json_encode(['ok' => true, 'msg' => '✅ Conta salva com sucesso!']);
    } catch (Exception $e) {
        echo json_encode(['ok' => false, 'msg' => '❌ ' . $e->getMessage()]);
    }
    exit;
}

/**
 * ============================================================
 * INATIVAR / REATIVAR
 * ============================================================
 */
if ($acao === 'toggle') {
    header('Content-Type: application/json; charset=utf-8');
    try {
        $codigo = $_GET['codigo'] ?? null;
        if (!$codigo) throw new Exception('Código não informado.');
        $pdo->exec("
            UPDATE back.planocontabil 
               SET flativo = CASE WHEN flativo=0 THEN 1 ELSE 0 END 
             WHERE cdconta = '$codigo'
        ");
        echo json_encode(['ok' => true, 'msg' => '🔁 Status atualizado com sucesso!']);
    } catch (Exception $e) {
        echo json_encode(['ok' => false, 'msg' => $e->getMessage()]);
    }
    exit;
}

/**
 * ============================================================
 * EXCLUSÃO
 * ============================================================
 */
if ($acao === 'delete') {
    header('Content-Type: application/json; charset=utf-8');
    try {
        $codigo = $_GET['codigo'] ?? null;
        if (!$codigo) throw new Exception('Código não informado.');
        $pdo->prepare("DELETE FROM back.planocontabil WHERE cdconta = :c")->execute([':c' => $codigo]);
        echo json_encode(['ok' => true, 'msg' => '🗑️ Conta excluída com sucesso!']);
    } catch (Exception $e) {
        echo json_encode(['ok' => false, 'msg' => $e->getMessage()]);
    }
    exit;
}
?>
