<?php
// api/clientes.php
require_once 'config.php';

$auth = validarAPIKey();
$tenantId = $auth['tenant_id'];

// Log da requisição (opcional)
function logRequest($endpoint, $metodo, $requestData, $responseCode) {
    global $conn, $auth;
    
    $headers = getallheaders();
    $stmt = $conn->prepare("
        INSERT INTO api_logs (api_key_id, tenant_id, endpoint, metodo, ip, user_agent, request_data, response_code)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    ");
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '';
    $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
    $requestJson = $requestData ? json_encode($requestData) : null;
    
    $stmt->bind_param("iisssssi", 
        $auth['api_key_id'], 
        $auth['tenant_id'],
        $endpoint,
        $metodo,
        $ip,
        $userAgent,
        $requestJson,
        $responseCode
    );
    $stmt->execute();
    $stmt->close();
}

// ROTEAMENTO BASEADO NO MÉTODO E PATH
$method = $_SERVER['REQUEST_METHOD'];
$path = isset($_GET['path']) ? $_GET['path'] : '';
$pathParts = explode('/', trim($path, '/'));
$resourceId = isset($pathParts[1]) ? (int)$pathParts[1] : null;

try {
    switch ($method) {
        case 'GET':
            if ($resourceId) {
                // GET /api/clientes/{id} - Buscar um cliente
                buscarCliente($conn, $tenantId, $resourceId);
            } else {
                // GET /api/clientes - Listar clientes
                listarClientes($conn, $tenantId);
            }
            break;
            
        case 'POST':
            // POST /api/clientes - Criar novo cliente
            criarCliente($conn, $tenantId, $auth);
            break;
            
        case 'PUT':
            // PUT /api/clientes/{id} - Atualizar cliente
            if (!$resourceId) {
                jsonResponse(['erro' => 'ID do cliente não fornecido'], 400);
            }
            atualizarCliente($conn, $tenantId, $resourceId);
            break;
            
        case 'DELETE':
            // DELETE /api/clientes/{id} - Excluir cliente
            if (!$resourceId) {
                jsonResponse(['erro' => 'ID do cliente não fornecido'], 400);
            }
            excluirCliente($conn, $tenantId, $resourceId);
            break;
            
        default:
            jsonResponse(['erro' => 'Método não suportado'], 405);
    }
} catch (Exception $e) {
    logRequest($path, $method, null, 500);
    jsonResponse(['erro' => 'Erro interno: ' . $e->getMessage()], 500);
}

// FUNÇÕES DA API

function listarClientes($conn, $tenantId) {
    $page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
    $limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 20;
    $offset = ($page - 1) * $limit;
    
    $filtros = [];
    $params = [];
    $types = "";
    
    // Filtros opcionais
    if (isset($_GET['nome'])) {
        $filtros[] = "Nome_Cliente LIKE ?";
        $params[] = "%{$_GET['nome']}%";
        $types .= "s";
    }
    
    if (isset($_GET['email'])) {
        $filtros[] = "Email = ?";
        $params[] = $_GET['email'];
        $types .= "s";
    }
    
    if (isset($_GET['cpf_cnpj'])) {
        $filtros[] = "CPF_CNPJ = ?";
        $params[] = preg_replace('/\D/', '', $_GET['cpf_cnpj']);
        $types .= "s";
    }
    
    if (isset($_GET['funil_id'])) {
        $filtros[] = "funil_id = ?";
        $params[] = $_GET['funil_id'];
        $types .= "i";
    }
    
    if (isset($_GET['etapa_id'])) {
        $filtros[] = "etapa_funil_id = ?";
        $params[] = $_GET['etapa_id'];
        $types .= "i";
    }
    
    if (isset($_GET['responsavel_id'])) {
        $filtros[] = "responsavel = ?";
        $params[] = $_GET['responsavel_id'];
        $types .= "i";
    }
    
    // Query base
    $where = "WHERE tenant_id = ?";
    array_unshift($params, $tenantId);
    $types = "i" . $types;
    
    if (!empty($filtros)) {
        $where .= " AND " . implode(" AND ", $filtros);
    }
    
    // Contar total
    $countSql = "SELECT COUNT(*) as total FROM clientes $where";
    $countStmt = $conn->prepare($countSql);
    $countStmt->bind_param($types, ...$params);
    $countStmt->execute();
    $total = $countStmt->get_result()->fetch_assoc()['total'];
    $countStmt->close();
    
    // Buscar dados paginados
    $sql = "SELECT 
                id, Nome_Cliente as nome, Email as email, Telefone, Telefone2, Celular,
                Endereco, Cidade, Pais, Estado, Provincia, Bairro, Complemento, CEP,
                CPF_CNPJ, origem_id, Origem, Instagram, Linkedin, Observacoes,
                status, funil_id, etapa_funil_id, responsavel, data_cadastro,
                (SELECT nome FROM usuarios WHERE id = responsavel) as responsavel_nome
            FROM clientes 
            $where 
            ORDER BY id DESC 
            LIMIT ? OFFSET ?";
    
    $stmt = $conn->prepare($sql);
    
    // Adicionar parâmetros de paginação
    $params[] = $limit;
    $params[] = $offset;
    $types .= "ii";
    
    $stmt->bind_param($types, ...$params);
    $stmt->execute();
    $result = $stmt->get_result();
    
    $clientes = [];
    while ($row = $result->fetch_assoc()) {
        // Formatar dados
        $row['telefone'] = formatarTelefone($row['Telefone']);
        $row['telefone2'] = formatarTelefone($row['Telefone2']);
        $row['celular'] = formatarTelefone($row['Celular']);
        $row['cpf_cnpj'] = formatarCpfCnpj($row['CPF_CNPJ']);
        $row['cep'] = formatarCEP($row['CEP']);
        
        unset($row['Telefone'], $row['Telefone2'], $row['Celular'], $row['CPF_CNPJ']);
        
        $clientes[] = $row;
    }
    $stmt->close();
    
    logRequest("clientes", "GET", $_GET, 200);
    
    jsonResponse([
        'success' => true,
        'data' => $clientes,
        'pagination' => [
            'page' => $page,
            'limit' => $limit,
            'total' => (int)$total,
            'pages' => ceil($total / $limit)
        ]
    ]);
}

function buscarCliente($conn, $tenantId, $clienteId) {
    $stmt = $conn->prepare("
        SELECT 
            id, Nome_Cliente as nome, Email as email, Telefone, Telefone2, Celular,
            Endereco, Cidade, Pais, Estado, Provincia, Bairro, Complemento, CEP,
            CPF_CNPJ, origem_id, Origem, Instagram, Linkedin, Observacoes,
            status, funil_id, etapa_funil_id, responsavel, data_cadastro,
            (SELECT nome FROM usuarios WHERE id = responsavel) as responsavel_nome,
            (SELECT nome FROM funis WHERE id = funil_id) as funil_nome,
            (SELECT nome FROM etapas_funis WHERE id = etapa_funil_id) as etapa_nome
        FROM clientes 
        WHERE id = ? AND tenant_id = ?
    ");
    $stmt->bind_param("ii", $clienteId, $tenantId);
    $stmt->execute();
    $result = $stmt->get_result();
    
    if ($result->num_rows === 0) {
        logRequest("clientes/$clienteId", "GET", null, 404);
        jsonResponse(['erro' => 'Cliente não encontrado'], 404);
    }
    
    $cliente = $result->fetch_assoc();
    $stmt->close();
    
    // Formatar dados
    $cliente['telefone'] = formatarTelefone($cliente['Telefone']);
    $cliente['telefone2'] = formatarTelefone($cliente['Telefone2']);
    $cliente['celular'] = formatarTelefone($cliente['Celular']);
    $cliente['cpf_cnpj'] = formatarCpfCnpj($cliente['CPF_CNPJ']);
    $cliente['cep'] = formatarCEP($cliente['CEP']);
    
    unset($cliente['Telefone'], $cliente['Telefone2'], $cliente['Celular'], $cliente['CPF_CNPJ']);
    
    logRequest("clientes/$clienteId", "GET", null, 200);
    
    jsonResponse([
        'success' => true,
        'data' => $cliente
    ]);
}

function criarCliente($conn, $tenantId, $auth) {
    $dados = getRequestBody();
    
    // Validações
    $validarCpfCnpj = isset($dados['validar_cpf_cnpj']) ? (bool)$dados['validar_cpf_cnpj'] : true;
    
    // Verificar campos obrigatórios
    $camposObrigatorios = ['nome', 'telefone', 'cpf_cnpj', 'responsavel_id'];
    foreach ($camposObrigatorios as $campo) {
        if (empty($dados[$campo])) {
            jsonResponse(['erro' => "Campo '$campo' é obrigatório"], 400);
        }
    }
    
    // Limpar e validar CPF/CNPJ
    $cpfCnpj = preg_replace('/\D/', '', $dados['cpf_cnpj']);
    if (strlen($cpfCnpj) !== 11 && strlen($cpfCnpj) !== 14) {
        jsonResponse(['erro' => 'CPF/CNPJ deve ter 11 ou 14 dígitos'], 400);
    }
    
    if (strlen($cpfCnpj) === 11 && !validarCPF($cpfCnpj)) {
        jsonResponse(['erro' => 'CPF inválido'], 400);
    } elseif (strlen($cpfCnpj) === 14 && !validarCNPJ($cpfCnpj)) {
        jsonResponse(['erro' => 'CNPJ inválido'], 400);
    }
    
    // Verificar duplicidade
    if ($validarCpfCnpj && verificarCpfCnpjExistente($conn, $cpfCnpj, $tenantId)) {
        jsonResponse(['erro' => 'CPF/CNPJ já existe neste tenant'], 409);
    }
    
    // Validar responsável
    $stmt = $conn->prepare("SELECT id FROM usuarios WHERE id = ? AND tenant_id = ? AND ativo = 'sim'");
    $stmt->bind_param("ii", $dados['responsavel_id'], $tenantId);
    $stmt->execute();
    if ($stmt->get_result()->num_rows === 0) {
        jsonResponse(['erro' => 'Responsável não encontrado ou inativo'], 400);
    }
    $stmt->close();
    
    // Validar origem
    $origemId = null;
    if (!empty($dados['origem_id'])) {
        $stmt = $conn->prepare("SELECT id, nome FROM origens WHERE id = ? AND tenant_id = ? AND ativo = 1");
        $stmt->bind_param("ii", $dados['origem_id'], $tenantId);
        $stmt->execute();
        $result = $stmt->get_result();
        if ($result->num_rows > 0) {
            $origem = $result->fetch_assoc();
            $origemId = $origem['id'];
            $origemNome = $origem['nome'];
        }
        $stmt->close();
    }
    
    // País e estado/província
    $pais = $dados['pais'] ?? 'Brasil';
    $estado = '';
    $provincia = '';
    
    if (strcasecmp($pais, 'Brasil') === 0) {
        $estado = $dados['estado'] ?? '';
    } else {
        $provincia = $dados['provincia'] ?? '';
    }
    
    // Inserir cliente
    $sql = "INSERT INTO clientes (
        Nome_Cliente, Email, Telefone, Telefone2, Celular, Endereco, Cidade, Pais, Estado,
        Provincia, Bairro, Complemento, CEP, CPF_CNPJ, origem_id, Origem, Instagram, Linkedin,
        Observacoes, status, tenant_id, usuario_cadastro, funil_id, etapa_funil_id, responsavel
    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
    
    $stmt = $conn->prepare($sql);
    
    $telefone = preg_replace('/\D/', '', $dados['telefone']);
    $telefone2 = isset($dados['telefone2']) ? preg_replace('/\D/', '', $dados['telefone2']) : '';
    $celular = isset($dados['celular']) ? preg_replace('/\D/', '', $dados['celular']) : '';
    $cep = isset($dados['cep']) ? preg_replace('/\D/', '', $dados['cep']) : '';
    
    $stmt->bind_param("ssssssssssssssisssssiiiii",
        $dados['nome'],
        $dados['email'] ?? null,
        $telefone,
        $telefone2,
        $celular,
        $dados['endereco'] ?? '',
        $dados['cidade'] ?? '',
        $pais,
        $estado,
        $provincia,
        $dados['bairro'] ?? '',
        $dados['complemento'] ?? '',
        $cep,
        $cpfCnpj,
        $origemId,
        $origemNome ?? '',
        $dados['instagram'] ?? '',
        $dados['linkedin'] ?? '',
        $dados['observacoes'] ?? '',
        1, // status ativo
        $tenantId,
        $auth['api_key_id'], // usuário cadastro (ID da API Key)
        $dados['funil_id'] ?? null,
        $dados['etapa_id'] ?? null,
        $dados['responsavel_id']
    );
    
    if ($stmt->execute()) {
        $clienteId = $conn->insert_id;
        $stmt->close();
        
        logRequest("clientes", "POST", $dados, 201);
        
        jsonResponse([
            'success' => true,
            'message' => 'Cliente criado com sucesso',
            'data' => ['id' => $clienteId]
        ], 201);
    } else {
        logRequest("clientes", "POST", $dados, 500);
        jsonResponse(['erro' => 'Erro ao criar cliente: ' . $stmt->error], 500);
    }
}

function atualizarCliente($conn, $tenantId, $clienteId) {
    $dados = getRequestBody();
    
    // Verificar se cliente existe
    $stmt = $conn->prepare("SELECT id FROM clientes WHERE id = ? AND tenant_id = ?");
    $stmt->bind_param("ii", $clienteId, $tenantId);
    $stmt->execute();
    if ($stmt->get_result()->num_rows === 0) {
        logRequest("clientes/$clienteId", "PUT", $dados, 404);
        jsonResponse(['erro' => 'Cliente não encontrado'], 404);
    }
    $stmt->close();
    
    // Construir query dinâmica
    $campos = [];
    $params = [];
    $types = "";
    
    $camposPermitidos = [
        'nome' => 'Nome_Cliente',
        'email' => 'Email',
        'telefone' => 'Telefone',
        'telefone2' => 'Telefone2',
        'celular' => 'Celular',
        'endereco' => 'Endereco',
        'cidade' => 'Cidade',
        'pais' => 'Pais',
        'estado' => 'Estado',
        'provincia' => 'Provincia',
        'bairro' => 'Bairro',
        'complemento' => 'Complemento',
        'cep' => 'CEP',
        'cpf_cnpj' => 'CPF_CNPJ',
        'origem_id' => 'origem_id',
        'instagram' => 'Instagram',
        'linkedin' => 'Linkedin',
        'observacoes' => 'Observacoes',
        'funil_id' => 'funil_id',
        'etapa_id' => 'etapa_funil_id',
        'responsavel_id' => 'responsavel'
    ];
    
    foreach ($dados as $campo => $valor) {
        if (isset($camposPermitidos[$campo])) {
            $campoBanco = $camposPermitidos[$campo];
            
            // Tratamentos especiais
            if ($campo === 'telefone' || $campo === 'telefone2' || $campo === 'celular') {
                $valor = preg_replace('/\D/', '', $valor);
            } elseif ($campo === 'cpf_cnpj') {
                $valor = preg_replace('/\D/', '', $valor);
            } elseif ($campo === 'cep') {
                $valor = preg_replace('/\D/', '', $valor);
            }
            
            $campos[] = "$campoBanco = ?";
            $params[] = $valor;
            $types .= "s";
        }
    }
    
    if (empty($campos)) {
        jsonResponse(['erro' => 'Nenhum campo para atualizar'], 400);
    }
    
    // Adicionar ID e tenant aos parâmetros
    $params[] = $clienteId;
    $params[] = $tenantId;
    $types .= "ii";
    
    $sql = "UPDATE clientes SET " . implode(", ", $campos) . " WHERE id = ? AND tenant_id = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param($types, ...$params);
    
    if ($stmt->execute()) {
        logRequest("clientes/$clienteId", "PUT", $dados, 200);
        jsonResponse([
            'success' => true,
            'message' => 'Cliente atualizado com sucesso'
        ]);
    } else {
        logRequest("clientes/$clienteId", "PUT", $dados, 500);
        jsonResponse(['erro' => 'Erro ao atualizar cliente'], 500);
    }
}

function excluirCliente($conn, $tenantId, $clienteId) {
    // Verificar se cliente existe
    $stmt = $conn->prepare("SELECT id FROM clientes WHERE id = ? AND tenant_id = ?");
    $stmt->bind_param("ii", $clienteId, $tenantId);
    $stmt->execute();
    if ($stmt->get_result()->num_rows === 0) {
        logRequest("clientes/$clienteId", "DELETE", null, 404);
        jsonResponse(['erro' => 'Cliente não encontrado'], 404);
    }
    $stmt->close();
    
    // Soft delete ou hard delete? Vamos fazer soft delete
    $stmt = $conn->prepare("UPDATE clientes SET status = 0 WHERE id = ? AND tenant_id = ?");
    $stmt->bind_param("ii", $clienteId, $tenantId);
    
    if ($stmt->execute()) {
        logRequest("clientes/$clienteId", "DELETE", null, 200);
        jsonResponse([
            'success' => true,
            'message' => 'Cliente excluído com sucesso'
        ]);
    } else {
        logRequest("clientes/$clienteId", "DELETE", null, 500);
        jsonResponse(['erro' => 'Erro ao excluir cliente'], 500);
    }
}

// Funções auxiliares
function formatarTelefone($numero) {
    if (empty($numero)) return '';
    $numero = preg_replace('/\D/', '', $numero);
    if (strlen($numero) === 10) {
        return '(' . substr($numero, 0, 2) . ') ' . substr($numero, 2, 4) . '-' . substr($numero, 6);
    } elseif (strlen($numero) === 11) {
        return '(' . substr($numero, 0, 2) . ') ' . substr($numero, 2, 5) . '-' . substr($numero, 7);
    }
    return $numero;
}

function formatarCpfCnpj($valor) {
    $valor = preg_replace('/\D/', '', $valor);
    if (strlen($valor) === 11) {
        return preg_replace('/(\d{3})(\d{3})(\d{3})(\d{2})/', '$1.$2.$3-$4', $valor);
    }
    if (strlen($valor) === 14) {
        return preg_replace('/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/', '$1.$2.$3/$4-$5', $valor);
    }
    return $valor;
}

function formatarCEP($cep) {
    $cep = preg_replace('/\D/', '', $cep);
    if (strlen($cep) === 8) {
        return substr($cep, 0, 5) . '-' . substr($cep, 5);
    }
    return $cep;
}

function validarCPF($cpf) {
    $cpf = preg_replace('/[^0-9]/', '', $cpf);
    if (strlen($cpf) != 11 || preg_match('/(\d)\1{10}/', $cpf)) return false;
    
    for ($t = 9; $t < 11; $t++) {
        for ($d = 0, $c = 0; $c < $t; $c++) {
            $d += $cpf[$c] * (($t + 1) - $c);
        }
        $d = ((10 * $d) % 11) % 10;
        if ($cpf[$c] != $d) return false;
    }
    return true;
}

function validarCNPJ($cnpj) {
    $cnpj = preg_replace('/[^0-9]/', '', $cnpj);
    if (strlen($cnpj) != 14 || preg_match('/(\d)\1{13}/', $cnpj)) return false;
    
    for ($i = 0, $j = 5, $soma = 0; $i < 12; $i++) {
        $soma += $cnpj[$i] * $j;
        $j = ($j == 2) ? 9 : $j - 1;
    }
    $resto = $soma % 11;
    if ($cnpj[12] != ($resto < 2 ? 0 : 11 - $resto)) return false;
    
    for ($i = 0, $j = 6, $soma = 0; $i < 13; $i++) {
        $soma += $cnpj[$i] * $j;
        $j = ($j == 2) ? 9 : $j - 1;
    }
    $resto = $soma % 11;
    return $cnpj[13] == ($resto < 2 ? 0 : 11 - $resto);
}

function verificarCpfCnpjExistente($conn, $cpfCnpj, $tenantId, $clienteId = null) {
    $cpfCnpj = preg_replace('/\D/', '', $cpfCnpj);
    
    if ($clienteId) {
        $sql = "SELECT COUNT(*) as total FROM clientes WHERE CPF_CNPJ = ? AND tenant_id = ? AND id != ?";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("sii", $cpfCnpj, $tenantId, $clienteId);
    } else {
        $sql = "SELECT COUNT(*) as total FROM clientes WHERE CPF_CNPJ = ? AND tenant_id = ?";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("si", $cpfCnpj, $tenantId);
    }
    
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_assoc();
    $stmt->close();
    
    return ($row['total'] > 0);
}
?>