<?php

namespace App\Http\Controllers;

use App\Services\LogViewerService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class LogViewerController extends Controller
{
    public function __construct(
        protected LogViewerService $logService
    ) {}

    /**
     * Display the log viewer dashboard.
     */
    public function index(Request $request): View|RedirectResponse
    {
        $files = $this->logService->getLogFiles();

        if (empty($files)) {
            return view('logs.index', [
                'files' => [],
                'currentFile' => null,
                'currentFileSize' => '0 B',
                'entries' => [],
                'totalParsed' => 0,
                'shownCount' => 0,
                'level' => 'ALL',
                'tail' => '200',
                'search' => '',
                'supportedLevels' => LogViewerService::SUPPORTED_LEVELS,
                'tailOptions' => LogViewerService::TAIL_OPTIONS,
            ]);
        }

        $requestedFile = $request->query('file');
        $defaultFile = $this->logService->getDefaultLogFile($files);
        $currentFile = $requestedFile ?: $defaultFile;

        $filePath = $this->logService->getSecureFilePath((string) $currentFile);

        // If requested file does not exist, redirect to default
        if (! $filePath || ! file_exists($filePath)) {
            if ($requestedFile && $requestedFile !== $defaultFile && $defaultFile) {
                return redirect()->route('logs.index', [
                    'file' => $defaultFile,
                    'level' => $request->query('level', 'ALL'),
                    'tail' => $request->query('tail', '200'),
                ])->with('warning', "Log file '{$requestedFile}' was not found.");
            }

            $currentFile = $defaultFile;
            $filePath = $defaultFile ? $this->logService->getSecureFilePath($defaultFile) : null;
        }

        $level = strtoupper(trim((string) $request->query('level', 'ALL')));
        if (! array_key_exists($level, LogViewerService::SUPPORTED_LEVELS)) {
            $level = 'ALL';
        }

        $tail = strtolower(trim((string) $request->query('tail', '200')));
        if (! array_key_exists($tail, LogViewerService::TAIL_OPTIONS)) {
            $tail = '200';
        }

        $search = trim((string) $request->query('search', ''));

        $parseResult = $filePath ? $this->logService->parseFile($filePath, [
            'level' => $level,
            'tail' => $tail,
            'search' => $search,
        ]) : [
            'entries' => [],
            'total_parsed' => 0,
            'shown_count' => 0,
            'file_size_formatted' => '0 B',
            'file_size_bytes' => 0,
        ];

        return view('logs.index', [
            'files' => $files,
            'currentFile' => $currentFile,
            'currentFileSize' => $parseResult['file_size_formatted'],
            'entries' => $parseResult['entries'],
            'totalParsed' => $parseResult['total_parsed'],
            'shownCount' => $parseResult['shown_count'],
            'level' => $level,
            'tail' => $tail,
            'search' => $search,
            'supportedLevels' => LogViewerService::SUPPORTED_LEVELS,
            'tailOptions' => LogViewerService::TAIL_OPTIONS,
        ]);
    }

    /**
     * Download the requested log file.
     */
    public function download(Request $request): BinaryFileResponse|RedirectResponse
    {
        $file = $request->query('file');
        if (empty($file)) {
            return redirect()->route('logs.index')->with('error', 'No log file specified for download.');
        }

        $filePath = $this->logService->getSecureFilePath((string) $file);
        if (! $filePath || ! file_exists($filePath)) {
            return redirect()->route('logs.index')->with('error', 'Requested log file was not found.');
        }

        return response()->download($filePath, basename($filePath), [
            'Content-Type' => 'text/plain; charset=UTF-8',
        ]);
    }

    /**
     * Clear or delete logs.
     */
    public function clear(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'action' => 'required|string|in:clear_current,delete_current,delete_old,delete_all',
            'file' => 'nullable|string',
        ]);

        $result = $this->logService->clearLogs($validated['action'], $validated['file'] ?? null);

        $flashType = $result['success'] ? 'success' : 'error';

        $redirectParams = [];
        if ($validated['action'] === 'clear_current' && ! empty($validated['file'])) {
            $redirectParams['file'] = $validated['file'];
        }

        return redirect()->route('logs.index', $redirectParams)->with($flashType, $result['message']);
    }
}
