<?php
declare(strict_types=1);

namespace App\Controllers\Web;

use App\Middleware\AuthSession;
use App\Middleware\TenantScope;
use App\Lib\Pdf;
use App\Models\Asset;
use App\Models\Attachment;
use App\Models\FailureCode;
use App\Models\Incident;
use App\Models\Site;
use App\Models\Tenant;
use App\Models\User;
use Core\Controller;
use Core\Session;
use Core\Tool;

final class IncidentsController extends Controller
{
    public function middleware(): array
    {
        return [AuthSession::class, TenantScope::class];
    }

    private function tenantId(): int
    {
        return (int) ($_SESSION['tenant_id'] ?? 0);
    }

    public function index(): void
    {
        $filters = [
            'category' => $_GET['category'] ?? null,
            'severity' => $_GET['severity'] ?? null,
            'status'   => $_GET['status']   ?? null,
            'asset_id' => $_GET['asset_id'] ?? null,
            'q'        => $_GET['q']        ?? null,
        ];
        $sort = $_GET['sort'] ?? 'newest';
        $this->render('incidents/index', [
            'incidents' => Incident::listForTenant($this->tenantId(), array_filter($filters), $sort),
            'sort'      => $sort,
            'filters'   => $filters,
            'flash'     => Session::flash('incidents_msg'),
        ]);
    }

    public function create(): void
    {
        $tenantId = $this->tenantId();
        $this->render('incidents/form', [
            'incident'     => null,
            'types'        => Incident::typesForTenant($tenantId),
            'failureCodes' => FailureCode::optionsForTenant($tenantId),
            'assets'       => Asset::optionsForTenant($tenantId),
            'sites'        => Site::optionsForTenant($tenantId),
            'users'        => User::listForTenant($tenantId),
            'csrf'         => Tool::generateCsrf(),
        ]);
    }

    public function edit(int $id): void
    {
        $tenantId = $this->tenantId();
        $incident = Incident::findInTenant($tenantId, $id);
        if (!$incident) { Session::flash('incidents_msg', 'Incident not found.'); redirect('/Incidents'); }
        $this->render('incidents/form', [
            'incident'     => $incident,
            'types'        => Incident::typesForTenant($tenantId),
            'failureCodes' => FailureCode::optionsForTenant($tenantId),
            'assets'       => Asset::optionsForTenant($tenantId),
            'sites'        => Site::optionsForTenant($tenantId),
            'users'        => User::listForTenant($tenantId),
            'csrf'         => Tool::generateCsrf(),
        ]);
    }

    public function save(): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') redirect('/Incidents');
        if (!Tool::checkCsrf($_POST['_csrf'] ?? null)) {
            Session::flash('incidents_msg', 'Session expired.'); redirect('/Incidents');
        }
        $tenantId = $this->tenantId();
        $userId   = (int) (Session::user()['user_id'] ?? 0);
        $id       = (int) ($_POST['incident_id'] ?? 0);

        if (trim((string) ($_POST['title'] ?? '')) === '') {
            Session::flash('incidents_msg', 'Title is required.');
            redirect($id > 0 ? "/Incidents/edit/{$id}" : '/Incidents/create');
        }

        if ($id > 0) {
            Incident::update($tenantId, $userId, $id, $_POST);
            Session::flash('incidents_msg', 'Incident updated.');
        } else {
            $id = Incident::create($tenantId, $userId, $_POST);
            Session::flash('incidents_msg', 'Incident created.');
        }
        redirect("/Incidents/show/{$id}");
    }

    public function show(int $id): void
    {
        $tenantId = $this->tenantId();
        $incident = Incident::findInTenant($tenantId, $id);
        if (!$incident) { Session::flash('incidents_msg', 'Incident not found.'); redirect('/Incidents'); }
        $this->render('incidents/show', [
            'incident'    => $incident,
            'events'      => Incident::eventsFor($id),
            'attachments' => Attachment::forOwner($tenantId, 'incident', $id),
            'ownerType'   => 'incident',
            'ownerId'     => $id,
            'flash'       => Session::flash('incidents_msg') ?: Session::flash('attach_msg'),
            'csrf'        => Tool::generateCsrf(),
        ]);
    }

    public function note(int $id): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') redirect("/Incidents/show/{$id}");
        if (!Tool::checkCsrf($_POST['_csrf'] ?? null)) { redirect("/Incidents/show/{$id}"); }
        $tenantId = $this->tenantId();
        $userId   = (int) (Session::user()['user_id'] ?? 0);
        $incident = Incident::findInTenant($tenantId, $id);
        if (!$incident) redirect('/Incidents');
        $msg = trim((string) ($_POST['message'] ?? ''));
        if ($msg !== '') {
            Incident::logEvent($id, $userId, 'note', null, null, $msg);
        }
        redirect("/Incidents/show/{$id}");
    }

    public function delete(int $id): void
    {
        Incident::softDelete($this->tenantId(), $id);
        Session::flash('incidents_msg', 'Incident deleted.');
        redirect('/Incidents');
    }

    public function pdf(int $id): void
    {
        $tenantId = $this->tenantId();
        $incident = Incident::findInTenant($tenantId, $id);
        if (!$incident) { http_response_code(404); echo 'Not found'; return; }
        $tenant = Tenant::findById($tenantId);
        $events = Incident::eventsFor($id);
        ob_start();
        require ROOT . '/app/Views/pdf/incident.php';
        $html = ob_get_clean();
        Pdf::stream($html, 'INC-' . ($incident['code'] ?: $id));
    }
}
