<?php

declare(strict_types=1);

namespace App\Models;

use PDO;

class ArquivoFiscal
{
    private PDO $db;

    public function __construct(PDO $db)
    {
        $this->db = $db;
    }

    /**
     * Lista arquivos fiscais com filtros (busca da tabela vendas)
     */
    public function listar(array $filtros = []): array
    {
        $query = "SELECT
                    v.id,
                    v.company_id as empresa_id,
                    e.razao_social as empresa_nome,
                    COALESCE(v.numero_nfe, v.sale_number) as numero_documento,
                    v.sale_date as data_emissao,
                    v.total as valor_total,
                    v.status,
                    v.customer_name as destinatario_nome,
                    v.customer_document as destinatario_cnpj,
                    'NFe' as tipo_documento,
                    'saida' as tipo_operacao,
                    v.chave_nfe as chave_acesso,
                    v.protocolo_nfe as protocolo,
                    v.data_cancelamento,
                    CASE
                        WHEN v.data_cancelamento IS NOT NULL AND v.data_cancelamento != '0000-00-00' THEN 'cancelada'
                        WHEN v.chave_nfe IS NOT NULL AND v.chave_nfe != '' THEN 'emitida'
                        ELSE 'pendente'
                    END as status_nfe
                  FROM vendas v
                  INNER JOIN empresas e ON v.company_id = e.id
                  WHERE v.status != 'orcamento'";

        $params = [];

        if (!empty($filtros['empresa_id'])) {
            $query .= " AND v.company_id = :empresa_id";
            $params['empresa_id'] = $filtros['empresa_id'];
        }

        // Tipo de documento - por enquanto só vendas (NFe)
        if (!empty($filtros['tipo_documento'])) {
            // Ignora filtro por enquanto, todas são NFe
        }

        if (!empty($filtros['status'])) {
            if ($filtros['status'] === 'emitida') {
                // Vendas com NF-e emitida (chave preenchida) e não canceladas
                $query .= " AND v.chave_nfe IS NOT NULL AND v.chave_nfe != '' AND (v.data_cancelamento IS NULL OR v.data_cancelamento = '0000-00-00')";
            } elseif ($filtros['status'] === 'cancelada') {
                // Vendas com NF-e cancelada
                $query .= " AND v.data_cancelamento IS NOT NULL AND v.data_cancelamento != '0000-00-00'";
            }
        }

        // Tipo de operação - todas as vendas são saída
        if (!empty($filtros['tipo_operacao']) && $filtros['tipo_operacao'] != 'saida') {
            // Se filtrar por entrada, não retorna nada
            $query .= " AND 1=0";
        }

        if (!empty($filtros['mes']) && !empty($filtros['ano'])) {
            // Converte mes e ano separados para range de datas
            $dataInicial = $filtros['ano'] . '-' . $filtros['mes'] . '-01';
            $dataFinal = date('Y-m-t', strtotime($dataInicial));

            $query .= " AND v.sale_date BETWEEN :data_inicial AND :data_final";
            $params['data_inicial'] = $dataInicial;
            $params['data_final'] = $dataFinal;
        } elseif (!empty($filtros['ano'])) {
            // Apenas ano selecionado
            $query .= " AND YEAR(v.sale_date) = :ano";
            $params['ano'] = $filtros['ano'];
        } elseif (!empty($filtros['mes'])) {
            // Apenas mês selecionado
            $query .= " AND MONTH(v.sale_date) = :mes";
            $params['mes'] = $filtros['mes'];
        }

        if (!empty($filtros['chave_acesso'])) {
            // Vendas não têm chave, mas mantém o filtro para não quebrar
            $query .= " AND 1=0";
        }

        $query .= " ORDER BY v.sale_date DESC, v.id DESC";

        $stmt = $this->db->prepare($query);
        $stmt->execute($params);

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    /**
     * Busca arquivo por ID (busca da tabela vendas)
     */
    public function buscarPorId(int $id): ?array
    {
        $stmt = $this->db->prepare("
            SELECT
                v.id,
                v.company_id as empresa_id,
                e.razao_social as empresa_nome,
                COALESCE(v.numero_nfe, v.sale_number) as numero_documento,
                v.sale_date as data_emissao,
                v.total as valor_total,
                v.status,
                v.customer_name as destinatario_nome,
                v.customer_document as destinatario_cnpj,
                'NFe' as tipo_documento,
                'saida' as tipo_operacao,
                v.chave_nfe as chave_acesso,
                v.protocolo_nfe as protocolo
            FROM vendas v
            INNER JOIN empresas e ON v.company_id = e.id
            WHERE v.id = :id
        ");
        $stmt->execute(['id' => $id]);

        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        return $result ?: null;
    }

    /**
     * Busca arquivo por chave de acesso
     */
    public function buscarPorChave(string $chave): ?array
    {
        $stmt = $this->db->prepare("SELECT * FROM arquivos_fiscais WHERE chave_acesso = :chave");
        $stmt->execute(['chave' => $chave]);

        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        return $result ?: null;
    }

    /**
     * Cria novo arquivo fiscal
     */
    public function criar(array $dados): int
    {
        $stmt = $this->db->prepare("
            INSERT INTO arquivos_fiscais (
                empresa_id, tipo_documento, chave_acesso, numero_documento, serie,
                data_emissao, data_recebimento, valor_total, status, tipo_operacao,
                destinatario_nome, destinatario_cnpj, xml_path, pdf_path, hash_xml, observacoes
            ) VALUES (
                :empresa_id, :tipo_documento, :chave_acesso, :numero_documento, :serie,
                :data_emissao, :data_recebimento, :valor_total, :status, :tipo_operacao,
                :destinatario_nome, :destinatario_cnpj, :xml_path, :pdf_path, :hash_xml, :observacoes
            )
        ");

        $stmt->execute($dados);
        return (int) $this->db->lastInsertId();
    }

    /**
     * Atualiza arquivo fiscal
     */
    public function atualizar(int $id, array $dados): bool
    {
        $campos = [];
        $params = ['id' => $id];

        foreach ($dados as $campo => $valor) {
            $campos[] = "$campo = :$campo";
            $params[$campo] = $valor;
        }

        $query = "UPDATE arquivos_fiscais SET " . implode(', ', $campos) . " WHERE id = :id";
        $stmt = $this->db->prepare($query);

        return $stmt->execute($params);
    }

    /**
     * Deleta arquivo fiscal
     */
    public function deletar(int $id): bool
    {
        $stmt = $this->db->prepare("DELETE FROM arquivos_fiscais WHERE id = :id");
        return $stmt->execute(['id' => $id]);
    }

    /**
     * Estatísticas por período
     */
    public function estatisticas(int $empresaId, string $dataInicial, string $dataFinal): array
    {
        $stmt = $this->db->prepare("
            SELECT
                tipo_documento,
                tipo_operacao,
                COUNT(*) as quantidade,
                SUM(valor_total) as valor_total,
                status
            FROM arquivos_fiscais
            WHERE empresa_id = :empresa_id
                AND data_emissao BETWEEN :data_inicial AND :data_final
            GROUP BY tipo_documento, tipo_operacao, status
        ");

        $stmt->execute([
            'empresa_id' => $empresaId,
            'data_inicial' => $dataInicial,
            'data_final' => $dataFinal
        ]);

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    /**
     * Verifica se XML já existe (por hash)
     */
    public function xmlExiste(string $hash): bool
    {
        $stmt = $this->db->prepare("SELECT COUNT(*) FROM arquivos_fiscais WHERE hash_xml = :hash");
        $stmt->execute(['hash' => $hash]);

        return $stmt->fetchColumn() > 0;
    }
}

