<?php
namespace App\Controllers;

use App\Services\FechamentoCaixaService;

/**
 * Fiscal de Caixa — versão mobile dentro do Leitor.
 * Reutiliza o FechamentoCaixaService (mesma lógica do dashboard), mas protegido
 * pela autenticação do Leitor (leitor_ok) e pela permissão 'fiscal_caixa'.
 */
class LeitorFiscalController
{
    public function __construct()
    {
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
    }

    /** Permissões atuais do usuário do leitor (sempre frescas do arquivo) */
    private function perms(): array
    {
        return LeitorPermissoesController::permissoesDoUsuario($_SESSION['leitor_usuario'] ?? '');
    }

    private function exigeApi(string $perm = 'fiscal_caixa'): void
    {
        header('Content-Type: application/json; charset=utf-8');
        if (empty($_SESSION['leitor_ok'])) {
            http_response_code(401);
            echo json_encode(['sucesso' => false, 'erro' => 'Não autenticado']);
            exit;
        }
        if (!in_array($perm, $this->perms(), true)) {
            http_response_code(403);
            echo json_encode(['sucesso' => false, 'erro' => 'Sem permissão de Fiscal de Caixa']);
            exit;
        }
    }

    // ── GET /leitor/fiscal — página mobile ────────────────────────────────────
    public function index(): void
    {
        if (empty($_SESSION['leitor_ok'])) {
            header('Location: /leitor');
            exit;
        }
        $_SESSION['leitor_perms'] = $this->perms();
        if (!in_array('fiscal_caixa', $_SESSION['leitor_perms'], true)) {
            header('Location: /leitor/scanner');
            exit;
        }
        require __DIR__ . '/../Views/leitor/fiscal.php';
    }

    /** Calcula [dataIni, dataFim] a partir do período (mesma lógica do dashboard) */
    private function intervalo(string $periodo, ?string $ini, ?string $fim): array
    {
        if ($periodo === 'manual'
            && preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) $ini)
            && preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) $fim)) {
            return [$ini, $fim];
        }
        if (!in_array($periodo, ['hoje', 'semana', 'mes', 'ano'], true)) {
            $periodo = 'mes';
        }
        $svc    = new FechamentoCaixaService();
        $ancora = $svc->getRepo()->ultimaDataFechamento() ?: date('Y-m-d');
        $dataFim = $ancora;
        switch ($periodo) {
            case 'hoje':   $dataIni = $ancora; break;
            case 'semana': $dataIni = date('Y-m-d', strtotime($ancora . ' -6 days')); break;
            case 'ano':    $dataIni = date('Y-m-d', strtotime($ancora . ' -364 days')); break;
            default:       $dataIni = date('Y-m-d', strtotime($ancora . ' -29 days'));
        }
        return [$dataIni, $dataFim];
    }

    // ── GET /api/leitor/fiscal/operadores ─────────────────────────────────────
    public function operadoresApi(): void
    {
        $this->exigeApi();
        session_write_close();
        try {
            $periodo = $_GET['periodo'] ?? 'mes';
            [$ini, $fim] = $this->intervalo($periodo, $_GET['data_ini'] ?? null, $_GET['data_fim'] ?? null);
            $svc = new FechamentoCaixaService();
            $ops = $svc->getRepo()->operadoresComMovimento($ini, $fim);
            echo json_encode([
                'sucesso'    => true,
                'periodo'    => $periodo,
                'data_ini'   => $ini,
                'data_fim'   => $fim,
                'operadores' => $ops,
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['sucesso' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
        exit;
    }

    // ── GET /api/leitor/fiscal/dados ──────────────────────────────────────────
    public function dadosApi(): void
    {
        $this->exigeApi();
        session_write_close();
        $operador = trim($_GET['operador'] ?? '');
        $ini = $_GET['data_ini'] ?? '';
        $fim = $_GET['data_fim'] ?? '';
        if ($operador === '') {
            http_response_code(400);
            echo json_encode(['sucesso' => false, 'erro' => 'Informe o operador']);
            exit;
        }
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $ini) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $fim)) {
            http_response_code(400);
            echo json_encode(['sucesso' => false, 'erro' => 'Datas inválidas']);
            exit;
        }
        try {
            set_time_limit(300);
            $svc         = new FechamentoCaixaService();
            $fechamentos = $svc->fechamentosCompletos($operador, $ini, $fim);

            // SEGURANÇA: análise fiscal (vendas com/sem nota) é sensível.
            // Só vai no JSON se o usuário tiver a permissão 'fiscal_risco'.
            // (não basta esconder na tela — o dado não pode sair do servidor)
            if (!in_array('fiscal_risco', $this->perms(), true)) {
                foreach ($fechamentos as &$fcRef) {
                    if (is_array($fcRef)) {
                        unset($fcRef['vendas_fiscal']);
                    }
                }
                unset($fcRef);
            }

            // Anexa o status de conferência do fiscal a cada fechamento
            $status = $this->lerStatus();
            foreach ($fechamentos as &$fcRef2) {
                if (is_array($fcRef2)) {
                    $fcRef2['fiscal_status'] = $status[(string)($fcRef2['id'] ?? '')] ?? null;
                }
            }
            unset($fcRef2);

            echo json_encode([
                'sucesso'     => true,
                'total'       => count($fechamentos),
                'fechamentos' => $fechamentos,
            ], JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['sucesso' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
        exit;
    }

    // ── Store de status de conferência (storage/fiscal/status.json) ───────────
    private function fiscalDir(): string
    {
        $d = dirname(__DIR__, 2) . '/storage/fiscal';
        if (!is_dir($d)) @mkdir($d, 0775, true);
        return $d;
    }

    private function lerStatus(): array
    {
        $f = $this->fiscalDir() . '/status.json';
        if (!is_file($f)) return [];
        $j = json_decode((string) file_get_contents($f), true);
        return is_array($j) ? $j : [];
    }

    private function salvarStatus(array $mapa): void
    {
        file_put_contents(
            $this->fiscalDir() . '/status.json',
            json_encode($mapa, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
            LOCK_EX
        );
    }

    // ── POST /api/leitor/fiscal/acao ──────────────────────────────────────────
    // body: caixa_id, acao (anotar|conferir|aprovar), texto (p/ anotar)
    public function acaoApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        if (empty($_SESSION['leitor_ok'])) {
            http_response_code(401);
            echo json_encode(['sucesso' => false, 'erro' => 'Não autenticado']);
            exit;
        }
        $perms = $this->perms();
        $caixa = trim($_POST['caixa_id'] ?? '');
        $acao  = trim($_POST['acao'] ?? '');
        $texto = trim($_POST['texto'] ?? '');

        $mapaPerm = [
            'anotar'   => 'fiscal_anotar',
            'conferir' => 'fiscal_conferir',
            'aprovar'  => 'fiscal_aprovar',
        ];
        if ($caixa === '' || !isset($mapaPerm[$acao])) {
            http_response_code(400);
            echo json_encode(['sucesso' => false, 'erro' => 'Requisição inválida']);
            exit;
        }
        if (!in_array($mapaPerm[$acao], $perms, true)) {
            http_response_code(403);
            echo json_encode(['sucesso' => false, 'erro' => 'Sem permissão para esta ação']);
            exit;
        }

        $usuario = $_SESSION['leitor_nome'] ?? ($_SESSION['leitor_usuario'] ?? 'Fiscal');
        $agora   = date('Y-m-d H:i:s');

        $status = $this->lerStatus();
        $st = $status[$caixa] ?? ['anotacoes' => []];
        if (empty($st['anotacoes']) || !is_array($st['anotacoes'])) $st['anotacoes'] = [];

        if ($acao === 'anotar') {
            if ($texto === '') {
                http_response_code(400);
                echo json_encode(['sucesso' => false, 'erro' => 'Justificativa vazia']);
                exit;
            }
            $st['anotacoes'][] = ['texto' => $texto, 'usuario' => $usuario, 'ts' => $agora];
        } elseif ($acao === 'conferir') {
            $st['conferido'] = true;
            $st['conferido_por'] = $usuario;
            $st['conferido_em'] = $agora;
        } elseif ($acao === 'aprovar') {
            $st['aprovado'] = true;
            $st['aprovado_por'] = $usuario;
            $st['aprovado_em'] = $agora;
        }

        $status[$caixa] = $st;
        $this->salvarStatus($status);

        \App\Controllers\LeitorController::registrarAudit('fiscal_' . $acao, $caixa, [
            'usuario' => $usuario,
            'texto'   => $texto,
        ]);

        echo json_encode(['sucesso' => true, 'status' => $st], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        exit;
    }
}
