import { Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';

@Injectable()
export class RelatoriosService {
  constructor(private ds: DataSource) {}

  async orcamentoMensal(ano: number, mes: number) {
    const rows = await this.ds.query(`
      SELECT op.*, cc.nome as centro_custo_nome, cat.nome as categoria_nome
      FROM orcamento_planejado op
      LEFT JOIN centros_custo cc ON cc.id::text = op.centro_custo_id::text
      LEFT JOIN categorias cat ON cat.id::text = op.categoria_id::text
      WHERE op.ano = $1 AND op.mes = $2
      ORDER BY cc.nome, cat.nome`, [ano, mes]);

    const totais = rows.reduce((acc: any, r: any) => ({
      planejado: (acc.planejado || 0) + (r.valor_planejado || 0),
      comprometido: (acc.comprometido || 0) + (r.valor_comprometido || 0),
      realizado: (acc.realizado || 0) + (r.valor_realizado || 0),
    }), {});

    return { ano, mes, itens: rows, totais };
  }

  async demandasPeriodo(de: string, ate: string) {
    const rows = await this.ds.query(`
      SELECT d.*, cc.nome as centro_custo_nome, l.nome as local_nome
      FROM demandas d
      LEFT JOIN centros_custo cc ON cc.id::text = d.centro_custo_id::text
      LEFT JOIN locais l ON l.id::text = d.local_id::text
      WHERE d.created_at >= $1 AND d.created_at <= $2
      ORDER BY d.created_at DESC`, [de, ate + ' 23:59:59']);

    const por_status = await this.ds.query(`
      SELECT status, COUNT(*) as total FROM demandas
      WHERE created_at >= $1 AND created_at <= $2
      GROUP BY status`, [de, ate + ' 23:59:59']);

    return { periodo: { de, ate }, demandas: rows, resumo_por_status: por_status, total: rows.length };
  }

  async fornecedoresRanking() {
    const rows = await this.ds.query(`
      SELECT f.id, f.razao_social, f.nome_fantasia, f.rating,
        COUNT(DISTINCT os.id) as total_os,
        COALESCE(AVG(av.nota), 0) as nota_media,
        COALESCE(SUM(os.valor), 0) as valor_total_os
      FROM fornecedores f
      LEFT JOIN ordens_servico os ON os.fornecedor_id::text = f.id::text
      LEFT JOIN avaliacoes av ON av.fornecedor_id::text = f.id::text
      WHERE f.ativo = true
      GROUP BY f.id, f.razao_social, f.nome_fantasia, f.rating
      ORDER BY nota_media DESC, total_os DESC`);
    return rows;
  }

  async demandasPorImpactoAmbiental() {
    const rows = await this.ds.query(`
      SELECT d.impacto_ambiental_demanda as impacto, COUNT(*) as total,
        d.status, c.nome as categoria
      FROM demandas d
      LEFT JOIN categorias c ON c.id::text = d.categoria_id::text
      WHERE d.impacto_ambiental_demanda IS NOT NULL
      GROUP BY d.impacto_ambiental_demanda, d.status, c.nome
      ORDER BY d.impacto_ambiental_demanda, d.status`);
    
    const resumo = await this.ds.query(`
      SELECT impacto_ambiental_demanda as impacto, COUNT(*) as total
      FROM demandas WHERE impacto_ambiental_demanda IS NOT NULL
      GROUP BY impacto_ambiental_demanda`);

    return { detalhes: rows, resumo };
  }

  async fornecedoresPorEsg() {
    const rows = await this.ds.query(`
      SELECT f.id, f.razao_social, f.nome_fantasia, f.classificacao_esg,
        f.possui_politica_ambiental, f.possui_politica_sst, f.declara_uso_epi, f.equipe_treinada,
        f.rating, COUNT(DISTINCT os.id) as total_os
      FROM fornecedores f
      LEFT JOIN ordens_servico os ON os.fornecedor_id::text = f.id::text
      WHERE f.ativo = true
      GROUP BY f.id, f.razao_social, f.nome_fantasia, f.classificacao_esg,
        f.possui_politica_ambiental, f.possui_politica_sst, f.declara_uso_epi, f.equipe_treinada, f.rating
      ORDER BY f.classificacao_esg DESC, f.rating DESC`);

    const resumo = await this.ds.query(`
      SELECT classificacao_esg, COUNT(*) as total
      FROM fornecedores WHERE ativo = true AND classificacao_esg IS NOT NULL
      GROUP BY classificacao_esg`);

    return { fornecedores: rows, resumo };
  }

  async evolucaoManutencaoPreventiva() {
    const rows = await this.ds.query(`
      SELECT EXTRACT(MONTH FROM d.created_at) as mes, EXTRACT(YEAR FROM d.created_at) as ano,
        c.tipo_manutencao, COUNT(*) as total
      FROM demandas d
      LEFT JOIN categorias c ON c.id::text = d.categoria_id::text
      WHERE c.tipo_manutencao IS NOT NULL
      GROUP BY EXTRACT(MONTH FROM d.created_at), EXTRACT(YEAR FROM d.created_at), c.tipo_manutencao
      ORDER BY ano, mes`);
    return rows;
  }

  async excecoesGovernanca() {
    const rows = await this.ds.query(`
      SELECT w.id, w.demanda_id, w.valor_total, w.status, w.etapas,
        d.titulo as demanda_titulo, d.numero as demanda_numero
      FROM workflow_aprovacoes w
      LEFT JOIN demandas d ON d.id::text = w.demanda_id::text
      ORDER BY w.created_at DESC`);
    
    // Filter workflows that have ressalva in any step
    const comRessalva = rows.filter((w: any) => {
      try {
        const etapas = typeof w.etapas === 'string' ? JSON.parse(w.etapas) : w.etapas;
        return Array.isArray(etapas) && etapas.some((e: any) => e.ressalva || e.status === 'aprovado_com_ressalva');
      } catch { return false; }
    });

    return { total: comRessalva.length, itens: comRessalva };
  }

  async osPerformance() {
    const por_status = await this.ds.query(`
      SELECT status, COUNT(*) as total, COALESCE(SUM(valor),0) as valor_total
      FROM ordens_servico GROUP BY status`);

    const tempo_medio = await this.ds.query(`
      SELECT AVG(data_conclusao::date - data_inicio::date) as dias_medio
      FROM ordens_servico WHERE status = 'concluida' AND data_inicio IS NOT NULL AND data_conclusao IS NOT NULL`);

    const por_fornecedor = await this.ds.query(`
      SELECT f.razao_social, COUNT(os.id) as total, AVG(os.data_conclusao::date - os.data_inicio::date) as dias_medio
      FROM ordens_servico os
      LEFT JOIN fornecedores f ON f.id::text = os.fornecedor_id::text
      GROUP BY os.fornecedor_id, f.razao_social
      ORDER BY total DESC`);

    return { por_status, tempo_medio_dias: tempo_medio[0]?.dias_medio || null, por_fornecedor };
  }
}
