/**
 * DocuAgro - Serviço de Banco de Dados
 * Todas as operações CRUD para produtores, documentos e dossiês
 */

const Database = require('better-sqlite3');
const path = require('path');
const { v4: uuidv4 } = require('uuid');

const dbPath = process.env.DB_PATH || path.join(__dirname, '..', '..', 'data', 'docuagro.db');
const db = new Database(dbPath);
db.pragma('journal_mode = WAL');
db.pragma('foreign_keys = ON');

// ========== PRODUTORES ==========

/**
 * Busca produtor pelo chat_id do Telegram
 */
function buscarProdutorPorChat(chatId) {
  return db.prepare('SELECT * FROM produtores WHERE telegram_chat_id = ?').get(String(chatId));
}

/**
 * Busca produtor pelo ID
 */
function buscarProdutorPorId(id) {
  return db.prepare('SELECT * FROM produtores WHERE id = ?').get(id);
}

/**
 * Cria novo produtor a partir do Telegram
 */
function criarProdutor(chatId, username, nome) {
  const id = uuidv4();
  db.prepare(`
    INSERT INTO produtores (id, cooperativa_id, nome, telegram_chat_id, telegram_username, status, etapa_atual)
    VALUES (?, 'coop_001', ?, ?, ?, 'pendente', 'onboarding')
  `).run(id, nome || 'Novo Produtor', String(chatId), username || null);
  return buscarProdutorPorId(id);
}

/**
 * Atualiza dados do produtor
 */
function atualizarProdutor(id, dados) {
  const campos = [];
  const valores = [];
  
  const permitidos = [
    'nome', 'cpf_cnpj', 'telefone', 'propriedade_nome',
    'propriedade_municipio', 'propriedade_estado', 'propriedade_area_ha',
    'cultura_principal', 'status', 'etapa_atual', 'docs_completos'
  ];
  
  for (const [chave, valor] of Object.entries(dados)) {
    if (permitidos.includes(chave)) {
      campos.push(`${chave} = ?`);
      valores.push(valor);
    }
  }
  
  if (campos.length === 0) return;
  
  campos.push('atualizado_em = CURRENT_TIMESTAMP');
  valores.push(id);
  
  db.prepare(`UPDATE produtores SET ${campos.join(', ')} WHERE id = ?`).run(...valores);
  return buscarProdutorPorId(id);
}

/**
 * Lista todos os produtores (para painel)
 */
function listarProdutores(cooperativaId = 'coop_001') {
  return db.prepare(`
    SELECT p.*, 
      (SELECT COUNT(*) FROM documentos d WHERE d.produtor_id = p.id AND d.status = 'aprovado') as docs_aprovados,
      (SELECT COUNT(*) FROM documentos d WHERE d.produtor_id = p.id AND d.status = 'rejeitado') as docs_rejeitados,
      (SELECT COUNT(*) FROM documentos d WHERE d.produtor_id = p.id AND d.status = 'enviado') as docs_enviados
    FROM produtores p 
    WHERE p.cooperativa_id = ?
    ORDER BY p.criado_em DESC
  `).all(cooperativaId);
}

/**
 * Estatísticas do dashboard
 */
function estatisticas(cooperativaId = 'coop_001') {
  const total = db.prepare('SELECT COUNT(*) as n FROM produtores WHERE cooperativa_id = ?').get(cooperativaId);
  const completos = db.prepare("SELECT COUNT(*) as n FROM produtores WHERE cooperativa_id = ? AND status = 'completo'").get(cooperativaId);
  const emAndamento = db.prepare("SELECT COUNT(*) as n FROM produtores WHERE cooperativa_id = ? AND status = 'em_andamento'").get(cooperativaId);
  const pendentes = db.prepare("SELECT COUNT(*) as n FROM produtores WHERE cooperativa_id = ? AND status = 'pendente'").get(cooperativaId);
  const irregulares = db.prepare("SELECT COUNT(*) as n FROM produtores WHERE cooperativa_id = ? AND status = 'irregular'").get(cooperativaId);
  
  const docsTotal = db.prepare('SELECT COUNT(*) as n FROM documentos d JOIN produtores p ON d.produtor_id = p.id WHERE p.cooperativa_id = ?').get(cooperativaId);
  const docsAprovados = db.prepare("SELECT COUNT(*) as n FROM documentos d JOIN produtores p ON d.produtor_id = p.id WHERE p.cooperativa_id = ? AND d.status = 'aprovado'").get(cooperativaId);
  
  return {
    totalProdutores: total.n,
    completos: completos.n,
    emAndamento: emAndamento.n,
    pendentes: pendentes.n,
    irregulares: irregulares.n,
    totalDocumentos: docsTotal.n,
    documentosAprovados: docsAprovados.n,
    percentualCompliance: total.n > 0 ? Math.round((completos.n / total.n) * 100) : 0
  };
}

// ========== DOCUMENTOS ==========

/**
 * Busca documentos de um produtor
 */
function buscarDocumentos(produtorId) {
  return db.prepare('SELECT * FROM documentos WHERE produtor_id = ? ORDER BY tipo').all(produtorId);
}

/**
 * Busca documento específico
 */
function buscarDocumento(produtorId, tipo) {
  return db.prepare('SELECT * FROM documentos WHERE produtor_id = ? AND tipo = ?').get(produtorId, tipo);
}

/**
 * Cria ou atualiza documento
 */
function salvarDocumento(produtorId, tipo, dados) {
  const existente = buscarDocumento(produtorId, tipo);
  
  if (existente) {
    db.prepare(`
      UPDATE documentos SET
        status = ?, arquivo_path = ?, arquivo_nome = ?, arquivo_tipo = ?,
        arquivo_tamanho = ?, enviado_em = CURRENT_TIMESTAMP,
        atualizado_em = CURRENT_TIMESTAMP
      WHERE id = ?
    `).run(
      dados.status || 'enviado',
      dados.arquivo_path, dados.arquivo_nome, dados.arquivo_tipo,
      dados.arquivo_tamanho || 0, existente.id
    );
    return buscarDocumento(produtorId, tipo);
  }
  
  const id = uuidv4();
  db.prepare(`
    INSERT INTO documentos (id, produtor_id, tipo, status, arquivo_path, arquivo_nome, arquivo_tipo, arquivo_tamanho, enviado_em)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
  `).run(id, produtorId, tipo, dados.status || 'enviado', dados.arquivo_path, dados.arquivo_nome, dados.arquivo_tipo, dados.arquivo_tamanho || 0);
  
  // Atualiza contagem de docs do produtor
  atualizarContagemDocs(produtorId);
  
  return buscarDocumento(produtorId, tipo);
}

/**
 * Atualiza validação do documento
 */
function atualizarValidacao(docId, resultado, detalhes) {
  db.prepare(`
    UPDATE documentos SET
      status = ?, validacao_resultado = ?, validacao_detalhes = ?,
      validado_em = CURRENT_TIMESTAMP, atualizado_em = CURRENT_TIMESTAMP
    WHERE id = ?
  `).run(resultado, resultado, detalhes, docId);
  
  // Busca o doc pra atualizar contagem
  const doc = db.prepare('SELECT produtor_id FROM documentos WHERE id = ?').get(docId);
  if (doc) atualizarContagemDocs(doc.produtor_id);
}

/**
 * Atualiza contagem de documentos completos do produtor
 */
function atualizarContagemDocs(produtorId) {
  const aprovados = db.prepare("SELECT COUNT(*) as n FROM documentos WHERE produtor_id = ? AND status = 'aprovado'").get(produtorId);
  const total = db.prepare("SELECT COUNT(*) as n FROM documentos WHERE produtor_id = ?").get(produtorId);
  
  let status = 'pendente';
  if (aprovados.n >= 8) status = 'completo';
  else if (total.n > 0) status = 'em_andamento';
  
  db.prepare('UPDATE produtores SET docs_completos = ?, status = ?, atualizado_em = CURRENT_TIMESTAMP WHERE id = ?')
    .run(aprovados.n, status, produtorId);
}

// ========== CONVERSAS ==========

/**
 * Salva mensagem no histórico
 */
function salvarMensagem(produtorId, chatId, role, conteudo, tipo = 'texto') {
  db.prepare(`
    INSERT INTO conversas (produtor_id, chat_id, role, conteudo, tipo_mensagem)
    VALUES (?, ?, ?, ?, ?)
  `).run(produtorId, String(chatId), role, conteudo, tipo);
}

/**
 * Busca histórico de conversa (últimas N mensagens)
 */
function buscarHistorico(produtorId, limite = 20) {
  return db.prepare(`
    SELECT role, conteudo, tipo_mensagem, criado_em
    FROM conversas
    WHERE produtor_id = ?
    ORDER BY id DESC
    LIMIT ?
  `).all(produtorId, limite).reverse();
}

// ========== DOSSIÊS ==========

/**
 * Salva registro de dossiê gerado
 */
function salvarDossie(produtorId, arquivoPath, docsIncluidos) {
  const id = uuidv4();
  const versao = db.prepare('SELECT COALESCE(MAX(versao), 0) + 1 as v FROM dossies WHERE produtor_id = ?').get(produtorId);
  
  db.prepare(`
    INSERT INTO dossies (id, produtor_id, arquivo_path, versao, docs_incluidos)
    VALUES (?, ?, ?, ?, ?)
  `).run(id, produtorId, arquivoPath, versao.v, JSON.stringify(docsIncluidos));
  
  return { id, versao: versao.v, arquivo_path: arquivoPath };
}

/**
 * Busca último dossiê de um produtor
 */
function buscarUltimoDossie(produtorId) {
  return db.prepare('SELECT * FROM dossies WHERE produtor_id = ? ORDER BY versao DESC LIMIT 1').get(produtorId);
}

module.exports = {
  db,
  buscarProdutorPorChat,
  buscarProdutorPorId,
  criarProdutor,
  atualizarProdutor,
  listarProdutores,
  estatisticas,
  buscarDocumentos,
  buscarDocumento,
  salvarDocumento,
  atualizarValidacao,
  atualizarContagemDocs,
  salvarMensagem,
  buscarHistorico,
  salvarDossie,
  buscarUltimoDossie
};
