<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class financeiro_model extends CI_Model {

    // ── CONTAS ────────────────────────────────────────────────
    public function get_contas()
    {
        return $this->db->where('ativo', 1)->order_by('nome')->get('fin_contas')->result();
    }

    public function get_saldos_contas()
    {
        return $this->db->where('ativo', 1)->get('fin_contas')->result();
    }

    public function get_saldo_conta($conta_id, $data_ini = null, $data_fim = null)
    {
        $sql = "SELECT 
            SUM(CASE WHEN tipo='receber' AND status='pago' THEN valor ELSE 0 END) -
            SUM(CASE WHEN tipo='pagar' AND status='pago' THEN valor ELSE 0 END) AS saldo
            FROM fin_lancamentos WHERE conta_id = ?";
        $params = [$conta_id];
        if ($data_ini) { $sql .= " AND vencimento >= ?"; $params[] = $data_ini; }
        if ($data_fim) { $sql .= " AND vencimento <= ?"; $params[] = $data_fim; }
        $r = $this->db->query($sql, $params)->row();
        return $r ? (float)$r->saldo : 0;
    }

    public function atualizar_saldo_conta($conta_id)
    {
        if (!$conta_id) return;
        $conta = $this->db->where('id',$conta_id)->get('fin_contas')->row();
        if (!$conta) return;
        $sql = "SELECT 
            SUM(CASE WHEN tipo='receber' AND status='pago' THEN valor ELSE 0 END) AS entradas,
            SUM(CASE WHEN tipo='pagar' AND status='pago' THEN valor ELSE 0 END) AS saidas
            FROM fin_lancamentos WHERE conta_id = ?";
        $r = $this->db->query($sql, [$conta_id])->row();
        $saldo = (float)$conta->saldo_inicial + (float)($r->entradas ?? 0) - (float)($r->saidas ?? 0);
        // Also include transfers
        $tin = $this->db->query("SELECT SUM(valor) AS v FROM fin_transferencias WHERE conta_destino_id=? AND 1=1", [$conta_id])->row();
        $tout = $this->db->query("SELECT SUM(valor) AS v FROM fin_transferencias WHERE conta_origem_id=? AND 1=1", [$conta_id])->row();
        $saldo += (float)($tin->v ?? 0) - (float)($tout->v ?? 0);
        $this->db->where('id',$conta_id)->update('fin_contas', ['saldo_atual' => $saldo]);
    }

    // ── LANÇAMENTOS ───────────────────────────────────────────
    public function add_lancamento(array $data)
    {
        $data['created_at'] = isset($data['created_at']) ? $data['created_at'] : date('Y-m-d H:i:s');
        $this->db->insert('fin_lancamentos', $data);
        return $this->db->insert_id();
    }

    public function update_lancamento($id, array $data)
    {
        $data['updated_at'] = date('Y-m-d H:i:s');
        $this->db->where('id', $id)->update('fin_lancamentos', $data);
    }

    public function get_lancamento($id)
    {
        $this->db->select('l.*, u.name AS client_nome, c.case_no, ct.nome AS conta_nome');
        $this->db->from('fin_lancamentos l');
        $this->db->join('users u','u.id = l.client_id','left');
        $this->db->join('cases c','c.id = l.case_id','left');
        $this->db->join('fin_contas ct','ct.id = l.conta_id','left');
        $this->db->where('l.id', $id);
        return $this->db->get()->row();
    }

    public function get_lancamentos(array $f = [])
    {
        $this->db->select('l.*, u.name AS client_nome, c.case_no, ct.nome AS conta_nome');
        $this->db->from('fin_lancamentos l');
        $this->db->join('users u','u.id = l.client_id','left');
        $this->db->join('cases c','c.id = l.case_id','left');
        $this->db->join('fin_contas ct','ct.id = l.conta_id','left');
        if (!empty($f['tipo']))      $this->db->where('l.tipo', $f['tipo']);
        if (!empty($f['status']))    $this->db->where('l.status', $f['status']);
        if (!empty($f['client_id'])) $this->db->where('l.client_id', $f['client_id']);
        if (!empty($f['conta_id']))  $this->db->where('l.conta_id', $f['conta_id']);
        if (!empty($f['data_ini']))  $this->db->where('l.vencimento >=', $f['data_ini']);
        if (!empty($f['data_fim']))  $this->db->where('l.vencimento <=', $f['data_fim']);
        $this->db->order_by('l.vencimento','ASC');
        return $this->db->get()->result();
    }

    public function get_lancamentos_periodo($tipo, $data_ini, $data_fim)
    {
        return $this->get_lancamentos(['tipo'=>$tipo,'data_ini'=>$data_ini,'data_fim'=>$data_fim]);
    }

    public function get_totais(array $f = [])
    {
        $sql = "SELECT 
            SUM(CASE WHEN tipo='receber' THEN valor ELSE 0 END) AS total_receber,
            SUM(CASE WHEN tipo='pagar' THEN valor ELSE 0 END) AS total_pagar,
            SUM(CASE WHEN tipo='receber' AND status='pago' THEN valor ELSE 0 END) AS total_recebido,
            SUM(CASE WHEN tipo='pagar' AND status='pago' THEN valor ELSE 0 END) AS total_pago,
            SUM(CASE WHEN tipo='receber' AND status='pendente' THEN valor ELSE 0 END) AS total_pendente_receber,
            SUM(CASE WHEN tipo='pagar' AND status='pendente' THEN valor ELSE 0 END) AS total_pendente_pagar,
            SUM(CASE WHEN tipo='receber' AND status='pendente' AND vencimento < CURDATE() THEN valor ELSE 0 END) AS total_vencido_receber,
            SUM(CASE WHEN tipo='pagar' AND status='pendente' AND vencimento < CURDATE() THEN valor ELSE 0 END) AS total_vencido_pagar
            FROM fin_lancamentos WHERE 1=1";
        $params = [];
        if (!empty($f['tipo']))      { $sql .= " AND tipo=?"; $params[] = $f['tipo']; }
        if (!empty($f['client_id'])) { $sql .= " AND client_id=?"; $params[] = $f['client_id']; }
        if (!empty($f['conta_id']))  { $sql .= " AND conta_id=?"; $params[] = $f['conta_id']; }
        if (!empty($f['data_ini']))  { $sql .= " AND vencimento>=?"; $params[] = $f['data_ini']; }
        if (!empty($f['data_fim']))  { $sql .= " AND vencimento<=?"; $params[] = $f['data_fim']; }
        return $this->db->query($sql, $params)->row();
    }

    public function get_totais_mes($data_ini, $data_fim)
    {
        return $this->get_totais(['data_ini'=>$data_ini,'data_fim'=>$data_fim]);
    }

    public function get_vencidos()
    {
        $this->db->select('l.*, u.name AS client_nome');
        $this->db->from('fin_lancamentos l');
        $this->db->join('users u','u.id = l.client_id','left');
        $this->db->where('l.status','pendente');
        $this->db->where('l.vencimento <', date('Y-m-d'));
        $this->db->order_by('l.vencimento','ASC');
        $this->db->limit(20);
        return $this->db->get()->result();
    }

    // ── CATEGORIAS ────────────────────────────────────────────
    public function get_categorias($tipo = null)
    {
        if ($tipo) $this->db->where("(tipo='$tipo' OR tipo='ambos')");
        return $this->db->order_by('nome')->get('fin_categorias')->result();
    }

    // ── TRANSFERÊNCIAS ────────────────────────────────────────
    public function get_transferencias()
    {
        $this->db->select('t.*, co.nome AS conta_origem, cd.nome AS conta_destino');
        $this->db->from('fin_transferencias t');
        $this->db->join('fin_contas co','co.id = t.conta_origem_id','left');
        $this->db->join('fin_contas cd','cd.id = t.conta_destino_id','left');
        $this->db->order_by('t.data_transferencia','DESC');
        return $this->db->get()->result();
    }

    // ── EXTRATO ───────────────────────────────────────────────
    public function get_extrato($conta_id, $data_ini, $data_fim)
    {
        return $this->get_lancamentos(['conta_id'=>$conta_id,'data_ini'=>$data_ini,'data_fim'=>$data_fim]);
    }

    // ── RELATÓRIOS ────────────────────────────────────────────
    public function get_lancamentos_relatorio($tipo, $data_ini, $data_fim, $conta_id = null)
    {
        $f = ['data_ini'=>$data_ini,'data_fim'=>$data_fim];
        if (in_array($tipo,['receber','pagar'])) $f['tipo'] = $tipo;
        if ($conta_id) $f['conta_id'] = $conta_id;
        return $this->get_lancamentos($f);
    }

    // ── BPO ───────────────────────────────────────────────────
    public function get_lancamentos_bpo(array $f = [])
    {
        $this->db->select('l.*, u.name AS client_nome, c.case_no');
        $this->db->from('fin_lancamentos l');
        $this->db->join('users u','u.id = l.client_id','left');
        $this->db->join('cases c','c.id = l.case_id','left');
        if (!empty($f['client_id'])) $this->db->where('l.client_id',$f['client_id']);
        if (!empty($f['status']))    $this->db->where('l.status',$f['status']);
        if (!empty($f['data_ini']))  $this->db->where('l.vencimento >=',$f['data_ini']);
        if (!empty($f['data_fim']))  $this->db->where('l.vencimento <=',$f['data_fim']);
        $this->db->order_by('l.vencimento','ASC');
        return $this->db->get()->result();
    }

    public function get_resumo_bpo(array $f = [])
    {
        $where = '1=1';
        if (!empty($f['client_id'])) $where .= " AND l.client_id=".(int)$f['client_id'];
        if (!empty($f['data_ini']))  $where .= " AND l.vencimento>='".$this->db->escape_str($f['data_ini'])."'";
        if (!empty($f['data_fim']))  $where .= " AND l.vencimento<='".$this->db->escape_str($f['data_fim'])."'";
        $sql = "SELECT u.id AS client_id, u.name AS client_nome,
            SUM(CASE WHEN l.tipo='receber' THEN l.valor ELSE 0 END) AS total_receber,
            SUM(CASE WHEN l.tipo='pagar' THEN l.valor ELSE 0 END) AS total_pagar,
            SUM(CASE WHEN l.tipo='receber' AND l.status='pago' THEN l.valor ELSE 0 END) AS total_recebido,
            SUM(CASE WHEN l.tipo='receber' AND l.status='pendente' THEN l.valor ELSE 0 END) AS total_pendente,
            SUM(CASE WHEN l.tipo='receber' AND l.status='pendente' AND l.vencimento < CURDATE() THEN l.valor ELSE 0 END) AS total_vencido
            FROM fin_lancamentos l INNER JOIN users u ON u.id=l.client_id WHERE {$where}
            GROUP BY u.id ORDER BY total_vencido DESC";
        return $this->db->query($sql)->result();
    }

    public function get_alertas_bpo()
    {
        $this->db->select('l.*, u.name AS client_nome, c.case_no');
        $this->db->from('fin_lancamentos l');
        $this->db->join('users u','u.id=l.client_id','left');
        $this->db->join('cases c','c.id=l.case_id','left');
        $this->db->where('l.tipo','receber');
        $this->db->where('l.status','pendente');
        $this->db->where('l.vencimento <', date('Y-m-d'));
        $this->db->order_by('l.vencimento','ASC');
        return $this->db->get()->result();
    }

    public function get_honorarios_cliente($client_id)
    {
        $this->db->from('fin_lancamentos')->where('client_id',$client_id);
        $this->db->order_by('created_at','DESC');
        return $this->db->get()->result();
    }

    public function get_relatorio_bpo($data_ini, $data_fim)
    {
        $wi = $data_ini ? "AND (l.vencimento >= '".$this->db->escape_str($data_ini)."' OR l.id IS NULL)" : '';
        $wf = $data_fim ? "AND (l.vencimento <= '".$this->db->escape_str($data_fim)."' OR l.id IS NULL)" : '';
        $sql = "SELECT u.name AS cliente, COUNT(DISTINCT c.id) AS total_processos,
            SUM(CASE WHEN l.tipo='receber' THEN l.valor ELSE 0 END) AS honorarios_total,
            SUM(CASE WHEN l.tipo='receber' AND l.status='pago' THEN l.valor ELSE 0 END) AS honorarios_recebidos,
            SUM(CASE WHEN l.tipo='receber' AND l.status='pendente' THEN l.valor ELSE 0 END) AS honorarios_pendentes,
            SUM(CASE WHEN l.tipo='receber' AND l.status='pendente' AND l.vencimento < CURDATE() THEN l.valor ELSE 0 END) AS honorarios_vencidos
            FROM users u
            LEFT JOIN fin_lancamentos l ON l.client_id=u.id {$wi} {$wf}
            LEFT JOIN cases c ON c.client_id=u.id AND c.is_archived=0
            WHERE u.user_role=2 GROUP BY u.id ORDER BY honorarios_vencidos DESC";
        return $this->db->query($sql)->result();
    }

    // ── RECIBOS / COMISSÕES / PROLABORE ──────────────────────
    public function get_recibos()
    {
        $this->db->select('r.*, l.client_id, l.valor AS valor_lancamento');
        $this->db->from('fin_recibos r');
        $this->db->join('fin_lancamentos l','l.id = r.lancamento_id','left');
        $this->db->order_by('r.created_at','DESC');
        return $this->db->get()->result();
    }

    public function get_comissoes()
    {
        $this->db->select('c.*, e.name AS advogado, l.descricao, l.valor AS valor_lancamento, l.client_id');
        $this->db->from('fin_comissoes c');
        $this->db->join('users e','e.id = c.advogado_id','left');
        $this->db->join('fin_lancamentos l','l.id = c.lancamento_id','left');
        $this->db->order_by('c.id','DESC');
        return $this->db->get()->result();
    }

    public function add_comissao(array $data)
    {
        $this->db->insert('fin_comissoes', $data);
        return $this->db->insert_id();
    }

    public function get_prolabore()
    {
        $this->db->where("subcategoria IN ('prolabore','lucro')");
        $this->db->order_by('vencimento','DESC');
        return $this->db->get('fin_lancamentos')->result();
    }
}
