'use strict' const { execute, queryOne, query } = require('../database/postgres') class Cliente { static findById(id) { return queryOne('SELECT * FROM clientes WHERE id = $1', [id]) } static findByCpfCnpj(cpfCnpj, tenantId) { return queryOne('SELECT * FROM clientes WHERE cpf_cnpj = $1 AND tenant_id = $2', [cpfCnpj, tenantId]) } static findByUserId(userId, tenantId) { return queryOne('SELECT * FROM clientes WHERE user_id = $1 AND tenant_id = $2', [userId, tenantId]) } static list(tenantId, { search, tipo, status, limit = 50, offset = 0 } = {}) { const params = [tenantId] let where = 'WHERE tenant_id = $1' if (tipo) { params.push(tipo); where += ` AND tipo = $${params.length}` } if (status) { params.push(status); where += ` AND status = $${params.length}` } if (search) { params.push(`%${search.replace(/[%_]/g, '\\$&')}%`) where += ` AND (nome ILIKE $${params.length} OR cpf_cnpj ILIKE $${params.length} OR email ILIKE $${params.length})` } params.push(Math.min(Number(limit) || 50, 200)) params.push(Math.max(Number(offset) || 0, 0)) return query( `SELECT * FROM clientes ${where} ORDER BY nome ASC LIMIT $${params.length - 1} OFFSET $${params.length}`, params ) } static create({ tenant_id, tipo, nome, cpf_cnpj, email, status = 'ativo', user_id = null }) { return execute( `INSERT INTO clientes (tenant_id, tipo, nome, cpf_cnpj, email, status, user_id) VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING *`, [tenant_id, tipo, nome, cpf_cnpj, email || null, status, user_id] ) } static update(id, { nome, email, status }) { return execute( `UPDATE clientes SET nome=$1, email=$2, status=$3, updated_at=NOW() WHERE id=$4`, [nome, email || null, status, id] ) } static delete(id) { return execute('DELETE FROM clientes WHERE id = $1', [id]) } // ── Endereços ───────────────────────────────────────────── static listEnderecos(clienteId) { return query('SELECT * FROM cliente_enderecos WHERE cliente_id = $1 ORDER BY principal DESC, id ASC', [clienteId]) } static createEndereco({ cliente_id, tipo, cep, rua, numero, complemento, bairro, cidade, estado, referencia, principal }) { return execute( `INSERT INTO cliente_enderecos (cliente_id,tipo,cep,rua,numero,complemento,bairro,cidade,estado,referencia,principal) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) RETURNING *`, [cliente_id, tipo || 'entrega', cep || null, rua || null, numero || null, complemento || null, bairro || null, cidade || null, estado || null, referencia || null, principal || false] ) } static updateEndereco(id, { tipo, cep, rua, numero, complemento, bairro, cidade, estado, referencia, principal }) { return execute( `UPDATE cliente_enderecos SET tipo=$1,cep=$2,rua=$3,numero=$4,complemento=$5, bairro=$6,cidade=$7,estado=$8,referencia=$9,principal=$10 WHERE id=$11`, [tipo, cep || null, rua || null, numero || null, complemento || null, bairro || null, cidade || null, estado || null, referencia || null, principal || false, id] ) } static setEndereçoPrincipal(clienteId, enderecoId) { return execute( `UPDATE cliente_enderecos SET principal = (id = $2) WHERE cliente_id = $1`, [clienteId, enderecoId] ) } static deleteEndereco(id) { return execute('DELETE FROM cliente_enderecos WHERE id = $1', [id]) } // ── Telefones ───────────────────────────────────────────── static listTelefones(clienteId) { return query('SELECT * FROM cliente_telefones WHERE cliente_id = $1 ORDER BY principal DESC, id ASC', [clienteId]) } static createTelefone({ cliente_id, tipo, numero, ramal, aceita_whatsapp, principal }) { return execute( `INSERT INTO cliente_telefones (cliente_id,tipo,numero,ramal,aceita_whatsapp,principal) VALUES ($1,$2,$3,$4,$5,$6) RETURNING *`, [cliente_id, tipo || 'celular', numero, ramal || null, aceita_whatsapp || false, principal || false] ) } static updateTelefone(id, { tipo, numero, ramal, aceita_whatsapp, principal }) { return execute( `UPDATE cliente_telefones SET tipo=$1,numero=$2,ramal=$3,aceita_whatsapp=$4,principal=$5 WHERE id=$6`, [tipo, numero, ramal || null, aceita_whatsapp || false, principal || false, id] ) } static deleteTelefone(id) { return execute('DELETE FROM cliente_telefones WHERE id = $1', [id]) } // ── Responsáveis ───────────────────────────────────────── static listResponsaveis(clienteId) { return query( `SELECT r.*, t.numero AS telefone_numero FROM cliente_responsaveis r LEFT JOIN cliente_telefones t ON t.id = r.telefone_id WHERE r.cliente_id = $1 ORDER BY r.id ASC`, [clienteId] ) } static createResponsavel({ cliente_id, nome, cargo, setor, telefone_id, email, permissao }) { return execute( `INSERT INTO cliente_responsaveis (cliente_id,nome,cargo,setor,telefone_id,email,permissao) VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING *`, [cliente_id, nome, cargo || null, setor || null, telefone_id || null, email || null, permissao || null] ) } static updateResponsavel(id, { nome, cargo, setor, telefone_id, email, permissao }) { return execute( `UPDATE cliente_responsaveis SET nome=$1,cargo=$2,setor=$3,telefone_id=$4,email=$5,permissao=$6 WHERE id=$7`, [nome, cargo || null, setor || null, telefone_id || null, email || null, permissao || null, id] ) } static deleteResponsavel(id) { return execute('DELETE FROM cliente_responsaveis WHERE id = $1', [id]) } // ── Dados completos (cliente + endereços + telefones + responsáveis) ────── static async findComplete(id) { const [cliente, enderecos, telefones, responsaveis] = await Promise.all([ Cliente.findById(id), Cliente.listEnderecos(id), Cliente.listTelefones(id), Cliente.listResponsaveis(id), ]) if (!cliente) return null return { ...cliente, enderecos, telefones, responsaveis } } } module.exports = Cliente