<?php

namespace App\Models;

use App\Core\Database;

class NFe
{
    private $db;

    public function __construct()
    {
        $this->db = Database::getInstance();
    }

    public function criar($dados)
    {
        $sql = "INSERT INTO nfes (
            empresa_id, cliente_id, numero, serie, chave_acesso, protocolo,
            data_emissao, data_saida, valor_total, valor_desconto, valor_frete,
            valor_seguro, valor_outros, valor_icms, valor_ipi, valor_pis,
            valor_cofins, status, xml_path, pdf_path, observacoes, justificativa_cancelamento,
            created_at, updated_at
        ) VALUES (
            :empresa_id, :cliente_id, :numero, :serie, :chave_acesso, :protocolo,
            :data_emissao, :data_saida, :valor_total, :valor_desconto, :valor_frete,
            :valor_seguro, :valor_outros, :valor_icms, :valor_ipi, :valor_pis,
            :valor_cofins, :status, :xml_path, :pdf_path, :observacoes, :justificativa_cancelamento,
            NOW(), NOW()
        )";

        $params = [
            ':empresa_id' => $dados['empresa_id'],
            ':cliente_id' => $dados['cliente_id'],
            ':numero' => $dados['numero'],
            ':serie' => $dados['serie'],
            ':chave_acesso' => $dados['chave_acesso'] ?? null,
            ':protocolo' => $dados['protocolo'] ?? null,
            ':data_emissao' => $dados['data_emissao'],
            ':data_saida' => $dados['data_saida'],
            ':valor_total' => $dados['valor_total'],
            ':valor_desconto' => $dados['valor_desconto'] ?? 0,
            ':valor_frete' => $dados['valor_frete'] ?? 0,
            ':valor_seguro' => $dados['valor_seguro'] ?? 0,
            ':valor_outros' => $dados['valor_outros'] ?? 0,
            ':valor_icms' => $dados['valor_icms'] ?? 0,
            ':valor_ipi' => $dados['valor_ipi'] ?? 0,
            ':valor_pis' => $dados['valor_pis'] ?? 0,
            ':valor_cofins' => $dados['valor_cofins'] ?? 0,
            ':status' => $dados['status'] ?? 'pendente',
            ':xml_path' => $dados['xml_path'] ?? null,
            ':pdf_path' => $dados['pdf_path'] ?? null,
            ':observacoes' => $dados['observacoes'] ?? null,
            ':justificativa_cancelamento' => $dados['justificativa_cancelamento'] ?? null
        ];

        $this->db->query($sql, $params);
        $nfe_id = $this->db->getConnection()->lastInsertId();

        // Salvar itens da NFe
        if (isset($dados['itens']) && is_array($dados['itens'])) {
            $this->salvarItens($nfe_id, $dados['itens']);
        }

        return $nfe_id;
    }

    private function salvarItens($nfe_id, $itens)
    {
        $sql = "INSERT INTO nfe_itens (
            nfe_id, produto_id, codigo, descricao, ncm, cfop, unidade_comercial,
            quantidade_comercial, valor_unitario, valor_total, valor_desconto,
            valor_frete, valor_seguro, valor_outros, valor_icms, valor_ipi,
            valor_pis, valor_cofins
        ) VALUES (
            :nfe_id, :produto_id, :codigo, :descricao, :ncm, :cfop, :unidade_comercial,
            :quantidade_comercial, :valor_unitario, :valor_total, :valor_desconto,
            :valor_frete, :valor_seguro, :valor_outros, :valor_icms, :valor_ipi,
            :valor_pis, :valor_cofins
        )";

        foreach ($itens as $item) {
            $params = [
                ':nfe_id' => $nfe_id,
                ':produto_id' => $item['produto_id'] ?? null,
                ':codigo' => $item['codigo'],
                ':descricao' => $item['descricao'],
                ':ncm' => $item['ncm'],
                ':cfop' => $item['cfop'],
                ':unidade_comercial' => $item['unidade_comercial'],
                ':quantidade_comercial' => $item['quantidade_comercial'],
                ':valor_unitario' => $item['valor_unitario'],
                ':valor_total' => $item['valor_total'],
                ':valor_desconto' => $item['valor_desconto'] ?? 0,
                ':valor_frete' => $item['valor_frete'] ?? 0,
                ':valor_seguro' => $item['valor_seguro'] ?? 0,
                ':valor_outros' => $item['valor_outros'] ?? 0,
                ':valor_icms' => $item['valor_icms'] ?? 0,
                ':valor_ipi' => $item['valor_ipi'] ?? 0,
                ':valor_pis' => $item['valor_pis'] ?? 0,
                ':valor_cofins' => $item['valor_cofins'] ?? 0
            ];

            $this->db->query($sql, $params);
        }
    }

    public function buscar($id)
    {
        $sql = "SELECT n.*, e.nome as empresa_nome, e.cnpj as empresa_cnpj,
                       c.nome as cliente_nome, c.cnpj as cliente_cnpj, c.cpf as cliente_cpf
                FROM nfes n
                LEFT JOIN empresas e ON n.empresa_id = e.id
                LEFT JOIN clientes c ON n.cliente_id = c.id
                WHERE n.id = :id";

        $stmt = $this->db->query($sql, [':id' => $id]);
        $nfe = $stmt->fetch();

        if ($nfe) {
            $nfe['itens'] = $this->buscarItens($id);
        }

        return $nfe;
    }

    private function buscarItens($nfe_id)
    {
        $sql = "SELECT * FROM nfe_itens WHERE nfe_id = :nfe_id ORDER BY id";
        $stmt = $this->db->query($sql, [':nfe_id' => $nfe_id]);
        return $stmt->fetchAll();
    }

    public function atualizar($id, $dados)
    {
        // Construir SQL dinamicamente baseado nas chaves fornecidas
        $campos = [];
        $params = [':id' => $id];

        foreach ($dados as $chave => $valor) {
            if (
                in_array($chave, [
                    'empresa_id',
                    'cliente_id',
                    'numero',
                    'serie',
                    'chave_acesso',
                    'protocolo',
                    'data_emissao',
                    'data_saida',
                    'valor_total',
                    'valor_desconto',
                    'valor_frete',
                    'valor_seguro',
                    'valor_outros',
                    'valor_icms',
                    'valor_ipi',
                    'valor_pis',
                    'valor_cofins',
                    'status',
                    'xml_path',
                    'pdf_path',
                    'observacoes',
                    'justificativa_cancelamento'
                ])
            ) {
                $campos[] = "{$chave} = :{$chave}";
                $params[":{$chave}"] = $valor;
            }
        }

        if (empty($campos)) {
            return false; // Nenhum campo válido para atualizar
        }

        $campos[] = "updated_at = NOW()";
        $sql = "UPDATE nfes SET " . implode(', ', $campos) . " WHERE id = :id";

        return $this->db->query($sql, $params);
    }

    public function listar($empresa_id = null)
    {
        if ($empresa_id) {
            $sql = "SELECT n.*, e.nome as empresa_nome, c.nome as cliente_nome
                    FROM nfes n
                    LEFT JOIN empresas e ON n.empresa_id = e.id
                    LEFT JOIN clientes c ON n.cliente_id = c.id
                    WHERE n.empresa_id = :empresa_id
                    ORDER BY n.data_emissao DESC";
            $stmt = $this->db->query($sql, [':empresa_id' => $empresa_id]);
        } else {
            $sql = "SELECT n.*, e.nome as empresa_nome, c.nome as cliente_nome
                    FROM nfes n
                    LEFT JOIN empresas e ON n.empresa_id = e.id
                    LEFT JOIN clientes c ON n.cliente_id = c.id
                    ORDER BY n.data_emissao DESC";
            $stmt = $this->db->query($sql);
        }

        return $stmt->fetchAll();
    }

    public function atualizarStatus($id, $status, $chave_acesso = null, $protocolo = null)
    {
        $sql = "UPDATE nfes SET
            status = :status, chave_acesso = :chave_acesso, protocolo = :protocolo,
            updated_at = NOW()
            WHERE id = :id";

        $params = [
            ':id' => $id,
            ':status' => $status,
            ':chave_acesso' => $chave_acesso,
            ':protocolo' => $protocolo
        ];

        return $this->db->query($sql, $params);
    }

    public function buscarPorNumero($numero, $serie, $empresa_id)
    {
        $sql = "SELECT * FROM nfes WHERE numero = :numero AND serie = :serie AND empresa_id = :empresa_id";
        $stmt = $this->db->query($sql, [
            ':numero' => $numero,
            ':serie' => $serie,
            ':empresa_id' => $empresa_id
        ]);
        return $stmt->fetch();
    }

    public function buscarPorChaveAcesso($chave_acesso)
    {
        $sql = "SELECT n.*, e.nome as empresa_nome, e.cnpj as empresa_cnpj,
                       c.nome as cliente_nome, c.cnpj as cliente_cnpj, c.cpf as cliente_cpf
                FROM nfes n
                LEFT JOIN empresas e ON n.empresa_id = e.id
                LEFT JOIN clientes c ON n.cliente_id = c.id
                WHERE n.chave_acesso = :chave_acesso";

        $stmt = $this->db->query($sql, [':chave_acesso' => $chave_acesso]);
        $nfe = $stmt->fetch();

        if ($nfe) {
            $nfe['itens'] = $this->buscarItens($nfe['id']);
        }

        return $nfe;
    }

    /**
     * Busca NFes autorizadas sem protocolo
     */
    public function buscarAutorizadasSemProtocolo()
    {
        $sql = "SELECT n.*, e.nome as empresa_nome, e.cnpj as empresa_cnpj
                FROM nfes n
                LEFT JOIN empresas e ON n.empresa_id = e.id
                WHERE n.status = 'autorizada'
                  AND (n.protocolo IS NULL OR n.protocolo = '')
                  AND n.chave_acesso IS NOT NULL
                ORDER BY n.created_at ASC";

        $stmt = $this->db->query($sql);
        return $stmt->fetchAll();
    }
}
