<?php
declare(strict_types=1);

require_once __DIR__ . '/auth.php';
require_once __DIR__ . '/conexao.php';
require_once __DIR__ . '/telecom_helpers.php';

date_default_timezone_set('America/Sao_Paulo');

if ($mysqli instanceof mysqli) {
    $mysqli->set_charset('utf8mb4');
}

if (session_status() !== PHP_SESSION_ACTIVE) {
    session_start();
}

$usuarioEhCynthia = telecomEhCynthia();
$usuarioTelecomAutorizado = telecomAcessoPermitido();

/*
|--------------------------------------------------------------------------
| Funções auxiliares
|--------------------------------------------------------------------------
*/

function e(mixed $valor): string
{
    return htmlspecialchars((string) $valor, ENT_QUOTES, 'UTF-8');
}

function normalizarModelo(string $modelo): string
{
    $modelo = trim($modelo);
    $modelo = preg_replace('/\s+/', ' ', $modelo) ?? $modelo;

    return mb_strtoupper($modelo, 'UTF-8');
}

function somenteCodigo(string $codigo): string
{
    return trim(preg_replace('/[^A-Za-z0-9\-_\.]/', '', $codigo) ?? '');
}

function definirFlash(string $tipo, string $mensagem): void
{
    $_SESSION['toner_flash'] = [
        'tipo' => $tipo,
        'mensagem' => $mensagem
    ];
}

function redirecionar(): never
{
    header('Location: tonner.php');
    exit;
}

function colunaExiste(mysqli $mysqli, string $tabela, string $coluna): bool
{
    $stmt = $mysqli->prepare("
        SELECT COUNT(*) AS total
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = DATABASE()
          AND TABLE_NAME = ?
          AND COLUMN_NAME = ?
    ");

    if (!$stmt) {
        return false;
    }

    $stmt->bind_param('ss', $tabela, $coluna);
    $stmt->execute();

    $resultado = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    return (int) ($resultado['total'] ?? 0) > 0;
}

function statusEstoque(int $quantidade, int $minimo): array
{
    if ($quantidade <= 0) {
        return [
            'codigo' => 'zerado',
            'rotulo' => 'Sem estoque',
            'icone' => 'bi-x-octagon-fill'
        ];
    }

    if ($quantidade <= $minimo) {
        return [
            'codigo' => 'critico',
            'rotulo' => 'Estoque crítico',
            'icone' => 'bi-exclamation-octagon-fill'
        ];
    }

    if ($quantidade <= ($minimo + 3)) {
        return [
            'codigo' => 'baixo',
            'rotulo' => 'Estoque baixo',
            'icone' => 'bi-exclamation-triangle-fill'
        ];
    }

    return [
        'codigo' => 'saudavel',
        'rotulo' => 'Estoque saudável',
        'icone' => 'bi-check-circle-fill'
    ];
}

/*
|--------------------------------------------------------------------------
| Estrutura do banco
|--------------------------------------------------------------------------
*/

$mysqli->query("
    CREATE TABLE IF NOT EXISTS tonner_estoque (
        modelo VARCHAR(100) PRIMARY KEY,
        quantidade INT NOT NULL DEFAULT 0,
        codigo_barras VARCHAR(120) NULL,
        estoque_minimo INT NOT NULL DEFAULT 2,
        atualizado_em TIMESTAMP NOT NULL
            DEFAULT CURRENT_TIMESTAMP
            ON UPDATE CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
");

if (!colunaExiste($mysqli, 'tonner_estoque', 'codigo_barras')) {
    $mysqli->query("
        ALTER TABLE tonner_estoque
        ADD COLUMN codigo_barras VARCHAR(120) NULL AFTER quantidade
    ");
}

if (!colunaExiste($mysqli, 'tonner_estoque', 'estoque_minimo')) {
    $mysqli->query("
        ALTER TABLE tonner_estoque
        ADD COLUMN estoque_minimo INT NOT NULL DEFAULT 2
        AFTER codigo_barras
    ");
}

if (!colunaExiste($mysqli, 'tonner_estoque', 'atualizado_em')) {
    $mysqli->query("
        ALTER TABLE tonner_estoque
        ADD COLUMN atualizado_em TIMESTAMP NOT NULL
        DEFAULT CURRENT_TIMESTAMP
        ON UPDATE CURRENT_TIMESTAMP
    ");
}

$mysqli->query("
    CREATE TABLE IF NOT EXISTS tonner_movimentacoes (
        id INT AUTO_INCREMENT PRIMARY KEY,
        modelo VARCHAR(100) NOT NULL,
        tipo ENUM('ENTRADA', 'SAIDA', 'AJUSTE') NOT NULL,
        quantidade INT NOT NULL,
        estoque_anterior INT NOT NULL DEFAULT 0,
        estoque_posterior INT NOT NULL DEFAULT 0,
        responsavel VARCHAR(150) NULL,
        responsavel_entrega VARCHAR(150) NULL,
        destino VARCHAR(180) NULL,
        observacao VARCHAR(255) NULL,
        usuario_sistema VARCHAR(120) NULL,
        criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_mov_modelo (modelo),
        INDEX idx_mov_tipo (tipo),
        INDEX idx_mov_data (criado_em)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
");

if (!colunaExiste(
    $mysqli,
    'tonner_movimentacoes',
    'responsavel_entrega'
)) {
    $mysqli->query("
        ALTER TABLE tonner_movimentacoes
        ADD COLUMN responsavel_entrega VARCHAR(150) NULL
        AFTER responsavel
    ");
}


/*
|--------------------------------------------------------------------------
| Lotes de saída — um comprovante para vários modelos
|--------------------------------------------------------------------------
*/

$mysqli->query("
    CREATE TABLE IF NOT EXISTS tonner_saida_lotes (
        id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        codigo VARCHAR(50) NOT NULL,
        responsavel_retirada VARCHAR(150) NOT NULL,
        responsavel_entrega VARCHAR(150) NOT NULL,
        destino VARCHAR(180) NOT NULL,
        observacao_geral VARCHAR(500) NULL,
        usuario_sistema VARCHAR(120) NOT NULL,
        criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
        UNIQUE KEY uk_tonner_saida_lote_codigo (codigo),
        INDEX idx_tonner_saida_lote_data (criado_em)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
");

if (!colunaExiste(
    $mysqli,
    'tonner_movimentacoes',
    'saida_lote_id'
)) {
    $mysqli->query("
        ALTER TABLE tonner_movimentacoes
        ADD COLUMN saida_lote_id BIGINT UNSIGNED NULL AFTER id
    ");

    $mysqli->query("
        ALTER TABLE tonner_movimentacoes
        ADD INDEX idx_tonner_mov_saida_lote (saida_lote_id)
    ");
}

$flash = $_SESSION['toner_flash'] ?? null;
unset($_SESSION['toner_flash']);

$usuarioLogado = trim((string) ($_SESSION['usuario'] ?? 'Servidor da TI'));

/*
|--------------------------------------------------------------------------
| Operações POST
|--------------------------------------------------------------------------
*/

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $acao = trim((string) ($_POST['acao'] ?? ''));

    /*
    |--------------------------------------------------------------------------
    | Entrada de estoque
    |--------------------------------------------------------------------------
    */
    if ($acao === 'entrada') {
        $modelo = normalizarModelo((string) ($_POST['modelo'] ?? ''));
        $quantidade = max(0, (int) ($_POST['quantidade'] ?? 0));
        $codigoBarras = somenteCodigo((string) ($_POST['codigo_barras'] ?? ''));
        $estoqueMinimo = max(0, (int) ($_POST['estoque_minimo'] ?? 2));
        $origem = trim((string) ($_POST['origem'] ?? ''));
        $observacao = trim((string) ($_POST['observacao'] ?? ''));

        $imprimirComprovante =
            isset($_POST['imprimir_comprovante']) &&
            (string) $_POST['imprimir_comprovante'] === '1';

        if ($modelo === '' || $quantidade <= 0) {
            definirFlash(
                'erro',
                'Informe o modelo e uma quantidade válida para registrar a entrada.'
            );

            redirecionar();
        }

        try {
            $mysqli->begin_transaction();

            $stmt = $mysqli->prepare("
                SELECT quantidade
                FROM tonner_estoque
                WHERE modelo = ?
                FOR UPDATE
            ");

            if (!$stmt) {
                throw new RuntimeException('Falha ao preparar consulta.');
            }

            $stmt->bind_param('s', $modelo);
            $stmt->execute();

            $registro = $stmt->get_result()->fetch_assoc();
            $stmt->close();

            $estoqueAnterior = (int) ($registro['quantidade'] ?? 0);
            $estoquePosterior = $estoqueAnterior + $quantidade;

            if ($registro) {
                $stmt = $mysqli->prepare("
                    UPDATE tonner_estoque
                    SET quantidade = ?,
                        codigo_barras = CASE
                            WHEN ? <> '' THEN ?
                            ELSE codigo_barras
                        END,
                        estoque_minimo = ?
                    WHERE modelo = ?
                ");

                if (!$stmt) {
                    throw new RuntimeException('Falha ao atualizar o estoque.');
                }

                $stmt->bind_param(
                    'issis',
                    $estoquePosterior,
                    $codigoBarras,
                    $codigoBarras,
                    $estoqueMinimo,
                    $modelo
                );
            } else {
                $stmt = $mysqli->prepare("
                    INSERT INTO tonner_estoque (
                        modelo,
                        quantidade,
                        codigo_barras,
                        estoque_minimo
                    )
                    VALUES (?, ?, NULLIF(?, ''), ?)
                ");

                if (!$stmt) {
                    throw new RuntimeException('Falha ao cadastrar o modelo.');
                }

                $stmt->bind_param(
                    'sisi',
                    $modelo,
                    $estoquePosterior,
                    $codigoBarras,
                    $estoqueMinimo
                );
            }

            $stmt->execute();
            $stmt->close();

            $tipo = 'ENTRADA';

            $stmt = $mysqli->prepare("
                INSERT INTO tonner_movimentacoes (
                    modelo,
                    tipo,
                    quantidade,
                    estoque_anterior,
                    estoque_posterior,
                    responsavel,
                    responsavel_entrega,
                    destino,
                    observacao,
                    usuario_sistema
                )
                VALUES (?, ?, ?, ?, ?, ?, ?, NULLIF(?, ''), NULLIF(?, ''), ?)
            ");

            if (!$stmt) {
                throw new RuntimeException('Falha ao registrar movimentação.');
            }

            $stmt->bind_param(
                'ssiiisssss',
                $modelo,
                $tipo,
                $quantidade,
                $estoqueAnterior,
                $estoquePosterior,
                $usuarioLogado,
                $usuarioLogado,
                $origem,
                $observacao,
                $usuarioLogado
            );

            $stmt->execute();
            $movimentacaoId = (int) $stmt->insert_id;
            $stmt->close();

            $mysqli->commit();

            if ($imprimirComprovante && $movimentacaoId > 0) {
                header(
                    'Location: comprovante_tonner.php?id=' .
                    $movimentacaoId .
                    '&print=1'
                );
                exit;
            }

            definirFlash(
                'sucesso',
                "Entrada de {$quantidade} unidade(s) do modelo {$modelo} registrada."
            );
        } catch (Throwable $erro) {
            $mysqli->rollback();

            definirFlash(
                'erro',
                'Não foi possível registrar a entrada no estoque.'
            );
        }

        redirecionar();
    }

    /*
    |--------------------------------------------------------------------------
    | Saída de estoque
    |--------------------------------------------------------------------------
    */
    if ($acao === 'saida') {
        $modelosRecebidos = $_POST['itens_modelo'] ?? [];
        $quantidadesRecebidas = $_POST['itens_quantidade'] ?? [];
        $observacoesRecebidas = $_POST['itens_observacao'] ?? [];

        /* Compatibilidade com o formulário antigo. */
        if (!is_array($modelosRecebidos)) {
            $modelosRecebidos = [$modelosRecebidos];
        }

        if (!is_array($quantidadesRecebidas)) {
            $quantidadesRecebidas = [$quantidadesRecebidas];
        }

        if (!is_array($observacoesRecebidas)) {
            $observacoesRecebidas = [$observacoesRecebidas];
        }

        if (empty($modelosRecebidos) && isset($_POST['modelo'])) {
            $modelosRecebidos = [(string) $_POST['modelo']];
            $quantidadesRecebidas = [
                (int) ($_POST['quantidade'] ?? 0)
            ];
            $observacoesRecebidas = [
                (string) ($_POST['observacao'] ?? '')
            ];
        }

        $responsavelRetirada = trim(
            (string) ($_POST['responsavel_retirada'] ?? '')
        );

        $responsavelEntrega = trim(
            (string) ($_POST['responsavel_entrega'] ?? '')
        );

        $local = trim((string) ($_POST['local'] ?? ''));
        $itens = [];

        foreach ($modelosRecebidos as $indice => $modeloRecebido) {
            $modelo = normalizarModelo((string) $modeloRecebido);
            $quantidade = max(
                0,
                (int) ($quantidadesRecebidas[$indice] ?? 0)
            );
            $observacaoItem = trim(
                (string) ($observacoesRecebidas[$indice] ?? '')
            );

            if ($modelo === '' && $quantidade === 0) {
                continue;
            }

            if ($modelo === '' || $quantidade <= 0) {
                definirFlash(
                    'erro',
                    'Revise os modelos e as quantidades informadas.'
                );
                redirecionar();
            }

            /*
             * Se o mesmo modelo for adicionado mais de uma vez, o sistema
             * soma as quantidades e mantém um único item no comprovante.
             */
            if (!isset($itens[$modelo])) {
                $itens[$modelo] = [
                    'modelo' => $modelo,
                    'quantidade' => 0,
                    'observacoes' => []
                ];
            }

            $itens[$modelo]['quantidade'] += $quantidade;

            if (
                $observacaoItem !== '' &&
                !in_array(
                    $observacaoItem,
                    $itens[$modelo]['observacoes'],
                    true
                )
            ) {
                $itens[$modelo]['observacoes'][] = $observacaoItem;
            }
        }

        if (empty($itens)) {
            definirFlash(
                'erro',
                'Adicione pelo menos um modelo de toner para registrar a saída.'
            );
            redirecionar();
        }

        if (
            $responsavelRetirada === '' ||
            $responsavelEntrega === '' ||
            $local === ''
        ) {
            definirFlash(
                'erro',
                'Preencha os responsáveis e o local de destino.'
            );
            redirecionar();
        }

        ksort($itens, SORT_NATURAL | SORT_FLAG_CASE);

        try {
            $mysqli->begin_transaction();

            $codigoLote = sprintf(
                'TNS-%s-%04d',
                date('YmdHis'),
                random_int(1, 9999)
            );

            $stmt = $mysqli->prepare("
                INSERT INTO tonner_saida_lotes (
                    codigo,
                    responsavel_retirada,
                    responsavel_entrega,
                    destino,
                    usuario_sistema
                )
                VALUES (?, ?, ?, ?, ?)
            ");

            if (!$stmt) {
                throw new RuntimeException(
                    'Falha ao preparar o comprovante conjunto.'
                );
            }

            $stmt->bind_param(
                'sssss',
                $codigoLote,
                $responsavelRetirada,
                $responsavelEntrega,
                $local,
                $usuarioLogado
            );

            if (!$stmt->execute()) {
                throw new RuntimeException(
                    'Falha ao criar o comprovante conjunto.'
                );
            }

            $loteId = (int) $stmt->insert_id;
            $stmt->close();

            $totalUnidadesSaida = 0;
            $totalModelosSaida = 0;

            foreach ($itens as $item) {
                $modeloSolicitado = (string) $item['modelo'];
                $quantidade = (int) $item['quantidade'];
                $observacao = implode(
                    ' | ',
                    (array) $item['observacoes']
                );

                $stmt = $mysqli->prepare("
                    SELECT modelo, quantidade
                    FROM tonner_estoque
                    WHERE modelo = ?
                    LIMIT 1
                    FOR UPDATE
                ");

                if (!$stmt) {
                    throw new RuntimeException(
                        'Falha ao consultar o estoque.'
                    );
                }

                $stmt->bind_param('s', $modeloSolicitado);
                $stmt->execute();

                $registro = $stmt->get_result()->fetch_assoc();
                $stmt->close();

                if (!$registro) {
                    throw new DomainException(
                        "Modelo {$modeloSolicitado} não encontrado no estoque."
                    );
                }

                $modelo = (string) $registro['modelo'];
                $estoqueAnterior = (int) $registro['quantidade'];

                if ($estoqueAnterior < $quantidade) {
                    throw new DomainException(
                        "Estoque insuficiente para {$modelo}. " .
                        "Solicitado: {$quantidade}; disponível: " .
                        "{$estoqueAnterior}."
                    );
                }

                $estoquePosterior = $estoqueAnterior - $quantidade;

                $stmt = $mysqli->prepare("
                    UPDATE tonner_estoque
                    SET quantidade = ?
                    WHERE modelo = ?
                ");

                if (!$stmt) {
                    throw new RuntimeException(
                        'Falha ao atualizar o estoque.'
                    );
                }

                $stmt->bind_param(
                    'is',
                    $estoquePosterior,
                    $modelo
                );
                $stmt->execute();
                $stmt->close();

                /* Mantém o histórico legado utilizado pelos indicadores. */
                $stmt = $mysqli->prepare("
                    INSERT INTO tonner (
                        modelo,
                        responsavel_retirada,
                        responsavel_entrega,
                        local,
                        quantidade
                    )
                    VALUES (?, ?, ?, ?, ?)
                ");

                if (!$stmt) {
                    throw new RuntimeException(
                        'Falha ao registrar a saída no histórico.'
                    );
                }

                $stmt->bind_param(
                    'ssssi',
                    $modelo,
                    $responsavelRetirada,
                    $responsavelEntrega,
                    $local,
                    $quantidade
                );
                $stmt->execute();
                $stmt->close();

                $tipo = 'SAIDA';

                $stmt = $mysqli->prepare("
                    INSERT INTO tonner_movimentacoes (
                        saida_lote_id,
                        modelo,
                        tipo,
                        quantidade,
                        estoque_anterior,
                        estoque_posterior,
                        responsavel,
                        responsavel_entrega,
                        destino,
                        observacao,
                        usuario_sistema
                    )
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULLIF(?, ''), ?)
                ");

                if (!$stmt) {
                    throw new RuntimeException(
                        'Falha ao registrar a movimentação.'
                    );
                }

                $stmt->bind_param(
                    'issiiisssss',
                    $loteId,
                    $modelo,
                    $tipo,
                    $quantidade,
                    $estoqueAnterior,
                    $estoquePosterior,
                    $responsavelRetirada,
                    $responsavelEntrega,
                    $local,
                    $observacao,
                    $usuarioLogado
                );

                if (!$stmt->execute()) {
                    throw new RuntimeException(
                        'Falha ao registrar um dos modelos.'
                    );
                }

                $stmt->close();

                $totalUnidadesSaida += $quantidade;
                $totalModelosSaida++;
            }

            $mysqli->commit();

            /*
             * O documento só é aberto depois da confirmação e reúne todos
             * os modelos da operação em um único comprovante.
             */
            header(
                'Location: comprovante_tonner.php?lote_id=' .
                $loteId .
                '&print=1'
            );
            exit;
        } catch (DomainException $erro) {
            $mysqli->rollback();
            definirFlash('erro', $erro->getMessage());
        } catch (Throwable $erro) {
            $mysqli->rollback();

            definirFlash(
                'erro',
                'Não foi possível registrar a saída. Nenhum item foi baixado.'
            );
        }

        redirecionar();
    }

    /*
    |--------------------------------------------------------------------------
    | Configurar modelo
    |--------------------------------------------------------------------------
    */
    if ($acao === 'configurar') {
        $modeloAtual = normalizarModelo(
            (string) ($_POST['modelo_atual'] ?? '')
        );

        $codigoBarras = somenteCodigo(
            (string) ($_POST['codigo_barras'] ?? '')
        );

        $estoqueMinimo = max(
            0,
            (int) ($_POST['estoque_minimo'] ?? 2)
        );

        if ($modeloAtual === '') {
            definirFlash('erro', 'Modelo inválido para configuração.');
            redirecionar();
        }

        $stmt = $mysqli->prepare("
            UPDATE tonner_estoque
            SET codigo_barras = NULLIF(?, ''),
                estoque_minimo = ?
            WHERE modelo = ?
        ");

        if ($stmt) {
            $stmt->bind_param(
                'sis',
                $codigoBarras,
                $estoqueMinimo,
                $modeloAtual
            );

            $stmt->execute();
            $stmt->close();

            definirFlash(
                'sucesso',
                "Configuração do modelo {$modeloAtual} atualizada."
            );
        } else {
            definirFlash('erro', 'Não foi possível atualizar o modelo.');
        }

        redirecionar();
    }
}

/*
|--------------------------------------------------------------------------
| Dados do estoque
|--------------------------------------------------------------------------
*/

$estoque = [];

$resultadoEstoque = $mysqli->query("
    SELECT
        modelo,
        quantidade,
        codigo_barras,
        estoque_minimo,
        atualizado_em
    FROM tonner_estoque
    ORDER BY quantidade ASC, modelo ASC
");

if ($resultadoEstoque) {
    while ($registro = $resultadoEstoque->fetch_assoc()) {
        $estoque[] = [
            'modelo' => (string) $registro['modelo'],
            'quantidade' => (int) $registro['quantidade'],
            'codigo_barras' => (string) ($registro['codigo_barras'] ?? ''),
            'estoque_minimo' => (int) ($registro['estoque_minimo'] ?? 2),
            'atualizado_em' => (string) ($registro['atualizado_em'] ?? '')
        ];
    }

    $resultadoEstoque->free();
}

/*
|--------------------------------------------------------------------------
| Histórico de saídas
|--------------------------------------------------------------------------
*/

$saidas = [];

$resultadoSaidas = $mysqli->query("
    SELECT
        m.id,
        m.saida_lote_id,
        l.codigo AS lote_codigo,
        m.modelo,
        m.responsavel AS responsavel_retirada,
        COALESCE(
            NULLIF(m.responsavel_entrega, ''),
            m.usuario_sistema
        ) AS responsavel_entrega,
        m.destino AS local,
        m.quantidade,
        m.observacao,
        m.criado_em AS data_saida
    FROM tonner_movimentacoes AS m
    LEFT JOIN tonner_saida_lotes AS l
      ON l.id = m.saida_lote_id
    WHERE m.tipo = 'SAIDA'
    ORDER BY m.criado_em DESC, m.id DESC
");

if ($resultadoSaidas) {
    $saidas = $resultadoSaidas->fetch_all(MYSQLI_ASSOC);
    $resultadoSaidas->free();
}

/*
|--------------------------------------------------------------------------
| Consumo dos últimos 30 dias por modelo
|--------------------------------------------------------------------------
*/

$consumo30Dias = [];

$resultadoConsumo = $mysqli->query("
    SELECT
        modelo,
        COALESCE(SUM(quantidade), 0) AS total
    FROM tonner
    WHERE data_saida >= DATE_SUB(NOW(), INTERVAL 30 DAY)
    GROUP BY modelo
");

if ($resultadoConsumo) {
    while ($registro = $resultadoConsumo->fetch_assoc()) {
        $consumo30Dias[(string) $registro['modelo']] =
            (int) $registro['total'];
    }

    $resultadoConsumo->free();
}

/*
|--------------------------------------------------------------------------
| Indicadores
|--------------------------------------------------------------------------
*/

$totalModelos = count($estoque);
$totalUnidades = 0;
$totalCriticos = 0;
$totalBaixos = 0;
$totalZerados = 0;
$saidasHoje = 0;
$saidasMes = 0;
$consumoTotal30 = array_sum($consumo30Dias);

foreach ($estoque as $item) {
    $totalUnidades += $item['quantidade'];

    $status = statusEstoque(
        $item['quantidade'],
        $item['estoque_minimo']
    );

    if ($status['codigo'] === 'zerado') {
        $totalZerados++;
    } elseif ($status['codigo'] === 'critico') {
        $totalCriticos++;
    } elseif ($status['codigo'] === 'baixo') {
        $totalBaixos++;
    }
}

foreach ($saidas as $saida) {
    $timestamp = strtotime((string) ($saida['data_saida'] ?? ''));

    if ($timestamp === false) {
        continue;
    }

    if (date('Y-m-d', $timestamp) === date('Y-m-d')) {
        $saidasHoje += (int) ($saida['quantidade'] ?? 0);
    }

    if (date('Y-m', $timestamp) === date('Y-m')) {
        $saidasMes += (int) ($saida['quantidade'] ?? 0);
    }
}

$mediaDiaria = $consumoTotal30 > 0
    ? $consumoTotal30 / 30
    : 0;

$coberturaEstimada = $mediaDiaria > 0
    ? (int) floor($totalUnidades / $mediaDiaria)
    : null;

$modelosJson = json_encode(
    array_map(
        static fn(array $item): array => [
            'modelo' => $item['modelo'],
            'quantidade' => $item['quantidade'],
            'codigo_barras' => $item['codigo_barras'],
            'estoque_minimo' => $item['estoque_minimo']
        ],
        $estoque
    ),
    JSON_UNESCAPED_UNICODE |
    JSON_UNESCAPED_SLASHES |
    JSON_HEX_TAG |
    JSON_HEX_APOS |
    JSON_HEX_QUOT |
    JSON_HEX_AMP
);

$hora = (int) date('H');

$saudacao = match (true) {
    $hora >= 5 && $hora < 12 => 'Bom dia',
    $hora >= 12 && $hora < 18 => 'Boa tarde',
    default => 'Boa noite'
};
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">

    <meta
        name="viewport"
        content="width=device-width, initial-scale=1, viewport-fit=cover"
    >

    <meta
        name="description"
        content="Controle inteligente do estoque de toner da Gerência de Tecnologia."
    >

    <meta name="theme-color" content="#08396f">

    <title>Estoque de Toner | Manutenção TI</title>

    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

    <link
        href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap"
        rel="stylesheet"
    >

    <link
        href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
        rel="stylesheet"
    >

    <link
        href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
        rel="stylesheet"
    >

    <style>
        :root {
            --primary: #08396f;
            --primary-dark: #05294f;
            --primary-light: #145b9f;

            --green: #087f5b;
            --green-light: #e8f8f1;

            --yellow: #d17a00;
            --yellow-light: #fff7e6;

            --red: #bd263d;
            --red-dark: #8d182b;
            --red-light: #fff0f3;

            --blue-light: #eaf4fc;

            --background: #edf3f8;
            --surface: #ffffff;
            --surface-soft: #f6f9fc;

            --text: #152236;
            --text-soft: #617086;
            --text-light: #8795a8;

            --border: #dce5ee;
            --border-soft: #e9eff5;

            --shadow-sm: 0 10px 28px rgba(8, 57, 111, 0.06);
            --shadow-md: 0 22px 58px rgba(8, 57, 111, 0.11);
            --shadow-lg: 0 36px 95px rgba(5, 41, 79, 0.18);

            --radius-sm: 14px;
            --radius-md: 22px;
            --radius-lg: 30px;
        }

        * {
            box-sizing: border-box;
        }

        html {
            min-height: 100%;
            scroll-behavior: smooth;
        }

        body {
            margin: 0;
            min-height: 100vh;

            overflow-x: hidden;

            font-family:
                "Inter",
                system-ui,
                -apple-system,
                BlinkMacSystemFont,
                "Segoe UI",
                sans-serif;

            color: var(--text);

            background:
                radial-gradient(
                    circle at 7% 5%,
                    rgba(20, 91, 159, 0.13),
                    transparent 28rem
                ),
                radial-gradient(
                    circle at 96% 90%,
                    rgba(8, 127, 91, 0.09),
                    transparent 30rem
                ),
                linear-gradient(
                    145deg,
                    #f7fafc,
                    var(--background) 55%,
                    #e8f0f6
                );
        }

        button,
        input,
        select,
        textarea {
            font: inherit;
        }

        a {
            text-decoration: none;
        }

        .top-strip {
            position: fixed;
            top: 0;
            right: 0;
            left: 0;
            z-index: 1100;

            height: 6px;

            background: linear-gradient(
                90deg,
                var(--primary) 0 58%,
                var(--green) 58% 88%,
                #e8ad16 88% 100%
            );
        }

        .background-grid {
            position: fixed;
            inset: 0;
            z-index: 0;

            pointer-events: none;

            background-image:
                linear-gradient(
                    rgba(8, 57, 111, 0.026) 1px,
                    transparent 1px
                ),
                linear-gradient(
                    90deg,
                    rgba(8, 57, 111, 0.026) 1px,
                    transparent 1px
                );

            background-size: 54px 54px;

            mask-image: linear-gradient(
                to bottom,
                #000,
                transparent 94%
            );
        }

        .background-orb {
            position: fixed;
            z-index: 0;

            border-radius: 50%;
            pointer-events: none;

            animation: orbFloat 10s ease-in-out infinite;
        }

        .orb-one {
            top: -210px;
            left: -150px;

            width: 430px;
            height: 430px;

            border: 1px solid rgba(20, 91, 159, 0.09);

            background:
                radial-gradient(
                    circle at 68% 70%,
                    rgba(20, 91, 159, 0.12),
                    transparent 64%
                );
        }

        .orb-two {
            right: -240px;
            bottom: -240px;

            width: 540px;
            height: 540px;

            border: 1px solid rgba(8, 127, 91, 0.08);

            background:
                radial-gradient(
                    circle at 30% 28%,
                    rgba(8, 127, 91, 0.1),
                    transparent 63%
                );

            animation-delay: 2s;
        }

        @keyframes orbFloat {
            0%,
            100% {
                transform: translate3d(0, 0, 0);
            }

            50% {
                transform: translate3d(0, -18px, 0);
            }
        }

        .app {
            position: relative;
            z-index: 2;

            padding-top: 6px;
        }

        /*
        |--------------------------------------------------------------------------
        | Cabeçalho
        |--------------------------------------------------------------------------
        */

        .main-header {
            position: relative;

            overflow: hidden;

            margin: 19px 19px 0;
            padding: 20px 22px;

            border: 1px solid rgba(255, 255, 255, 0.18);
            border-radius: 27px;

            color: #ffffff;

            background:
                radial-gradient(
                    circle at 82% 0,
                    rgba(255, 255, 255, 0.12),
                    transparent 22rem
                ),
                radial-gradient(
                    circle at 0 100%,
                    rgba(8, 127, 91, 0.25),
                    transparent 24rem
                ),
                linear-gradient(
                    135deg,
                    var(--primary-dark),
                    var(--primary) 56%,
                    #07537c
                );

            box-shadow:
                var(--shadow-lg),
                inset 0 1px 0 rgba(255, 255, 255, 0.12);
        }

        .main-header::before {
            content: "";
            position: absolute;

            top: -205px;
            right: -110px;

            width: 420px;
            height: 420px;

            border: 40px solid rgba(255, 255, 255, 0.035);
            border-radius: 50%;

            box-shadow:
                0 0 0 42px rgba(255, 255, 255, 0.018),
                0 0 0 84px rgba(255, 255, 255, 0.012);

            animation: headerCircle 30s linear infinite;
        }

        @keyframes headerCircle {
            to {
                transform: rotate(360deg);
            }
        }

        .header-content {
            position: relative;
            z-index: 2;

            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 24px;
        }

        .brand-area {
            min-width: 0;

            display: flex;
            align-items: center;
            gap: 15px;
        }

        .logo-box {
            width: 70px;
            height: 70px;
            flex: 0 0 70px;

            display: grid;
            place-items: center;

            padding: 5px;

            border-radius: 21px;

            background: linear-gradient(
                145deg,
                #ffffff,
                #dceaf5
            );

            box-shadow: 0 18px 36px rgba(0, 0, 0, 0.18);

            animation: logoFloat 6s ease-in-out infinite;
        }

        .logo-inner {
            width: 100%;
            height: 100%;

            display: grid;
            place-items: center;

            overflow: hidden;

            border: 1px solid rgba(8, 57, 111, 0.08);
            border-radius: 17px;

            background: #ffffff;
        }

        .logo-inner img {
            max-width: 56px;
            max-height: 56px;

            object-fit: contain;
        }

        .logo-fallback {
            display: none;

            width: 100%;
            height: 100%;

            place-items: center;

            color: var(--primary);
            background: #f0f6fa;

            font-size: 28px;
        }

        @keyframes logoFloat {
            0%,
            100% {
                transform:
                    perspective(700px)
                    translateY(0)
                    rotateX(4deg)
                    rotateY(-5deg);
            }

            50% {
                transform:
                    perspective(700px)
                    translateY(-5px)
                    rotateX(0)
                    rotateY(3deg);
            }
        }

        .government-label {
            display: inline-flex;
            align-items: center;
            gap: 7px;

            margin-bottom: 7px;
            padding: 6px 10px;

            border: 1px solid rgba(255, 255, 255, 0.15);
            border-radius: 999px;

            color: rgba(255, 255, 255, 0.84);
            background: rgba(255, 255, 255, 0.08);

            font-size: 9px;
            font-weight: 800;
            letter-spacing: 0.65px;
            text-transform: uppercase;
        }

        .government-label i {
            color: #9cebd2;
        }

        .header-title {
            margin: 0;

            font-size: clamp(22px, 2.4vw, 34px);
            line-height: 1.04;
            letter-spacing: -1px;
            font-weight: 900;
        }

        .header-subtitle {
            margin: 7px 0 0;

            color: rgba(255, 255, 255, 0.68);

            font-size: 11px;
            line-height: 1.55;
            font-weight: 500;
        }

        .header-side {
            min-width: 430px;

            display: flex;
            flex-direction: column;
            align-items: flex-end;
            gap: 12px;
        }

        .user-line {
            display: flex;
            align-items: center;
            gap: 10px;

            text-align: right;
        }

        .user-line strong {
            display: block;

            font-size: 11px;
            font-weight: 800;
        }

        .user-line span {
            display: block;
            margin-top: 3px;

            color: rgba(255, 255, 255, 0.6);

            font-size: 8px;
            font-weight: 600;
        }

        .user-avatar {
            width: 40px;
            height: 40px;
            flex: 0 0 40px;

            display: grid;
            place-items: center;

            border-radius: 13px;

            color: var(--primary-dark);
            background: linear-gradient(145deg, #ffffff, #dceaf5);

            font-size: 17px;
        }

        .header-actions {
            display: flex;
            justify-content: flex-end;
            gap: 7px;
            flex-wrap: wrap;
        }

        .header-button {
            min-height: 38px;

            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 7px;

            padding: 0 12px;

            border: 1px solid rgba(255, 255, 255, 0.15);
            border-radius: 13px;

            color: #ffffff;
            background: rgba(255, 255, 255, 0.08);

            font-size: 9px;
            font-weight: 800;
            letter-spacing: 0.2px;
            text-transform: uppercase;

            transition:
                transform 0.2s ease,
                background 0.2s ease,
                box-shadow 0.2s ease;
        }

        .header-button:hover {
            color: #ffffff;
            background: rgba(255, 255, 255, 0.15);

            transform: translateY(-2px);

            box-shadow: 0 12px 24px rgba(0, 0, 0, 0.12);
        }

        .header-button-primary {
            color: var(--primary-dark);
            border-color: #ffffff;
            background: #ffffff;
        }

        .header-button-primary:hover {
            color: var(--primary-dark);
            background: #eef6fc;
        }

        /*
        |--------------------------------------------------------------------------
        | Conteúdo
        |--------------------------------------------------------------------------
        */

        .main-content {
            width: 100%;
            max-width: 1700px;

            margin: 0 auto;
            padding: 17px 19px 32px;
        }

        /*
        |--------------------------------------------------------------------------
        | Flash
        |--------------------------------------------------------------------------
        */

        .flash-message {
            display: flex;
            align-items: center;
            gap: 11px;

            margin-bottom: 14px;
            padding: 13px 15px;

            border: 1px solid var(--border);
            border-radius: 17px;

            background: #ffffff;

            box-shadow: var(--shadow-sm);

            font-size: 10px;
            font-weight: 700;
        }

        .flash-message.sucesso {
            color: #076448;
            border-color: #c3e9dc;
            background: var(--green-light);
        }

        .flash-message.erro {
            color: #932238;
            border-color: #efcbd2;
            background: var(--red-light);
        }

        .flash-icon {
            width: 35px;
            height: 35px;
            flex: 0 0 35px;

            display: grid;
            place-items: center;

            border-radius: 12px;

            color: #ffffff;
            background: var(--primary);

            font-size: 16px;
        }

        .flash-message.sucesso .flash-icon {
            background: var(--green);
        }

        .flash-message.erro .flash-icon {
            background: var(--red);
        }

        /*
        |--------------------------------------------------------------------------
        | Leitor de código de barras
        |--------------------------------------------------------------------------
        */

        .scanner-panel {
            position: relative;

            display: grid;
            grid-template-columns: minmax(0, 1.3fr) minmax(290px, 0.7fr);
            gap: 17px;

            overflow: hidden;

            padding: 22px;

            border: 1px solid rgba(255, 255, 255, 0.9);
            border-radius: var(--radius-lg);

            background: rgba(255, 255, 255, 0.84);

            backdrop-filter: blur(20px);

            box-shadow:
                var(--shadow-md),
                inset 0 1px 0 #ffffff;
        }

        .scanner-panel::after {
            content: "";
            position: absolute;

            right: -95px;
            bottom: -150px;

            width: 330px;
            height: 330px;

            border-radius: 50%;

            background:
                radial-gradient(
                    circle,
                    rgba(8, 127, 91, 0.08),
                    transparent 68%
                );

            pointer-events: none;
        }

        .scanner-label {
            display: inline-flex;
            align-items: center;
            gap: 7px;

            margin-bottom: 11px;

            color: var(--primary);

            font-size: 8px;
            font-weight: 850;
            letter-spacing: 0.65px;
            text-transform: uppercase;
        }

        .scanner-title {
            max-width: 760px;

            margin: 0;

            font-size: clamp(25px, 3vw, 41px);
            line-height: 1.04;
            letter-spacing: -1.65px;
            font-weight: 900;
        }

        .scanner-title span {
            color: var(--primary);
        }

        .scanner-description {
            max-width: 760px;

            margin: 12px 0 0;

            color: var(--text-soft);

            font-size: 10px;
            line-height: 1.65;
            font-weight: 500;
        }

        .scanner-input-box {
            position: relative;

            margin-top: 18px;
        }

        .scanner-input-box > i {
            position: absolute;
            top: 50%;
            left: 15px;

            color: var(--primary);

            font-size: 19px;

            transform: translateY(-50%);
        }

        .scanner-input {
            width: 100%;
            height: 58px;

            border: 2px solid #cddbe7;
            border-radius: 18px;
            outline: 0;

            color: var(--text);
            background: #ffffff;

            padding: 0 115px 0 46px;

            box-shadow: var(--shadow-sm);

            font-size: 13px;
            font-weight: 750;
            letter-spacing: 0.4px;

            transition:
                border-color 0.2s ease,
                box-shadow 0.2s ease,
                transform 0.2s ease;
        }

        .scanner-input:focus {
            border-color: var(--primary-light);

            box-shadow:
                0 0 0 5px rgba(20, 91, 159, 0.1),
                var(--shadow-sm);

            transform: translateY(-1px);
        }

        .scanner-ready {
            position: absolute;
            top: 50%;
            right: 10px;

            display: inline-flex;
            align-items: center;
            gap: 6px;

            padding: 7px 9px;

            border-radius: 999px;

            color: #086247;
            background: var(--green-light);

            font-size: 7px;
            font-weight: 850;
            letter-spacing: 0.35px;
            text-transform: uppercase;

            transform: translateY(-50%);
        }

        .scanner-dot {
            width: 7px;
            height: 7px;

            border-radius: 50%;

            background: var(--green);

            animation: scannerPulse 1.5s ease-in-out infinite;
        }

        @keyframes scannerPulse {
            50% {
                box-shadow: 0 0 0 7px rgba(8, 127, 91, 0);
            }

            0%,
            100% {
                box-shadow: 0 0 0 0 rgba(8, 127, 91, 0.22);
            }
        }

        .scanner-result {
            display: none;

            margin-top: 11px;
            padding: 12px 13px;

            border: 1px solid var(--border);
            border-radius: 14px;

            color: var(--text-soft);
            background: var(--surface-soft);

            font-size: 9px;
            line-height: 1.5;
            font-weight: 600;
        }

        .scanner-result.visible {
            display: block;
        }

        .scanner-result.success {
            color: #076448;
            border-color: #c3e9dc;
            background: var(--green-light);
        }

        .scanner-result.error {
            color: #922138;
            border-color: #edc7cf;
            background: var(--red-light);
        }

        .scanner-side-card {
            position: relative;
            z-index: 2;

            min-height: 215px;
            padding: 20px;

            display: flex;
            flex-direction: column;
            justify-content: space-between;

            border-radius: 24px;

            color: #ffffff;

            background:
                radial-gradient(
                    circle at 90% 10%,
                    rgba(255, 255, 255, 0.13),
                    transparent 12rem
                ),
                linear-gradient(
                    145deg,
                    var(--primary-dark),
                    var(--primary)
                );

            box-shadow: 0 22px 46px rgba(8, 57, 111, 0.2);

            transform: translateZ(20px);
        }

        .scanner-side-card strong {
            display: block;

            font-size: 43px;
            line-height: 1;
            letter-spacing: -1.5px;
            font-weight: 900;
        }

        .scanner-side-card h3 {
            margin: 10px 0 0;

            font-size: 13px;
            font-weight: 850;
        }

        .scanner-side-card p {
            margin: 6px 0 0;

            color: rgba(255, 255, 255, 0.65);

            font-size: 9px;
            line-height: 1.55;
        }

        .coverage-bar {
            height: 8px;

            overflow: hidden;

            margin-top: 17px;

            border-radius: 999px;

            background: rgba(255, 255, 255, 0.13);
        }

        .coverage-bar span {
            display: block;
            height: 100%;

            border-radius: inherit;

            background: linear-gradient(
                90deg,
                #91ebcf,
                #ffffff
            );
        }

        /*
        |--------------------------------------------------------------------------
        | KPIs
        |--------------------------------------------------------------------------
        */

        .kpi-grid {
            display: grid;
            grid-template-columns: repeat(6, minmax(0, 1fr));
            gap: 12px;

            margin-top: 14px;
        }

        .kpi-card {
            position: relative;

            min-height: 126px;
            padding: 16px;

            overflow: hidden;

            border: 1px solid var(--border);
            border-radius: 22px;

            background: rgba(255, 255, 255, 0.9);

            backdrop-filter: blur(15px);

            box-shadow:
                var(--shadow-sm),
                inset 0 1px 0 #ffffff;

            transform-style: preserve-3d;

            transition:
                transform 0.22s ease,
                box-shadow 0.22s ease,
                border-color 0.22s ease;
        }

        .kpi-card:hover {
            border-color: #c5d5e3;

            transform:
                translateY(-5px)
                perspective(800px)
                rotateX(2deg);

            box-shadow: var(--shadow-md);
        }

        .kpi-card::after {
            content: "";
            position: absolute;

            top: -52px;
            right: -52px;

            width: 122px;
            height: 122px;

            border-radius: 50%;

            background: rgba(20, 91, 159, 0.055);
        }

        .kpi-top {
            position: relative;
            z-index: 2;

            display: flex;
            justify-content: space-between;
            gap: 10px;
        }

        .kpi-icon {
            width: 40px;
            height: 40px;

            display: grid;
            place-items: center;

            border-radius: 13px;

            color: var(--primary);
            background: var(--blue-light);

            font-size: 17px;
        }

        .kpi-number {
            font-size: 30px;
            line-height: 1;
            letter-spacing: -1.2px;
            font-weight: 900;
        }

        .kpi-label {
            position: relative;
            z-index: 2;

            display: block;

            margin-top: 14px;

            color: var(--text-soft);

            font-size: 8px;
            font-weight: 850;
            letter-spacing: 0.55px;
            text-transform: uppercase;
        }

        .kpi-description {
            position: relative;
            z-index: 2;

            display: block;
            margin-top: 4px;

            color: var(--text-light);

            font-size: 7px;
            line-height: 1.45;
            font-weight: 550;
        }

        .kpi-green .kpi-icon {
            color: var(--green);
            background: var(--green-light);
        }

        .kpi-yellow .kpi-icon {
            color: var(--yellow);
            background: var(--yellow-light);
        }

        .kpi-red .kpi-icon {
            color: var(--red);
            background: var(--red-light);
        }

        /*
        |--------------------------------------------------------------------------
        | Layout principal
        |--------------------------------------------------------------------------
        */

        .management-grid {
            display: grid;
            grid-template-columns: minmax(340px, 0.62fr) minmax(0, 1.38fr);
            gap: 14px;

            margin-top: 14px;
        }

        .panel {
            overflow: hidden;

            border: 1px solid rgba(255, 255, 255, 0.9);
            border-radius: var(--radius-lg);

            background: rgba(255, 255, 255, 0.9);

            backdrop-filter: blur(18px);

            box-shadow:
                var(--shadow-md),
                inset 0 1px 0 #ffffff;
        }

        .panel-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 14px;

            padding: 18px 19px;

            border-bottom: 1px solid var(--border-soft);

            background:
                radial-gradient(
                    circle at 100% 0,
                    rgba(20, 91, 159, 0.06),
                    transparent 17rem
                ),
                linear-gradient(
                    180deg,
                    #ffffff,
                    #f9fbfd
                );
        }

        .panel-title {
            display: flex;
            align-items: center;
            gap: 11px;
        }

        .panel-title-icon {
            width: 41px;
            height: 41px;
            flex: 0 0 41px;

            display: grid;
            place-items: center;

            border-radius: 14px;

            color: #ffffff;
            background: linear-gradient(
                145deg,
                var(--primary),
                var(--primary-light)
            );

            box-shadow: 0 12px 24px rgba(8, 57, 111, 0.18);

            font-size: 17px;
        }

        .panel-header h2 {
            margin: 0;

            font-size: 15px;
            letter-spacing: -0.3px;
            font-weight: 850;
        }

        .panel-header p {
            margin: 4px 0 0;

            color: var(--text-soft);

            font-size: 8px;
            line-height: 1.45;
            font-weight: 550;
        }

        .panel-counter {
            display: inline-flex;
            align-items: center;
            gap: 6px;

            padding: 7px 9px;

            border: 1px solid var(--border);
            border-radius: 999px;

            color: var(--primary);
            background: #ffffff;

            font-size: 8px;
            font-weight: 800;
        }

        .panel-body {
            padding: 19px;
        }

        /*
        |--------------------------------------------------------------------------
        | Formulário
        |--------------------------------------------------------------------------
        */

        .form-group {
            margin-bottom: 13px;
        }

        .form-label {
            display: block;

            margin-bottom: 6px;

            color: #516176;

            font-size: 8px;
            font-weight: 850;
            letter-spacing: 0.45px;
            text-transform: uppercase;
        }

        .input-wrapper {
            position: relative;
        }

        .input-wrapper > i {
            position: absolute;
            top: 50%;
            left: 13px;

            z-index: 2;

            color: var(--primary);

            font-size: 14px;

            transform: translateY(-50%);
            pointer-events: none;
        }

        .form-control,
        .form-select {
            min-height: 47px;

            border: 1px solid var(--border);
            border-radius: 14px;

            color: var(--text);
            background-color: var(--surface-soft);

            box-shadow: none;

            font-size: 10px;
            font-weight: 650;

            transition:
                border-color 0.2s ease,
                background 0.2s ease,
                box-shadow 0.2s ease,
                transform 0.2s ease;
        }

        textarea.form-control {
            min-height: 85px;
            padding-top: 12px;
            resize: vertical;
        }

        .input-wrapper .form-control {
            padding-left: 38px;
        }

        .form-control:hover,
        .form-select:hover {
            background-color: #ffffff;
            border-color: #c6d4e1;
        }

        .form-control:focus,
        .form-select:focus {
            color: var(--text);
            background-color: #ffffff;
            border-color: var(--primary-light);

            box-shadow: 0 0 0 4px rgba(20, 91, 159, 0.1);

            transform: translateY(-1px);
        }

        .stock-preview {
            display: none;

            margin-bottom: 13px;
            padding: 12px 13px;

            border: 1px solid var(--border);
            border-radius: 14px;

            color: var(--text-soft);
            background: var(--surface-soft);

            font-size: 9px;
            line-height: 1.5;
            font-weight: 600;
        }

        .stock-preview.visible {
            display: block;
        }

        .stock-preview strong {
            color: var(--text);
        }

        .multi-output-intro {
            display: flex;
            align-items: flex-start;
            gap: 10px;

            margin-bottom: 13px;
            padding: 12px 13px;

            border: 1px solid #c7dceb;
            border-radius: 15px;

            color: #31516b;
            background: linear-gradient(145deg, #f3faff, #eaf5fb);

            font-size: 8px;
            line-height: 1.5;
        }

        .multi-output-intro i {
            color: var(--primary);
            font-size: 18px;
        }

        .multi-output-intro strong {
            display: block;
            color: var(--primary-dark);
            font-size: 9px;
            font-weight: 900;
            text-transform: uppercase;
        }

        .saida-items {
            display: flex;
            flex-direction: column;
            gap: 9px;

            margin-bottom: 10px;
        }

        .saida-item {
            position: relative;

            padding: 12px;

            border: 1px solid var(--border);
            border-radius: 17px;

            background: linear-gradient(145deg, #ffffff, #f7fafc);

            box-shadow: 0 8px 22px rgba(8, 57, 111, 0.055);

            transition:
                border-color 0.2s ease,
                box-shadow 0.2s ease,
                transform 0.2s ease;
        }

        .saida-item:focus-within {
            border-color: #aac8df;
            box-shadow: 0 13px 28px rgba(8, 57, 111, 0.1);
            transform: translateY(-1px);
        }

        .saida-item-top {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 9px;

            margin-bottom: 10px;
        }

        .saida-item-number {
            display: inline-flex;
            align-items: center;
            gap: 6px;

            color: var(--primary);

            font-size: 7px;
            font-weight: 900;
            letter-spacing: 0.5px;
            text-transform: uppercase;
        }

        .saida-remove-button {
            width: 31px;
            height: 31px;

            display: grid;
            place-items: center;

            border: 1px solid #efcbd2;
            border-radius: 10px;

            color: var(--red);
            background: var(--red-light);

            cursor: pointer;

            transition: transform 0.2s ease, background 0.2s ease;
        }

        .saida-remove-button:hover {
            color: #ffffff;
            background: var(--red);
            transform: scale(1.04);
        }

        .saida-item-grid {
            display: grid;
            grid-template-columns: minmax(0, 1fr) 92px;
            gap: 8px;
        }

        .saida-item-grid .form-group {
            margin-bottom: 8px;
        }

        .saida-item-note {
            grid-column: 1 / -1;
        }

        .saida-item-stock {
            min-height: 31px;

            display: flex;
            align-items: center;
            gap: 6px;

            padding: 6px 8px;

            border: 1px dashed #cbd8e4;
            border-radius: 10px;

            color: var(--text-soft);
            background: #f8fbfd;

            font-size: 7px;
            font-weight: 700;
        }

        .saida-item-stock.valid {
            color: #086247;
            border-color: #bfe3d7;
            background: #edf9f4;
        }

        .saida-item-stock.invalid {
            color: #922138;
            border-color: #efcbd2;
            background: #fff4f6;
        }

        .add-toner-button {
            width: 100%;
            min-height: 43px;

            display: flex;
            align-items: center;
            justify-content: center;
            gap: 7px;

            margin-bottom: 13px;

            border: 1px dashed #9fbcd2;
            border-radius: 14px;

            color: var(--primary);
            background: #f5faff;

            cursor: pointer;

            font-size: 8px;
            font-weight: 900;
            text-transform: uppercase;

            transition: transform 0.2s ease, background 0.2s ease;
        }

        .add-toner-button:hover {
            background: #eaf5fc;
            transform: translateY(-1px);
        }

        .saida-summary {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 12px;

            margin-bottom: 13px;
            padding: 11px 12px;

            border-radius: 14px;

            color: #ffffff;
            background: linear-gradient(145deg, var(--primary-dark), var(--primary));
        }

        .saida-summary span {
            display: block;
            color: rgba(255, 255, 255, 0.7);
            font-size: 7px;
            font-weight: 750;
        }

        .saida-summary strong {
            display: block;
            margin-top: 3px;
            font-size: 10px;
            font-weight: 900;
        }

        .receipt-information {
            display: flex;
            align-items: flex-start;
            gap: 10px;

            margin: 3px 0 13px;
            padding: 11px 12px;

            border: 1px solid #cbdbe7;
            border-radius: 14px;

            color: #31516b;
            background: #edf7fc;
        }

        .receipt-information > i {
            color: var(--primary);
            font-size: 17px;
        }

        .receipt-information strong {
            display: block;
            color: var(--primary);
            font-size: 8px;
            font-weight: 900;
            text-transform: uppercase;
        }

        .receipt-information span {
            display: block;
            margin-top: 3px;
            color: var(--text-soft);
            font-size: 7px;
            line-height: 1.45;
        }

        .submit-button {
            position: relative;

            width: 100%;
            min-height: 52px;

            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;

            overflow: hidden;

            border: 0;
            border-radius: 16px;

            color: #ffffff;

            background: linear-gradient(
                135deg,
                var(--primary-dark),
                var(--primary),
                var(--primary-light)
            );

            box-shadow:
                0 17px 34px rgba(8, 57, 111, 0.22),
                inset 0 1px 0 rgba(255, 255, 255, 0.18);

            font-size: 10px;
            font-weight: 850;
            letter-spacing: 0.4px;
            text-transform: uppercase;

            transition:
                transform 0.2s ease,
                box-shadow 0.2s ease;
        }

        .submit-button:hover {
            transform: translateY(-3px);

            box-shadow:
                0 23px 44px rgba(8, 57, 111, 0.28),
                inset 0 1px 0 rgba(255, 255, 255, 0.2);
        }

        /*
        |--------------------------------------------------------------------------
        | Estoque
        |--------------------------------------------------------------------------
        */

        .stock-toolbar {
            display: grid;
            grid-template-columns: 1fr auto;
            gap: 10px;

            padding: 14px 17px;

            border-bottom: 1px solid var(--border-soft);

            background: #fbfdfe;
        }

        .search-wrapper {
            position: relative;
        }

        .search-wrapper i {
            position: absolute;
            top: 50%;
            left: 14px;

            color: var(--primary);

            font-size: 15px;

            transform: translateY(-50%);
        }

        .search-input {
            width: 100%;
            height: 46px;

            border: 1px solid var(--border);
            border-radius: 14px;
            outline: 0;

            color: var(--text);
            background: var(--surface-soft);

            padding: 0 14px 0 40px;

            font-size: 10px;
            font-weight: 650;

            transition:
                border-color 0.2s ease,
                box-shadow 0.2s ease,
                background 0.2s ease;
        }

        .search-input:focus {
            border-color: var(--primary-light);
            background: #ffffff;

            box-shadow: 0 0 0 4px rgba(20, 91, 159, 0.1);
        }

        .stock-filter {
            height: 46px;

            border: 1px solid var(--border);
            border-radius: 14px;

            color: var(--text-soft);
            background: #ffffff;

            padding: 0 12px;

            font-size: 9px;
            font-weight: 750;
        }

        .stock-grid {
            display: grid;
            grid-template-columns: repeat(
                auto-fill,
                minmax(215px, 1fr)
            );
            gap: 11px;

            padding: 16px;
        }

        .stock-card {
            position: relative;

            min-height: 190px;
            padding: 16px;

            overflow: hidden;

            border: 1px solid var(--border);
            border-radius: 20px;

            background: #ffffff;

            box-shadow: var(--shadow-sm);

            transform-style: preserve-3d;

            transition:
                transform 0.22s ease,
                border-color 0.22s ease,
                box-shadow 0.22s ease;
        }

        .stock-card:hover {
            border-color: #c3d3e1;

            transform:
                translateY(-5px)
                perspective(800px)
                rotateX(2deg);

            box-shadow: var(--shadow-md);
        }

        .stock-card::before {
            content: "";
            position: absolute;

            top: 0;
            bottom: 0;
            left: 0;

            width: 5px;

            background: var(--green);
        }

        .stock-card.baixo::before {
            background: var(--yellow);
        }

        .stock-card.critico::before,
        .stock-card.zerado::before {
            background: var(--red);
        }

        .stock-card::after {
            content: "";

            position: absolute;

            top: -47px;
            right: -47px;

            width: 112px;
            height: 112px;

            border-radius: 50%;

            background: rgba(20, 91, 159, 0.05);
        }

        .stock-card-top {
            position: relative;
            z-index: 2;

            display: flex;
            align-items: flex-start;
            justify-content: space-between;
            gap: 10px;
        }

        .stock-model {
            margin: 0;

            color: var(--text);

            font-size: 12px;
            line-height: 1.35;
            font-weight: 850;
        }

        .stock-config-button {
            width: 32px;
            height: 32px;
            flex: 0 0 32px;

            display: grid;
            place-items: center;

            border: 1px solid var(--border);
            border-radius: 10px;

            color: var(--primary);
            background: var(--surface-soft);

            font-size: 13px;

            transition:
                transform 0.18s ease,
                background 0.18s ease;
        }

        .stock-config-button:hover {
            background: #ffffff;
            transform: rotate(12deg);
        }

        .stock-status {
            position: relative;
            z-index: 2;

            display: inline-flex;
            align-items: center;
            gap: 5px;

            margin-top: 9px;
            padding: 6px 8px;

            border: 1px solid #c3e9dc;
            border-radius: 999px;

            color: #076448;
            background: var(--green-light);

            font-size: 7px;
            font-weight: 850;
            letter-spacing: 0.2px;
        }

        .stock-status.baixo {
            color: #916000;
            border-color: #edd9aa;
            background: var(--yellow-light);
        }

        .stock-status.critico,
        .stock-status.zerado {
            color: #922138;
            border-color: #edc7cf;
            background: var(--red-light);
        }

        .stock-quantity {
            position: relative;
            z-index: 2;

            display: flex;
            align-items: flex-end;
            gap: 5px;

            margin-top: 15px;
        }

        .stock-quantity strong {
            font-size: 38px;
            line-height: 0.92;
            letter-spacing: -1.6px;
            font-weight: 900;
        }

        .stock-quantity span {
            color: var(--text-light);

            font-size: 8px;
            font-weight: 750;
        }

        .stock-information {
            position: relative;
            z-index: 2;

            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 7px;

            margin-top: 13px;
        }

        .stock-info-item {
            padding: 8px;

            border: 1px solid var(--border-soft);
            border-radius: 11px;

            background: var(--surface-soft);
        }

        .stock-info-item span {
            display: block;

            color: var(--text-light);

            font-size: 6px;
            font-weight: 800;
            letter-spacing: 0.45px;
            text-transform: uppercase;
        }

        .stock-info-item strong {
            display: block;
            margin-top: 4px;

            color: var(--text);

            font-size: 8px;
            font-weight: 800;
        }

        .stock-progress {
            position: relative;
            z-index: 2;

            height: 7px;

            overflow: hidden;

            margin-top: 12px;

            border-radius: 999px;

            background: #e7edf3;
        }

        .stock-progress span {
            display: block;
            height: 100%;

            border-radius: inherit;

            background: var(--green);
        }

        .stock-card.baixo .stock-progress span {
            background: var(--yellow);
        }

        .stock-card.critico .stock-progress span,
        .stock-card.zerado .stock-progress span {
            background: var(--red);
        }

        .stock-empty {
            grid-column: 1 / -1;

            padding: 55px 20px;

            text-align: center;

            color: var(--text-soft);
        }

        .stock-empty i {
            display: block;

            margin-bottom: 10px;

            color: var(--primary);

            font-size: 34px;
        }

        /*
        |--------------------------------------------------------------------------
        | Histórico
        |--------------------------------------------------------------------------
        */

        .history-panel {
            margin-top: 14px;
        }

        .history-filters {
            display: grid;
            grid-template-columns: minmax(230px, 1fr) 180px auto;
            gap: 9px;

            padding: 14px 17px;

            border-bottom: 1px solid var(--border-soft);

            background: #fbfdfe;
        }

        .clear-button {
            min-height: 46px;

            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 7px;

            padding: 0 13px;

            border: 1px solid var(--border);
            border-radius: 14px;

            color: var(--text-soft);
            background: #ffffff;

            font-size: 8px;
            font-weight: 850;
            text-transform: uppercase;

            transition:
                transform 0.18s ease,
                color 0.18s ease,
                border-color 0.18s ease;
        }

        .clear-button:hover {
            color: var(--primary);
            border-color: #c5d4e1;

            transform: translateY(-2px);
        }

        .table-container {
            max-height: 62vh;
            overflow: auto;

            scrollbar-width: thin;
            scrollbar-color: #b9c7d4 transparent;
        }

        .history-table {
            width: 100%;
            min-width: 1000px;

            border-collapse: separate;
            border-spacing: 0;
        }

        .history-table th {
            position: sticky;
            top: 0;
            z-index: 5;

            padding: 13px 14px;

            border-bottom: 1px solid var(--border);

            color: #65758a;
            background: #f5f8fb;

            font-size: 8px;
            font-weight: 850;
            letter-spacing: 0.55px;
            text-transform: uppercase;
            white-space: nowrap;
        }

        .history-table td {
            padding: 13px 14px;

            border-bottom: 1px solid var(--border-soft);

            color: #354459;
            background: rgba(255, 255, 255, 0.86);

            font-size: 9px;
            font-weight: 600;
            vertical-align: middle;
        }

        .history-table tr:hover td {
            background: #f7fafc;
        }

        .history-main {
            display: block;

            color: var(--text);

            font-size: 9px;
            font-weight: 800;
        }

        .history-secondary {
            display: block;
            margin-top: 4px;

            color: var(--text-light);

            font-size: 7px;
            font-weight: 550;
        }

        .history-location {
            display: inline-flex;
            align-items: center;
            gap: 5px;

            padding: 6px 8px;

            border: 1px solid var(--border);
            border-radius: 999px;

            color: #526176;
            background: var(--surface-soft);

            font-size: 7px;
            font-weight: 750;
        }

        .history-quantity {
            display: inline-flex;
            align-items: center;
            justify-content: center;

            min-width: 31px;
            height: 29px;

            border-radius: 10px;

            color: #ffffff;
            background: var(--primary);

            font-size: 9px;
            font-weight: 850;
        }

        .empty-history {
            padding: 55px 20px;

            text-align: center;

            color: var(--text-soft);
        }

        /*
        |--------------------------------------------------------------------------
        | Modal
        |--------------------------------------------------------------------------
        */

        .modal-content {
            overflow: hidden;

            border: 0;
            border-radius: 24px;

            box-shadow: 0 35px 100px rgba(5, 41, 79, 0.3);
        }

        .modal-header {
            padding: 17px 20px;

            border: 0;

            color: #ffffff;

            background:
                radial-gradient(
                    circle at 90% 0,
                    rgba(255, 255, 255, 0.12),
                    transparent 14rem
                ),
                linear-gradient(
                    135deg,
                    var(--primary-dark),
                    var(--primary)
                );
        }

        .modal-title {
            font-size: 13px;
            font-weight: 850;
        }

        .modal-body {
            padding: 21px;
        }

        .modal-footer {
            padding: 13px 20px;

            border-top: 1px solid var(--border-soft);

            background: #f9fbfd;
        }

        .modal-button {
            min-height: 40px;

            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 7px;

            padding: 0 14px;

            border: 1px solid var(--border);
            border-radius: 12px;

            font-size: 9px;
            font-weight: 800;
        }

        .modal-button-primary {
            color: #ffffff;
            border-color: var(--primary);
            background: var(--primary);
        }

        .modal-button-success {
            color: #ffffff;
            border-color: var(--green);
            background: var(--green);
        }

        /*
        |--------------------------------------------------------------------------
        | Rodapé
        |--------------------------------------------------------------------------
        */

        .page-footer {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 15px;

            margin-top: 14px;
            padding: 13px 16px;

            border: 1px solid rgba(255, 255, 255, 0.9);
            border-radius: 17px;

            color: var(--text-light);
            background: rgba(255, 255, 255, 0.72);

            backdrop-filter: blur(14px);

            box-shadow: var(--shadow-sm);

            font-size: 7px;
            line-height: 1.5;
            font-weight: 600;
        }

        .footer-secure {
            display: flex;
            align-items: center;
            gap: 6px;

            color: var(--primary);
            font-weight: 750;
        }

        /*
        |--------------------------------------------------------------------------
        | Responsividade
        |--------------------------------------------------------------------------
        */

        @media (max-width: 1300px) {
            .kpi-grid {
                grid-template-columns: repeat(3, 1fr);
            }

            .management-grid {
                grid-template-columns: 1fr;
            }
        }

        @media (max-width: 1000px) {
            .main-header {
                margin: 13px 11px 0;
            }

            .header-content {
                align-items: flex-start;
                flex-direction: column;
            }

            .header-side {
                width: 100%;
                min-width: 0;

                align-items: flex-start;
            }

            .user-line {
                text-align: left;
            }

            .header-actions {
                justify-content: flex-start;
            }

            .main-content {
                padding: 14px 11px 28px;
            }

            .scanner-panel {
                grid-template-columns: 1fr;
            }

            .kpi-grid {
                grid-template-columns: repeat(2, 1fr);
            }
        }

        @media (max-width: 720px) {
            .header-actions {
                display: grid;
                grid-template-columns: repeat(2, minmax(0, 1fr));

                width: 100%;
            }

            .header-button {
                width: 100%;
            }

            .logo-box {
                width: 60px;
                height: 60px;
                flex-basis: 60px;
            }

            .header-title {
                font-size: 22px;
            }

            .scanner-panel {
                padding: 18px;
                border-radius: 24px;
            }

            .scanner-input {
                padding-right: 15px;
            }

            .scanner-ready {
                display: none;
            }

            .stock-toolbar {
                grid-template-columns: 1fr;
            }

            .history-filters {
                grid-template-columns: 1fr;
            }

            .table-container {
                max-height: none;
                overflow: visible;
            }

            .history-table {
                min-width: 0;
            }

            .history-table thead {
                display: none;
            }

            .history-table,
            .history-table tbody,
            .history-table tr,
            .history-table td {
                display: block;
                width: 100%;
            }

            .history-table tbody {
                padding: 10px;
            }

            .history-table tr.history-row {
                overflow: hidden;

                margin-bottom: 10px;

                border: 1px solid var(--border);
                border-radius: 18px;

                background: #ffffff;

                box-shadow: var(--shadow-sm);
            }

            .history-table td {
                display: grid;
                grid-template-columns: 100px minmax(0, 1fr);
                align-items: center;
                gap: 10px;

                padding: 10px 12px;
            }

            .history-table td::before {
                content: attr(data-label);

                color: var(--text-light);

                font-size: 6px;
                font-weight: 850;
                letter-spacing: 0.5px;
                text-transform: uppercase;
            }
        }

        @media (max-width: 560px) {
            .main-header {
                margin-right: 7px;
                margin-left: 7px;
                padding: 15px;
                border-radius: 21px;
            }

            .main-content {
                padding-right: 7px;
                padding-left: 7px;
            }

            .brand-area {
                align-items: flex-start;
                gap: 10px;
            }

            .government-label {
                font-size: 7px;
            }

            .header-subtitle {
                font-size: 8px;
            }

            .scanner-title {
                font-size: 28px;
            }

            .scanner-description {
                font-size: 9px;
            }

            .kpi-grid {
                grid-template-columns: 1fr;
            }

            .panel-header {
                align-items: flex-start;
            }

            .stock-grid {
                grid-template-columns: 1fr;
            }

            .history-table td {
                grid-template-columns: 85px minmax(0, 1fr);
            }

            .page-footer {
                flex-direction: column;
                align-items: flex-start;
            }
        }

        @media (max-width: 540px) {
            .saida-item-grid {
                grid-template-columns: minmax(0, 1fr) 82px;
            }

            .saida-summary {
                align-items: flex-start;
                flex-direction: column;
            }
        }

        @media (prefers-reduced-motion: reduce) {
            *,
            *::before,
            *::after {
                animation-duration: 0.01ms !important;
                animation-iteration-count: 1 !important;
                transition-duration: 0.01ms !important;
                scroll-behavior: auto !important;
            }
        }

        /*
        |--------------------------------------------------------------------------
        | Comprovantes de toner
        |--------------------------------------------------------------------------
        */

        .receipt-option {
            display: flex;
            align-items: flex-start;
            gap: 10px;

            margin: 3px 0 13px;
            padding: 11px 12px;

            border: 1px solid #cbdbe7;
            border-radius: 14px;

            color: #31516b;
            background: #edf7fc;

            cursor: pointer;
        }

        .receipt-option input {
            width: 17px;
            height: 17px;
            flex: 0 0 17px;

            margin-top: 1px;

            accent-color: var(--primary);
        }

        .receipt-option strong {
            display: block;

            color: var(--primary);

            font-size: 8px;
            font-weight: 850;
            text-transform: uppercase;
        }

        .receipt-option span {
            display: block;

            margin-top: 3px;

            color: var(--text-soft);

            font-size: 7px;
            line-height: 1.45;
        }

        .history-print-button {
            min-height: 34px;

            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 6px;

            padding: 0 10px;

            border: 1px solid #c6d7e4;
            border-radius: 11px;

            color: var(--primary);
            background: #eef6fc;

            font-size: 7px;
            font-weight: 850;
            text-transform: uppercase;
            white-space: nowrap;

            transition:
                transform 0.18s ease,
                color 0.18s ease,
                background 0.18s ease,
                box-shadow 0.18s ease;
        }

        .history-print-button:hover {
            color: #ffffff;
            background: var(--primary);

            transform: translateY(-2px);

            box-shadow: 0 10px 20px rgba(8, 57, 111, 0.15);
        }

    </style>
</head>

<body>

<div class="top-strip"></div>
<div class="background-grid"></div>
<div class="background-orb orb-one"></div>
<div class="background-orb orb-two"></div>

<div class="app">

    <header class="main-header">

        <div class="header-content">

            <div class="brand-area">

                <div class="logo-box">
                    <div class="logo-inner">

                        <img
                            src="assets/logo_pref.jpg"
                            alt="Prefeitura de Extrema"
                            onerror="
                                this.style.display='none';
                                this.nextElementSibling.style.display='grid';
                            "
                        >

                        <div class="logo-fallback">
                            <i class="bi bi-buildings-fill"></i>
                        </div>

                    </div>
                </div>

                <div>
                    <div class="government-label">
                        <i class="bi bi-shield-check"></i>
                        Prefeitura de Extrema • Gerência de Tecnologia
                    </div>

                    <h1 class="header-title">
                        ESTOQUE INTELIGENTE DE TONER
                    </h1>

                    <p class="header-subtitle">
                        Controle de entradas, saídas, níveis mínimos,
                        consumo e rastreabilidade dos suprimentos.
                    </p>
                </div>

            </div>

            <div class="header-side">

                <div class="user-line">

                    <div>
                        <strong>
                            <?= e($saudacao) ?>, <?= e($usuarioLogado) ?>
                        </strong>

                        <span id="currentDateTime">
                            Carregando data e horário...
                        </span>
                    </div>

                    <div class="user-avatar">
                        <i class="bi bi-person-fill"></i>
                    </div>

                </div>

                <nav class="header-actions">

                    <button
                        type="button"
                        class="header-button header-button-primary"
                        data-bs-toggle="modal"
                        data-bs-target="#modalEntrada"
                    >
                        <i class="bi bi-plus-circle-fill"></i>
                        Entrada
                    </button>

                    <button
                        type="button"
                        class="header-button"
                        id="focusScannerButton"
                    >
                        <i class="bi bi-upc-scan"></i>
                        Ativar bipador
                    </button>

                    <?php if (!$usuarioEhCynthia): ?>

                        <a
                            href="listar_os.php"
                            class="header-button"
                        >
                            <i class="bi bi-arrow-left-circle-fill"></i>
                            Ordens de serviço
                        </a>

                        <a
                            href="almoxarifado.php"
                            class="header-button"
                        >
                            <i class="bi bi-boxes"></i>
                            Almoxarifado
                        </a>

                    <?php endif; ?>

                    <?php if ($usuarioTelecomAutorizado): ?>

                        <a
                            href="chips.php"
                            class="header-button"
                        >
                            <i class="bi bi-sim-fill"></i>
                            Chips
                        </a>

                        <a
                            href="smartphones.php"
                            class="header-button"
                        >
                            <i class="bi bi-phone-fill"></i>
                            Smartphones
                        </a>

                    <?php endif; ?>

                    <?php if ($usuarioEhCynthia): ?>

                        <a
                            href="dashboard_cynthia.php"
                            class="header-button"
                        >
                            <i class="bi bi-grid-1x2-fill"></i>
                            Meu painel
                        </a>

                        <a
                            href="logout.php"
                            class="header-button"
                        >
                            <i class="bi bi-box-arrow-right"></i>
                            Sair
                        </a>

                    <?php endif; ?>

                </nav>

            </div>

        </div>

    </header>

    <main class="main-content">

        <?php if (
            $usuarioEhCynthia &&
            isset($_GET['acesso_restrito'])
        ): ?>

            <div
                class="flash-message erro"
                style="margin-bottom:14px;"
            >
                <div class="flash-icon">
                    <i class="bi bi-shield-lock-fill"></i>
                </div>

                <span>
                    Acesso redirecionado. Cynthia possui permissão
                    somente para Toner, Chips e Smartphones.
                </span>
            </div>

        <?php endif; ?>

        <?php if (is_array($flash)): ?>
            <div
                class="flash-message <?= e((string) $flash['tipo']) ?>"
                id="flashMessage"
            >
                <div class="flash-icon">
                    <i
                        class="bi <?= $flash['tipo'] === 'sucesso'
                            ? 'bi-check-circle-fill'
                            : 'bi-exclamation-triangle-fill' ?>"
                    ></i>
                </div>

                <span>
                    <?= e((string) $flash['mensagem']) ?>
                </span>
            </div>
        <?php endif; ?>

        <!-- =========================================================
             BIPADOR
        ========================================================== -->
        <section class="scanner-panel" id="scannerPanel">

            <div>

                <div class="scanner-label">
                    <i class="bi bi-upc-scan"></i>
                    Leitura rápida de código de barras
                </div>

                <h2 class="scanner-title">
                    Aponte, bipe e encontre o
                    <span>toner imediatamente.</span>
                </h2>

                <p class="scanner-description">
                    O campo abaixo funciona com leitores USB que simulam um
                    teclado. Faça a leitura do código e pressione Enter. O
                    sistema localizará o modelo, emitirá um sinal sonoro e
                    preencherá automaticamente o formulário de saída.
                </p>

                <div class="scanner-input-box">

                    <i class="bi bi-upc-scan"></i>

                    <input
                        type="text"
                        id="scannerInput"
                        class="scanner-input"
                        placeholder="Bipe o código de barras ou digite o código..."
                        autocomplete="off"
                        inputmode="text"
                    >

                    <span class="scanner-ready">
                        <span class="scanner-dot"></span>
                        Leitor pronto
                    </span>

                </div>

                <div class="scanner-result" id="scannerResult"></div>

            </div>

            <aside class="scanner-side-card">

                <div>
                    <div class="scanner-label" style="color:#9cebd2;">
                        <i class="bi bi-graph-up-arrow"></i>
                        Cobertura estimada
                    </div>

                    <strong>
                        <?= $coberturaEstimada !== null
                            ? $coberturaEstimada
                            : '∞' ?>
                    </strong>

                    <h3>
                        <?= $coberturaEstimada !== null
                            ? 'DIAS DE ESTOQUE'
                            : 'sem consumo recente' ?>
                    </h3>

                    <p>
                        Cálculo baseado no consumo registrado durante os
                        últimos 30 dias.
                    </p>
                </div>

                <div class="coverage-bar">
                    <span
                        style="width:
                        <?= $coberturaEstimada === null
                            ? 100
                            : min(100, max(5, $coberturaEstimada * 3)) ?>%;"
                    ></span>
                </div>

            </aside>

        </section>

        <!-- =========================================================
             INDICADORES
        ========================================================== -->
        <section class="kpi-grid">

            <article class="kpi-card">

                <div class="kpi-top">
                    <div class="kpi-icon">
                        <i class="bi bi-printer-fill"></i>
                    </div>

                    <span class="kpi-number">
                        <?= $totalModelos ?>
                    </span>
                </div>

                <span class="kpi-label">
                    Modelos cadastrados
                </span>

                <span class="kpi-description">
                    Tipos diferentes disponíveis no controle.
                </span>

            </article>

            <article class="kpi-card">

                <div class="kpi-top">
                    <div class="kpi-icon">
                        <i class="bi bi-stack"></i>
                    </div>

                    <span class="kpi-number">
                        <?= $totalUnidades ?>
                    </span>
                </div>

                <span class="kpi-label">
                    Total de unidades
                </span>

                <span class="kpi-description">
                    Soma atual de todos os modelos.
                </span>

            </article>

            <article class="kpi-card kpi-green">

                <div class="kpi-top">
                    <div class="kpi-icon">
                        <i class="bi bi-calendar-check-fill"></i>
                    </div>

                    <span class="kpi-number">
                        <?= $saidasHoje ?>
                    </span>
                </div>

                <span class="kpi-label">
                    Saídas hoje
                </span>

                <span class="kpi-description">
                    Unidades entregues no dia atual.
                </span>

            </article>

            <article class="kpi-card kpi-yellow">

                <div class="kpi-top">
                    <div class="kpi-icon">
                        <i class="bi bi-calendar3"></i>
                    </div>

                    <span class="kpi-number">
                        <?= $saidasMes ?>
                    </span>
                </div>

                <span class="kpi-label">
                    Consumo no mês
                </span>

                <span class="kpi-description">
                    Unidades retiradas no mês atual.
                </span>

            </article>

            <article class="kpi-card kpi-red">

                <div class="kpi-top">
                    <div class="kpi-icon">
                        <i class="bi bi-exclamation-octagon-fill"></i>
                    </div>

                    <span class="kpi-number">
                        <?= $totalCriticos + $totalZerados ?>
                    </span>
                </div>

                <span class="kpi-label">
                    Estoques críticos
                </span>

                <span class="kpi-description">
                    Modelos no mínimo ou sem unidades.
                </span>

            </article>

            <article class="kpi-card kpi-yellow">

                <div class="kpi-top">
                    <div class="kpi-icon">
                        <i class="bi bi-exclamation-triangle-fill"></i>
                    </div>

                    <span class="kpi-number">
                        <?= $totalBaixos ?>
                    </span>
                </div>

                <span class="kpi-label">
                    Estoques baixos
                </span>

                <span class="kpi-description">
                    Modelos próximos do nível mínimo.
                </span>

            </article>

        </section>

        <!-- =========================================================
             SAÍDA + ESTOQUE
        ========================================================== -->
        <section class="management-grid">

            <!-- SAÍDA -->
            <div class="panel">

                <div class="panel-header">

                    <div class="panel-title">

                        <div class="panel-title-icon">
                            <i class="bi bi-box-arrow-up-right"></i>
                        </div>

                        <div>
                            <h2>REGISTRAR SAÍDA</h2>

                            <p>
                                Baixa protegida contra estoque negativo.
                            </p>
                        </div>

                    </div>

                </div>

                <div class="panel-body">

                    <form method="POST" id="saidaForm">

                        <input
                            type="hidden"
                            name="acao"
                            value="saida"
                        >

                        <div class="multi-output-intro">
                            <i class="bi bi-layers-fill"></i>

                            <div>
                                <strong>Uma entrega, vários modelos</strong>
                                Adicione todos os toners retirados pela mesma
                                pessoa e para o mesmo destino. O estoque será
                                baixado de uma só vez.
                            </div>
                        </div>

                        <div id="saidaItens" class="saida-items">

                            <article class="saida-item" data-saida-item>

                                <div class="saida-item-top">
                                    <span class="saida-item-number">
                                        <i class="bi bi-printer-fill"></i>
                                        Toner 1
                                    </span>

                                    <button
                                        type="button"
                                        class="saida-remove-button"
                                        data-remove-item
                                        title="Remover este modelo"
                                        aria-label="Remover este modelo"
                                    >
                                        <i class="bi bi-trash3-fill"></i>
                                    </button>
                                </div>

                                <div class="saida-item-grid">

                                    <div class="form-group">
                                        <label class="form-label">
                                            Modelo do toner
                                        </label>

                                        <div class="input-wrapper">
                                            <i class="bi bi-printer-fill"></i>

                                            <input
                                                type="text"
                                                name="itens_modelo[]"
                                                class="form-control"
                                                data-modelo-item
                                                list="modelosDatalist"
                                                placeholder="Digite ou selecione"
                                                autocomplete="off"
                                                required
                                            >
                                        </div>
                                    </div>

                                    <div class="form-group">
                                        <label class="form-label">
                                            Quantidade
                                        </label>

                                        <input
                                            type="number"
                                            name="itens_quantidade[]"
                                            class="form-control"
                                            data-quantidade-item
                                            min="1"
                                            value="1"
                                            required
                                        >
                                    </div>

                                    <div class="form-group saida-item-note">
                                        <label class="form-label">
                                            Observação deste modelo
                                        </label>

                                        <input
                                            type="text"
                                            name="itens_observacao[]"
                                            class="form-control"
                                            placeholder="Ex.: preto, ciano, reposição da impressora..."
                                            maxlength="255"
                                        >
                                    </div>

                                </div>

                                <div
                                    class="saida-item-stock"
                                    data-item-stock
                                >
                                    Selecione um modelo para conferir o estoque.
                                </div>

                            </article>

                        </div>

                        <datalist id="modelosDatalist">
                            <?php foreach ($estoque as $item): ?>
                                <option value="<?= e($item['modelo']) ?>">
                            <?php endforeach; ?>
                        </datalist>

                        <button
                            type="button"
                            class="add-toner-button"
                            id="adicionarTonerSaida"
                        >
                            <i class="bi bi-plus-circle-fill"></i>
                            Adicionar outro modelo
                        </button>

                        <div class="saida-summary" id="saidaResumo">
                            <div>
                                <span>Modelos selecionados</span>
                                <strong data-summary-models>0 modelos</strong>
                            </div>

                            <div>
                                <span>Total da entrega</span>
                                <strong data-summary-units>0 unidades</strong>
                            </div>
                        </div>

                        <div class="form-group">

                            <label
                                class="form-label"
                                for="responsavelRetirada"
                            >
                                Responsável pela retirada
                            </label>

                            <div class="input-wrapper">
                                <i class="bi bi-person-check-fill"></i>

                                <input
                                    type="text"
                                    name="responsavel_retirada"
                                    id="responsavelRetirada"
                                    class="form-control"
                                    placeholder="Nome de quem retirou"
                                    maxlength="150"
                                    required
                                >
                            </div>

                        </div>

                        <div class="form-group">

                            <label
                                class="form-label"
                                for="responsavelEntrega"
                            >
                                Responsável pela entrega
                            </label>

                            <div class="input-wrapper">
                                <i class="bi bi-person-badge-fill"></i>

                                <input
                                    type="text"
                                    name="responsavel_entrega"
                                    id="responsavelEntrega"
                                    class="form-control"
                                    placeholder="Nome de quem entregou"
                                    value="<?= e($usuarioLogado) ?>"
                                    maxlength="150"
                                    required
                                >
                            </div>

                        </div>

                        <div class="form-group">

                            <label class="form-label" for="localDestino">
                                Local de destino
                            </label>

                            <div class="input-wrapper">
                                <i class="bi bi-geo-alt-fill"></i>

                                <input
                                    type="text"
                                    name="local"
                                    id="localDestino"
                                    class="form-control"
                                    placeholder="Secretaria, setor, escola..."
                                    maxlength="180"
                                    required
                                >
                            </div>

                        </div>

                        <div class="receipt-information">
                            <i class="bi bi-file-earmark-text-fill"></i>

                            <div>
                                <strong>Comprovante único e automático</strong>
                                <span>
                                    O documento será gerado somente após você
                                    confirmar. Ele reunirá um ou vários modelos
                                    na mesma entrega, pronto para imprimir ou
                                    salvar em PDF.
                                </span>
                            </div>
                        </div>

                        <button type="submit" class="submit-button">
                            <i class="bi bi-check-circle-fill"></i>
                            Confirmar saída e gerar comprovante
                        </button>

                    </form>

                </div>

            </div>

            <!-- ESTOQUE -->
            <div class="panel">

                <div class="panel-header">

                    <div class="panel-title">

                        <div class="panel-title-icon">
                            <i class="bi bi-boxes"></i>
                        </div>

                        <div>
                            <h2>ESTOQUE ATUAL</h2>

                            <p>
                                Pesquisa, níveis mínimos e previsão de consumo.
                            </p>
                        </div>

                    </div>

                    <span class="panel-counter">
                        <i class="bi bi-stack"></i>
                        <span id="visibleStockCount">
                            <?= $totalModelos ?>
                        </span>
                        MODELOS
                    </span>

                </div>

                <div class="stock-toolbar">

                    <div class="search-wrapper">

                        <i class="bi bi-search"></i>

                        <input
                            type="search"
                            id="stockSearch"
                            class="search-input"
                            placeholder="Pesquisar modelo ou código de barras..."
                            autocomplete="off"
                        >

                    </div>

                    <select
                        id="stockStatusFilter"
                        class="stock-filter"
                    >
                        <option value="">
                            Todos os níveis
                        </option>

                        <option value="saudavel">
                            Saudável
                        </option>

                        <option value="baixo">
                            Baixo
                        </option>

                        <option value="critico">
                            Crítico
                        </option>

                        <option value="zerado">
                            Sem estoque
                        </option>
                    </select>

                </div>

                <div class="stock-grid" id="stockGrid">

                    <?php if (empty($estoque)): ?>

                        <div class="stock-empty">
                            <i class="bi bi-inbox-fill"></i>
                            Nenhum modelo foi cadastrado no estoque.
                        </div>

                    <?php endif; ?>

                    <?php foreach ($estoque as $item): ?>
                        <?php
                        $status = statusEstoque(
                            $item['quantidade'],
                            $item['estoque_minimo']
                        );

                        $consumoModelo = (int) (
                            $consumo30Dias[$item['modelo']] ?? 0
                        );

                        $mediaModelo = $consumoModelo > 0
                            ? $consumoModelo / 30
                            : 0;

                        $coberturaModelo = $mediaModelo > 0
                            ? (int) floor(
                                $item['quantidade'] / $mediaModelo
                            )
                            : null;

                        $estoqueIdeal = max(
                            $item['estoque_minimo'] + 5,
                            (int) ceil($mediaModelo * 30)
                        );

                        $percentual = $estoqueIdeal > 0
                            ? min(
                                100,
                                max(
                                    0,
                                    (int) round(
                                        ($item['quantidade'] / $estoqueIdeal)
                                        * 100
                                    )
                                )
                            )
                            : 0;

                        $recomendacaoCompra = max(
                            0,
                            $estoqueIdeal - $item['quantidade']
                        );
                        ?>

                        <article
                            class="stock-card <?= e($status['codigo']) ?>"
                            data-stock-card
                            data-search="<?= e(
                                mb_strtolower(
                                    $item['modelo'] . ' ' .
                                    $item['codigo_barras'],
                                    'UTF-8'
                                )
                            ) ?>"
                            data-status="<?= e($status['codigo']) ?>"
                        >

                            <div class="stock-card-top">

                                <h3 class="stock-model">
                                    <?= e($item['modelo']) ?>
                                </h3>

                                <button
                                    type="button"
                                    class="stock-config-button"
                                    title="Configurar modelo"
                                    onclick='abrirConfiguracao(
                                        <?= json_encode(
                                            $item['modelo'],
                                            JSON_HEX_TAG |
                                            JSON_HEX_APOS |
                                            JSON_HEX_QUOT |
                                            JSON_HEX_AMP
                                        ) ?>,
                                        <?= json_encode(
                                            $item['codigo_barras'],
                                            JSON_HEX_TAG |
                                            JSON_HEX_APOS |
                                            JSON_HEX_QUOT |
                                            JSON_HEX_AMP
                                        ) ?>,
                                        <?= $item['estoque_minimo'] ?>
                                    )'
                                >
                                    <i class="bi bi-sliders"></i>
                                </button>

                            </div>

                            <span
                                class="stock-status <?= e($status['codigo']) ?>"
                            >
                                <i class="bi <?= e($status['icone']) ?>"></i>
                                <?= e($status['rotulo']) ?>
                            </span>

                            <div class="stock-quantity">
                                <strong>
                                    <?= $item['quantidade'] ?>
                                </strong>

                                <span>unidades</span>
                            </div>

                            <div class="stock-information">

                                <div class="stock-info-item">
                                    <span>Mínimo</span>
                                    <strong>
                                        <?= $item['estoque_minimo'] ?> un.
                                    </strong>
                                </div>

                                <div class="stock-info-item">
                                    <span>30 dias</span>
                                    <strong>
                                        <?= $consumoModelo ?> consumidas
                                    </strong>
                                </div>

                                <div class="stock-info-item">
                                    <span>Cobertura</span>
                                    <strong>
                                        <?= $coberturaModelo !== null
                                            ? $coberturaModelo . ' dias'
                                            : 'Sem média' ?>
                                    </strong>
                                </div>

                                <div class="stock-info-item">
                                    <span>Comprar</span>
                                    <strong>
                                        <?= $recomendacaoCompra > 0
                                            ? $recomendacaoCompra . ' un.'
                                            : 'Não necessário' ?>
                                    </strong>
                                </div>

                            </div>

                            <div
                                class="stock-progress"
                                title="<?= $percentual ?>% do estoque ideal"
                            >
                                <span
                                    style="width:<?= $percentual ?>%;"
                                ></span>
                            </div>

                        </article>

                    <?php endforeach; ?>

                    <div
                        class="stock-empty"
                        id="stockSearchEmpty"
                        style="display:none;"
                    >
                        <i class="bi bi-search"></i>
                        Nenhum modelo corresponde à pesquisa.
                    </div>

                </div>

            </div>

        </section>

        <!-- =========================================================
             HISTÓRICO
        ========================================================== -->
        <section class="panel history-panel">

            <div class="panel-header">

                <div class="panel-title">

                    <div class="panel-title-icon">
                        <i class="bi bi-clock-history"></i>
                    </div>

                    <div>
                        <h2>Histórico de saídas</h2>

                        <p>
                            Rastreabilidade por modelo, responsável e destino.
                        </p>
                    </div>

                </div>

                <span class="panel-counter">
                    <i class="bi bi-database-fill"></i>
                    <span id="visibleHistoryCount">
                        <?= count($saidas) ?>
                    </span>
                    registros
                </span>

            </div>

            <div class="history-filters">

                <div class="search-wrapper">

                    <i class="bi bi-search"></i>

                    <input
                        type="search"
                        id="historySearch"
                        class="search-input"
                        placeholder="Pesquisar modelo, responsável, local ou data..."
                        autocomplete="off"
                    >

                </div>

                <select
                    id="historyModelFilter"
                    class="stock-filter"
                >
                    <option value="">
                        Todos os modelos
                    </option>

                    <?php foreach ($estoque as $item): ?>
                        <option value="<?= e($item['modelo']) ?>">
                            <?= e($item['modelo']) ?>
                        </option>
                    <?php endforeach; ?>
                </select>

                <button
                    type="button"
                    class="clear-button"
                    id="clearHistoryFilters"
                >
                    <i class="bi bi-arrow-counterclockwise"></i>
                    Limpar
                </button>

            </div>

            <div class="table-container">

                <table class="history-table" id="historyTable">

                    <thead>
                        <tr>
                            <th>Modelo</th>
                            <th>Data</th>
                            <th>Responsável pela retirada</th>
                            <th>Responsável pela entrega</th>
                            <th>Destino</th>
                            <th>Quantidade</th>
                            <th>Comprovante</th>
                        </tr>
                    </thead>

                    <tbody>

                    <?php if (empty($saidas)): ?>

                        <tr>
                            <td colspan="7">
                                <div class="empty-history">
                                    <i class="bi bi-inbox fs-2 d-block mb-2"></i>
                                    Nenhuma saída foi registrada.
                                </div>
                            </td>
                        </tr>

                    <?php endif; ?>

                    <?php foreach ($saidas as $saida): ?>
                        <?php
                        $timestamp = strtotime(
                            (string) ($saida['data_saida'] ?? '')
                        );

                        $dataFormatada = $timestamp !== false
                            ? date('d/m/Y', $timestamp)
                            : 'Data inválida';

                        $horaFormatada = $timestamp !== false
                            ? date('H:i', $timestamp)
                            : '--:--';

                        $textoBusca = mb_strtolower(
                            implode(' ', [
                                (string) ($saida['modelo'] ?? ''),
                                (string) (
                                    $saida['responsavel_retirada'] ?? ''
                                ),
                                (string) (
                                    $saida['responsavel_entrega'] ?? ''
                                ),
                                (string) ($saida['local'] ?? ''),
                                $dataFormatada
                            ]),
                            'UTF-8'
                        );
                        ?>

                        <tr
                            class="history-row"
                            data-history-row
                            data-search="<?= e($textoBusca) ?>"
                            data-model="<?= e(
                                (string) ($saida['modelo'] ?? '')
                            ) ?>"
                        >

                            <td data-label="Modelo">
                                <span class="history-main">
                                    <?= e(
                                        (string) ($saida['modelo'] ?? '')
                                    ) ?>
                                </span>
                            </td>

                            <td data-label="Data">
                                <span class="history-main">
                                    <?= e($dataFormatada) ?>
                                </span>

                                <span class="history-secondary">
                                    <i class="bi bi-clock"></i>
                                    <?= e($horaFormatada) ?>
                                </span>
                            </td>

                            <td data-label="Retirada">
                                <?= e(
                                    (string) (
                                        $saida['responsavel_retirada'] ?? ''
                                    )
                                ) ?>
                            </td>

                            <td data-label="Entrega">
                                <?= e(
                                    (string) (
                                        $saida['responsavel_entrega'] ?? ''
                                    )
                                ) ?>
                            </td>

                            <td data-label="Destino">
                                <span class="history-location">
                                    <i class="bi bi-geo-alt-fill"></i>
                                    <?= e(
                                        (string) ($saida['local'] ?? '')
                                    ) ?>
                                </span>
                            </td>

                            <td data-label="Quantidade">
                                <span class="history-quantity">
                                    <?= (int) ($saida['quantidade'] ?? 0) ?>
                                </span>
                            </td>

                            <td data-label="Comprovante">

                                <a
                                    href="comprovante_tonner.php?<?= !empty($saida['saida_lote_id'])
                                        ? 'lote_id=' . (int) $saida['saida_lote_id']
                                        : 'id=' . (int) ($saida['id'] ?? 0) ?>&print=1"
                                    target="_blank"
                                    rel="noopener noreferrer"
                                    class="history-print-button"
                                    title="Imprimir comprovante desta saída"
                                >
                                    <i class="bi bi-printer-fill"></i>
                                    Imprimir
                                </a>

                            </td>

                        </tr>

                    <?php endforeach; ?>

                        <tr
                            id="historyEmptyResult"
                            style="display:none;"
                        >
                            <td colspan="7">
                                <div class="empty-history">
                                    <i class="bi bi-search fs-2 d-block mb-2"></i>
                                    Nenhum registro corresponde aos filtros.
                                </div>
                            </td>
                        </tr>

                    </tbody>

                </table>

            </div>

        </section>

        <footer class="page-footer">

            <span>
                Prefeitura de Extrema — Gerência de Tecnologia<br>
                Controle institucional de suprimentos de impressão.
            </span>

            <span class="footer-secure">
                <i class="bi bi-shield-lock-fill"></i>
                Operações registradas por usuário autenticado
            </span>

        </footer>

    </main>

</div>

<!-- =============================================================
     MODAL ENTRADA
============================================================== -->
<div
    class="modal fade"
    id="modalEntrada"
    tabindex="-1"
    aria-labelledby="modalEntradaTitulo"
    aria-hidden="true"
>
    <div class="modal-dialog modal-lg modal-dialog-centered">

        <form method="POST" class="modal-content">

            <div class="modal-header">

                <h5 class="modal-title" id="modalEntradaTitulo">
                    <i class="bi bi-plus-circle-fill me-2"></i>
                    Registrar entrada no estoque
                </h5>

                <button
                    type="button"
                    class="btn-close btn-close-white"
                    data-bs-dismiss="modal"
                    aria-label="Fechar"
                ></button>

            </div>

            <div class="modal-body">

                <input type="hidden" name="acao" value="entrada">

                <div class="row g-3">

                    <div class="col-md-7">

                        <label class="form-label" for="modeloEntrada">
                            Modelo do toner
                        </label>

                        <input
                            type="text"
                            name="modelo"
                            id="modeloEntrada"
                            class="form-control"
                            list="modelosDatalist"
                            placeholder="Ex.: HP 85A ou Brother TN-1060"
                            maxlength="100"
                            required
                        >

                    </div>

                    <div class="col-md-5">

                        <label class="form-label" for="codigoEntrada">
                            Código de barras
                        </label>

                        <input
                            type="text"
                            name="codigo_barras"
                            id="codigoEntrada"
                            class="form-control"
                            placeholder="Bipe ou digite"
                            maxlength="120"
                        >

                    </div>

                    <div class="col-md-4">

                        <label class="form-label" for="quantidadeEntrada">
                            Quantidade recebida
                        </label>

                        <input
                            type="number"
                            name="quantidade"
                            id="quantidadeEntrada"
                            class="form-control"
                            min="1"
                            value="1"
                            required
                        >

                    </div>

                    <div class="col-md-4">

                        <label class="form-label" for="minimoEntrada">
                            Estoque mínimo
                        </label>

                        <input
                            type="number"
                            name="estoque_minimo"
                            id="minimoEntrada"
                            class="form-control"
                            min="0"
                            value="2"
                            required
                        >

                    </div>

                    <div class="col-md-4">

                        <label class="form-label" for="observacaoEntrada">
                            Observação
                        </label>

                        <input
                            type="text"
                            name="observacao"
                            id="observacaoEntrada"
                            class="form-control"
                            placeholder="Nota, pedido ou detalhe"
                            maxlength="255"
                        >

                    </div>

                    <div class="col-12">

                        <label class="form-label" for="origemEntrada">
                            Origem / fornecedor
                        </label>

                        <input
                            type="text"
                            name="origem"
                            id="origemEntrada"
                            class="form-control"
                            placeholder="Fornecedor, compra, devolução ou origem do material"
                            maxlength="180"
                        >

                    </div>

                </div>

                <label class="receipt-option mt-3 mb-0">

                    <input
                        type="checkbox"
                        name="imprimir_comprovante"
                        value="1"
                        checked
                    >

                    <span>
                        <strong>
                            <i class="bi bi-printer-fill me-1"></i>
                            Abrir comprovante após registrar
                        </strong>

                        <span>
                            O termo de entrada será aberto pronto para
                            imprimir ou salvar em PDF.
                        </span>
                    </span>

                </label>

                <div
                    class="alert alert-info border-0 rounded-4 mt-3 mb-0"
                    style="font-size:11px;"
                >
                    <i class="bi bi-info-circle-fill me-1"></i>

                    Caso o modelo já exista, a quantidade informada será
                    somada ao saldo atual.
                </div>

            </div>

            <div class="modal-footer">

                <button
                    type="button"
                    class="modal-button"
                    data-bs-dismiss="modal"
                >
                    <i class="bi bi-x-lg"></i>
                    Cancelar
                </button>

                <button
                    type="submit"
                    class="modal-button modal-button-success"
                >
                    <i class="bi bi-check-circle-fill"></i>
                    Registrar entrada
                </button>

            </div>

        </form>

    </div>
</div>

<!-- =============================================================
     MODAL CONFIGURAÇÃO
============================================================== -->
<div
    class="modal fade"
    id="modalConfiguracao"
    tabindex="-1"
    aria-labelledby="modalConfiguracaoTitulo"
    aria-hidden="true"
>
    <div class="modal-dialog modal-dialog-centered">

        <form method="POST" class="modal-content">

            <div class="modal-header">

                <h5 class="modal-title" id="modalConfiguracaoTitulo">
                    <i class="bi bi-sliders me-2"></i>
                    Configurar modelo
                </h5>

                <button
                    type="button"
                    class="btn-close btn-close-white"
                    data-bs-dismiss="modal"
                    aria-label="Fechar"
                ></button>

            </div>

            <div class="modal-body">

                <input type="hidden" name="acao" value="configurar">

                <input
                    type="hidden"
                    name="modelo_atual"
                    id="configModeloAtual"
                >

                <div class="mb-3">

                    <label class="form-label">
                        Modelo
                    </label>

                    <input
                        type="text"
                        id="configModeloVisual"
                        class="form-control"
                        disabled
                    >

                </div>

                <div class="mb-3">

                    <label
                        class="form-label"
                        for="configCodigoBarras"
                    >
                        Código de barras
                    </label>

                    <input
                        type="text"
                        name="codigo_barras"
                        id="configCodigoBarras"
                        class="form-control"
                        maxlength="120"
                        placeholder="Bipe ou digite o código"
                    >

                </div>

                <div>

                    <label
                        class="form-label"
                        for="configEstoqueMinimo"
                    >
                        Estoque mínimo
                    </label>

                    <input
                        type="number"
                        name="estoque_minimo"
                        id="configEstoqueMinimo"
                        class="form-control"
                        min="0"
                        required
                    >

                </div>

            </div>

            <div class="modal-footer">

                <button
                    type="button"
                    class="modal-button"
                    data-bs-dismiss="modal"
                >
                    Cancelar
                </button>

                <button
                    type="submit"
                    class="modal-button modal-button-primary"
                >
                    <i class="bi bi-floppy-fill"></i>
                    Salvar configuração
                </button>

            </div>

        </form>

    </div>
</div>

<script
    src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
></script>

<script>
const modelosEstoque = <?= $modelosJson ?: '[]' ?>;

/*
|--------------------------------------------------------------------------
| Áudio do bipador
|--------------------------------------------------------------------------
*/

let audioContext = null;

function obterAudioContext() {
    if (!audioContext) {
        const AudioContextClass =
            window.AudioContext || window.webkitAudioContext;

        if (AudioContextClass) {
            audioContext = new AudioContextClass();
        }
    }

    return audioContext;
}

function emitirBip(tipo = 'sucesso') {
    const contexto = obterAudioContext();

    if (!contexto) {
        return;
    }

    if (contexto.state === 'suspended') {
        contexto.resume();
    }

    const oscilador = contexto.createOscillator();
    const ganho = contexto.createGain();

    oscilador.connect(ganho);
    ganho.connect(contexto.destination);

    const agora = contexto.currentTime;

    if (tipo === 'erro') {
        oscilador.frequency.setValueAtTime(190, agora);
        oscilador.frequency.setValueAtTime(145, agora + 0.12);
    } else {
        oscilador.frequency.setValueAtTime(650, agora);
        oscilador.frequency.setValueAtTime(880, agora + 0.08);
    }

    ganho.gain.setValueAtTime(0.0001, agora);
    ganho.gain.exponentialRampToValueAtTime(0.18, agora + 0.015);
    ganho.gain.exponentialRampToValueAtTime(0.0001, agora + 0.22);

    oscilador.start(agora);
    oscilador.stop(agora + 0.24);
}

/*
|--------------------------------------------------------------------------
| Localização por código
|--------------------------------------------------------------------------
*/

const scannerInput = document.getElementById('scannerInput');
const scannerResult = document.getElementById('scannerResult');
const saidaItens = document.getElementById('saidaItens');
const adicionarTonerSaida = document.getElementById('adicionarTonerSaida');
const saidaResumo = document.getElementById('saidaResumo');

function normalizar(valor) {
    return String(valor ?? '')
        .normalize('NFD')
        .replace(/[\u0300-\u036f]/g, '')
        .toLowerCase()
        .trim();
}

function localizarPorCodigo(codigo) {
    const codigoNormalizado = normalizar(codigo);

    return modelosEstoque.find((item) => {
        return normalizar(item.codigo_barras) === codigoNormalizado;
    });
}

function localizarPorModelo(modelo) {
    const modeloNormalizado = normalizar(modelo);

    return modelosEstoque.find((item) => {
        return normalizar(item.modelo) === modeloNormalizado;
    });
}

function mostrarScannerResultado(tipo, html) {
    if (!scannerResult) {
        return;
    }

    scannerResult.className = `scanner-result visible ${tipo}`;
    scannerResult.innerHTML = html;
}

function criarLinhaSaida() {
    const artigo = document.createElement('article');
    artigo.className = 'saida-item';
    artigo.setAttribute('data-saida-item', '');

    artigo.innerHTML = `
        <div class="saida-item-top">
            <span class="saida-item-number">
                <i class="bi bi-printer-fill"></i>
                Toner
            </span>

            <button
                type="button"
                class="saida-remove-button"
                data-remove-item
                title="Remover este modelo"
                aria-label="Remover este modelo"
            >
                <i class="bi bi-trash3-fill"></i>
            </button>
        </div>

        <div class="saida-item-grid">
            <div class="form-group">
                <label class="form-label">Modelo do toner</label>
                <div class="input-wrapper">
                    <i class="bi bi-printer-fill"></i>
                    <input
                        type="text"
                        name="itens_modelo[]"
                        class="form-control"
                        data-modelo-item
                        list="modelosDatalist"
                        placeholder="Digite ou selecione"
                        autocomplete="off"
                        required
                    >
                </div>
            </div>

            <div class="form-group">
                <label class="form-label">Quantidade</label>
                <input
                    type="number"
                    name="itens_quantidade[]"
                    class="form-control"
                    data-quantidade-item
                    min="1"
                    value="1"
                    required
                >
            </div>

            <div class="form-group saida-item-note">
                <label class="form-label">Observação deste modelo</label>
                <input
                    type="text"
                    name="itens_observacao[]"
                    class="form-control"
                    placeholder="Ex.: preto, ciano, reposição da impressora..."
                    maxlength="255"
                >
            </div>
        </div>

        <div class="saida-item-stock" data-item-stock>
            Selecione um modelo para conferir o estoque.
        </div>
    `;

    saidaItens?.appendChild(artigo);
    prepararLinhaSaida(artigo);
    renumerarLinhasSaida();
    atualizarResumoSaida();

    return artigo;
}

function renumerarLinhasSaida() {
    const linhas = Array.from(
        saidaItens?.querySelectorAll('[data-saida-item]') ?? []
    );

    linhas.forEach((linha, indice) => {
        const numero = linha.querySelector('.saida-item-number');

        if (numero) {
            numero.innerHTML = `
                <i class="bi bi-printer-fill"></i>
                Toner ${indice + 1}
            `;
        }

        const remover = linha.querySelector('[data-remove-item]');

        if (remover) {
            remover.hidden = linhas.length <= 1;
        }
    });
}

function atualizarEstoqueLinha(linha) {
    const modeloInput = linha.querySelector('[data-modelo-item]');
    const quantidadeInput = linha.querySelector('[data-quantidade-item]');
    const estoqueBox = linha.querySelector('[data-item-stock]');
    const item = localizarPorModelo(modeloInput?.value);

    estoqueBox?.classList.remove('valid', 'invalid');

    if (!item) {
        if (estoqueBox) {
            estoqueBox.innerHTML = `
                <i class="bi bi-info-circle-fill"></i>
                Selecione um modelo cadastrado para conferir o estoque.
            `;
        }

        quantidadeInput?.removeAttribute('max');
        atualizarResumoSaida();
        return;
    }

    const quantidade = Math.max(
        0,
        Number(quantidadeInput?.value ?? 0)
    );
    const disponivel = Number(item.quantidade);

    if (quantidadeInput) {
        quantidadeInput.max = String(disponivel);
    }

    const valido = quantidade > 0 && quantidade <= disponivel;

    estoqueBox?.classList.add(valido ? 'valid' : 'invalid');

    if (estoqueBox) {
        estoqueBox.innerHTML = `
            <i class="bi ${valido
                ? 'bi-check-circle-fill'
                : 'bi-exclamation-triangle-fill'}"></i>
            Estoque: <strong>${disponivel}</strong> unidade(s) •
            mínimo: <strong>${Number(item.estoque_minimo)}</strong>
        `;
    }

    atualizarResumoSaida();
}

function prepararLinhaSaida(linha) {
    const modelo = linha.querySelector('[data-modelo-item]');
    const quantidade = linha.querySelector('[data-quantidade-item]');
    const remover = linha.querySelector('[data-remove-item]');

    modelo?.addEventListener('input', () => {
        atualizarEstoqueLinha(linha);
    });

    quantidade?.addEventListener('input', () => {
        atualizarEstoqueLinha(linha);
    });

    remover?.addEventListener('click', () => {
        const total = saidaItens?.querySelectorAll('[data-saida-item]').length ?? 0;

        if (total <= 1) {
            modelo?.focus();
            return;
        }

        linha.remove();
        renumerarLinhasSaida();
        atualizarResumoSaida();
    });

    atualizarEstoqueLinha(linha);
}

function atualizarResumoSaida() {
    const linhas = Array.from(
        saidaItens?.querySelectorAll('[data-saida-item]') ?? []
    );

    const modelosUnicos = new Set();
    let totalUnidades = 0;

    linhas.forEach((linha) => {
        const modelo = linha.querySelector('[data-modelo-item]')?.value ?? '';
        const quantidade = Number(
            linha.querySelector('[data-quantidade-item]')?.value ?? 0
        );
        const item = localizarPorModelo(modelo);

        if (item) {
            modelosUnicos.add(normalizar(item.modelo));
        }

        if (quantidade > 0) {
            totalUnidades += quantidade;
        }
    });

    const modelosBox = saidaResumo?.querySelector('[data-summary-models]');
    const unidadesBox = saidaResumo?.querySelector('[data-summary-units]');

    if (modelosBox) {
        modelosBox.textContent =
            `${modelosUnicos.size} ${modelosUnicos.size === 1 ? 'modelo' : 'modelos'}`;
    }

    if (unidadesBox) {
        unidadesBox.textContent =
            `${totalUnidades} ${totalUnidades === 1 ? 'unidade' : 'unidades'}`;
    }
}

function adicionarModeloAoPedido(item) {
    if (!item || !saidaItens) {
        return;
    }

    const linhas = Array.from(
        saidaItens.querySelectorAll('[data-saida-item]')
    );

    const linhaExistente = linhas.find((linha) => {
        const valor = linha.querySelector('[data-modelo-item]')?.value ?? '';
        return normalizar(valor) === normalizar(item.modelo);
    });

    if (linhaExistente) {
        const quantidade = linhaExistente.querySelector('[data-quantidade-item]');
        const atual = Number(quantidade?.value ?? 0);
        const novaQuantidade = atual + 1;

        if (novaQuantidade > Number(item.quantidade)) {
            emitirBip('erro');
            mostrarScannerResultado(
                'error',
                `Não há mais unidades disponíveis de
                 <strong>${escaparHtml(item.modelo)}</strong>.`
            );
            return;
        }

        if (quantidade) {
            quantidade.value = String(novaQuantidade);
        }

        atualizarEstoqueLinha(linhaExistente);
        linhaExistente.scrollIntoView({ behavior: 'smooth', block: 'center' });
        return;
    }

    let linha = linhas.find((itemLinha) => {
        const valor = itemLinha.querySelector('[data-modelo-item]')?.value ?? '';
        return String(valor).trim() === '';
    });

    if (!linha) {
        linha = criarLinhaSaida();
    }

    const modelo = linha.querySelector('[data-modelo-item]');
    const quantidade = linha.querySelector('[data-quantidade-item]');

    if (modelo) {
        modelo.value = item.modelo;
    }

    if (quantidade) {
        quantidade.value = '1';
    }

    atualizarEstoqueLinha(linha);
    linha.scrollIntoView({ behavior: 'smooth', block: 'center' });
}

function processarCodigo(codigo) {
    const valor = String(codigo ?? '').trim();

    if (valor === '') {
        return;
    }

    const item = localizarPorCodigo(valor);

    if (!item) {
        emitirBip('erro');
        mostrarScannerResultado(
            'error',
            `<i class="bi bi-x-octagon-fill me-1"></i>
             Código <strong>${escaparHtml(valor)}</strong> não encontrado.
             Cadastre o código nas configurações do modelo.`
        );
        scannerInput?.select();
        return;
    }

    emitirBip('sucesso');
    adicionarModeloAoPedido(item);

    mostrarScannerResultado(
        'success',
        `<i class="bi bi-check-circle-fill me-1"></i>
         <strong>${escaparHtml(item.modelo)}</strong> adicionado à saída.
         Estoque disponível: <strong>${Number(item.quantidade)}</strong>.`
    );

    if (scannerInput) {
        scannerInput.value = '';
        scannerInput.focus();
    }
}

scannerInput?.addEventListener('keydown', (event) => {
    if (event.key === 'Enter') {
        event.preventDefault();
        processarCodigo(scannerInput.value);
    }
});

document
    .getElementById('focusScannerButton')
    ?.addEventListener('click', () => {
        scannerInput?.focus();
        scannerInput?.select();
        emitirBip('sucesso');
    });

adicionarTonerSaida?.addEventListener('click', () => {
    const linha = criarLinhaSaida();
    linha.querySelector('[data-modelo-item]')?.focus();
});

saidaItens
    ?.querySelectorAll('[data-saida-item]')
    .forEach((linha) => prepararLinhaSaida(linha));

renumerarLinhasSaida();
atualizarResumoSaida();

/*
|--------------------------------------------------------------------------
| Validação da saída múltipla
|--------------------------------------------------------------------------
*/

document.getElementById('saidaForm')?.addEventListener('submit', (event) => {
    const linhas = Array.from(
        saidaItens?.querySelectorAll('[data-saida-item]') ?? []
    );
    const totaisPorModelo = new Map();
    let primeiraFalha = null;

    linhas.forEach((linha) => {
        const modeloInput = linha.querySelector('[data-modelo-item]');
        const quantidadeInput = linha.querySelector('[data-quantidade-item]');
        const item = localizarPorModelo(modeloInput?.value);
        const quantidade = Number(quantidadeInput?.value ?? 0);

        if (!item) {
            primeiraFalha ??= modeloInput;
            return;
        }

        if (quantidade <= 0) {
            primeiraFalha ??= quantidadeInput;
            return;
        }

        const chave = normalizar(item.modelo);
        const atual = totaisPorModelo.get(chave) ?? {
            item,
            quantidade: 0
        };

        atual.quantidade += quantidade;
        totaisPorModelo.set(chave, atual);
    });

    let mensagem = '';

    if (primeiraFalha) {
        mensagem = 'Revise os modelos e as quantidades da saída.';
    } else if (totaisPorModelo.size === 0) {
        mensagem = 'Adicione pelo menos um modelo de toner.';
    } else {
        for (const { item, quantidade } of totaisPorModelo.values()) {
            if (quantidade > Number(item.quantidade)) {
                mensagem =
                    `Estoque insuficiente para ${item.modelo}. ` +
                    `Solicitado: ${quantidade}; disponível: ${item.quantidade}.`;
                primeiraFalha = linhas.find((linha) => {
                    return normalizar(
                        linha.querySelector('[data-modelo-item]')?.value
                    ) === normalizar(item.modelo);
                })?.querySelector('[data-quantidade-item]') ?? null;
                break;
            }
        }
    }

    if (mensagem !== '') {
        event.preventDefault();
        emitirBip('erro');
        window.alert(mensagem);
        primeiraFalha?.focus();
        return;
    }

    const botao = event.currentTarget.querySelector('.submit-button');

    if (botao) {
        botao.disabled = true;
        botao.innerHTML = `
            <span class="spinner-border spinner-border-sm" aria-hidden="true"></span>
            Registrando saída...
        `;
    }
});

/*
|--------------------------------------------------------------------------
| Pesquisa de estoque
|--------------------------------------------------------------------------
*/

const stockSearch = document.getElementById('stockSearch');
const stockStatusFilter = document.getElementById('stockStatusFilter');
const visibleStockCount = document.getElementById('visibleStockCount');
const stockSearchEmpty = document.getElementById('stockSearchEmpty');

function filtrarEstoque() {
    const termo = normalizar(stockSearch?.value);
    const status = stockStatusFilter?.value ?? '';

    const cards = Array.from(
        document.querySelectorAll('[data-stock-card]')
    );

    let totalVisivel = 0;

    cards.forEach((card) => {
        const pesquisa = normalizar(card.dataset.search);
        const statusCard = card.dataset.status ?? '';

        const correspondePesquisa =
            termo === '' || pesquisa.includes(termo);

        const correspondeStatus =
            status === '' || statusCard === status;

        const exibir =
            correspondePesquisa && correspondeStatus;

        card.style.display = exibir ? '' : 'none';

        if (exibir) {
            totalVisivel++;
        }
    });

    if (visibleStockCount) {
        visibleStockCount.textContent = String(totalVisivel);
    }

    if (stockSearchEmpty) {
        stockSearchEmpty.style.display =
            totalVisivel === 0 && cards.length > 0
                ? ''
                : 'none';
    }
}

stockSearch?.addEventListener('input', filtrarEstoque);
stockStatusFilter?.addEventListener('change', filtrarEstoque);

/*
|--------------------------------------------------------------------------
| Histórico
|--------------------------------------------------------------------------
*/

const historySearch = document.getElementById('historySearch');
const historyModelFilter = document.getElementById('historyModelFilter');
const visibleHistoryCount = document.getElementById(
    'visibleHistoryCount'
);
const historyEmptyResult = document.getElementById(
    'historyEmptyResult'
);

function filtrarHistorico() {
    const termo = normalizar(historySearch?.value);
    const modelo = historyModelFilter?.value ?? '';

    const linhas = Array.from(
        document.querySelectorAll('[data-history-row]')
    );

    let totalVisivel = 0;

    linhas.forEach((linha) => {
        const pesquisa = normalizar(linha.dataset.search);
        const modeloLinha = linha.dataset.model ?? '';

        const correspondePesquisa =
            termo === '' || pesquisa.includes(termo);

        const correspondeModelo =
            modelo === '' || modeloLinha === modelo;

        const exibir =
            correspondePesquisa && correspondeModelo;

        linha.style.display = exibir ? '' : 'none';

        if (exibir) {
            totalVisivel++;
        }
    });

    if (visibleHistoryCount) {
        visibleHistoryCount.textContent =
            String(totalVisivel);
    }

    if (historyEmptyResult) {
        historyEmptyResult.style.display =
            totalVisivel === 0 && linhas.length > 0
                ? ''
                : 'none';
    }
}

historySearch?.addEventListener('input', filtrarHistorico);
historyModelFilter?.addEventListener('change', filtrarHistorico);

document
    .getElementById('clearHistoryFilters')
    ?.addEventListener('click', () => {
        if (historySearch) {
            historySearch.value = '';
        }

        if (historyModelFilter) {
            historyModelFilter.value = '';
        }

        filtrarHistorico();
        historySearch?.focus();
    });

/*
|--------------------------------------------------------------------------
| Configuração do modelo
|--------------------------------------------------------------------------
*/

function abrirConfiguracao(modelo, codigo, minimo) {
    const modeloAtual = document.getElementById(
        'configModeloAtual'
    );

    const modeloVisual = document.getElementById(
        'configModeloVisual'
    );

    const codigoInput = document.getElementById(
        'configCodigoBarras'
    );

    const minimoInput = document.getElementById(
        'configEstoqueMinimo'
    );

    if (modeloAtual) {
        modeloAtual.value = modelo;
    }

    if (modeloVisual) {
        modeloVisual.value = modelo;
    }

    if (codigoInput) {
        codigoInput.value = codigo;
    }

    if (minimoInput) {
        minimoInput.value = minimo;
    }

    const modal = bootstrap.Modal.getOrCreateInstance(
        document.getElementById('modalConfiguracao')
    );

    modal.show();

    document
        .getElementById('modalConfiguracao')
        ?.addEventListener(
            'shown.bs.modal',
            () => {
                codigoInput?.focus();
                codigoInput?.select();
            },
            {
                once: true
            }
        );
}

/*
|--------------------------------------------------------------------------
| Data e hora
|--------------------------------------------------------------------------
*/

function atualizarDataHora() {
    const elemento = document.getElementById('currentDateTime');

    if (!elemento) {
        return;
    }

    const agora = new Date();

    const data = agora.toLocaleDateString('pt-BR', {
        weekday: 'long',
        day: '2-digit',
        month: 'long',
        year: 'numeric'
    });

    const hora = agora.toLocaleTimeString('pt-BR', {
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit'
    });

    elemento.textContent =
        data.charAt(0).toUpperCase() +
        data.slice(1) +
        ' • ' +
        hora;
}

atualizarDataHora();
setInterval(atualizarDataHora, 1000);

/*
|--------------------------------------------------------------------------
| Escape HTML
|--------------------------------------------------------------------------
*/

function escaparHtml(valor) {
    const div = document.createElement('div');

    div.textContent = String(valor ?? '');

    return div.innerHTML;
}

/*
|--------------------------------------------------------------------------
| Feedback sonoro do flash
|--------------------------------------------------------------------------
*/

window.addEventListener('load', () => {
    const flash = document.getElementById('flashMessage');

    if (!flash) {
        return;
    }

    const sucesso = flash.classList.contains('sucesso');

    document.addEventListener(
        'click',
        () => emitirBip(sucesso ? 'sucesso' : 'erro'),
        {
            once: true
        }
    );
});
</script>

</body>
</html>