'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
