<?php

namespace App\Http\Controllers\Painel;

use App\Http\Controllers\Controller;
use App\Models\NotaFiscal;
use App\Services\Sefaz\DanfeService;
use App\Services\Sefaz\ManifestacaoService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;

class NotaFiscalController extends Controller
{
    public function index(): View
    {
        return view('painel.notas.index');
    }

    public function show(NotaFiscal $nota): View
    {
        $nota->load(['eventos' => fn ($q) => $q->orderByDesc('data_evento')]);

        return view('painel.notas.show', [
            'nota' => $nota,
            'xml' => $nota->xmlContent(),
        ]);
    }

    /**
     * Download do XML individual. O arquivo mora em disco privado; o acesso
     * passa por aqui justamente para que o escopo por empresa seja aplicado.
     */
    public function download(NotaFiscal $nota): Response
    {
        abort_unless($nota->xml_path && Storage::disk('xmls')->exists($nota->xml_path), 404, 'XML completo ainda não disponível para esta nota.');

        $xml = Storage::disk('xmls')->get($nota->xml_path);

        // Conferência de integridade: o arquivo entregue precisa ser o da
        // chave pedida. Documento fiscal trocado é problema sério na
        // escrituração, e um XML corrompido no disco passaria despercebido.
        abort_unless(
            str_contains($xml, $nota->chave),
            422,
            'O arquivo arquivado não corresponde à chave desta nota. Sincronize novamente antes de usá-lo.',
        );

        return response($xml, 200, [
            'Content-Type' => 'application/xml',
            'Content-Disposition' => 'attachment; filename="'.$nota->downloadFilename().'"',
        ]);
    }

    /**
     * DANFE em PDF. Abre no navegador (inline) para o usuário mandar imprimir
     * direto, sem baixar um arquivo intermediário.
     */
    public function danfe(NotaFiscal $nota, DanfeService $danfe): Response
    {
        try {
            $pdf = $danfe->gerar($nota);
        } catch (\Throwable $e) {
            abort(422, $e->getMessage());
        }

        return response($pdf, 200, [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'inline; filename="'.$danfe->nomeArquivo($nota).'"',
        ]);
    }

    public function manifestar(Request $request, NotaFiscal $nota, ManifestacaoService $manifestacao): RedirectResponse
    {
        abort_unless($request->user()->isAdmin() || $request->user()->isMaster(), 403);

        $dados = $request->validate([
            'tipo' => ['required', 'in:ciencia,confirmada,desconhecida,nao_realizada'],
            'justificativa' => ['nullable', 'string', 'min:15', 'max:255'],
        ]);

        try {
            $retorno = $manifestacao->manifestar(
                $nota->company,
                $nota,
                $dados['tipo'],
                $dados['justificativa'] ?? '',
            );
        } catch (\Throwable $e) {
            return back()->withErrors(['manifestacao' => $e->getMessage()]);
        }

        return $retorno['ok']
            ? back()->with('status', 'Manifestação registrada na SEFAZ. O XML completo chega na próxima sincronização.')
            : back()->withErrors(['manifestacao' => "SEFAZ {$retorno['cstat']}: {$retorno['motivo']}"]);
    }
}
