<?php
declare(strict_types=1);

namespace App\Controllers\Web;

use App\Lib\DashboardStats;
use App\Middleware\AuthSession;
use App\Middleware\TenantScope;
use App\Models\Incident;
use App\Models\Role;
use App\Models\Tenant;
use App\Models\WorkOrder;
use Core\Controller;
use Core\Session;

/**
 * Read-only tenant-scoped dashboard for role=client.
 * Also accessible to admin/exec/PM for cross-role visibility.
 */
final class ClientPortalController extends Controller
{
    public function middleware(): array
    {
        return [AuthSession::class, TenantScope::class];
    }

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

    private function guard(): void
    {
        $role = Session::user()['role_code'] ?? '';
        if (!in_array($role, [Role::CLIENT, Role::ADMIN, Role::EXECUTIVE, Role::PROJECT_MANAGER], true)) {
            Session::flash('portal_msg', 'You do not have access to the client portal.');
            redirect('/Home');
        }
    }

    public function index(): void
    {
        $this->guard();
        $tenantId = $this->tenantId();
        $stats    = DashboardStats::compute($tenantId);

        // Reuse the executive dashboard view — same charts, same shape,
        // just labelled "Client Portal" and no exec-only tables at the bottom.
        $this->render('home/index', array_merge($stats, [
            'user'          => Session::user(),
            'tenant'        => Tenant::findById($tenantId),
            'dashboardMode' => 'client',
            'title'         => 'Client Portal · Dashboard',
        ]));
    }

    /**
     * Client-scoped AJAX endpoint powering the Vue-driven date-range refresh.
     * Same contract as HomeController::data, but under /ClientPortal/data so
     * the front-end can call the right URL when it's rendered in the portal.
     */
    public function data(): void
    {
        $this->guard();
        $tenantId = $this->tenantId();
        $from = trim((string) ($_GET['from'] ?? '')) ?: null;
        $to   = trim((string) ($_GET['to']   ?? '')) ?: null;
        foreach (['from' => $from, 'to' => $to] as $k => $v) {
            if ($v !== null && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $v)) {
                $this->json(['error' => "Bad {$k} — expected YYYY-MM-DD"], 422);
            }
        }
        if ($from && $to && strtotime($from) > strtotime($to)) {
            $this->json(['error' => 'from cannot be after to'], 422);
        }
        $this->json(DashboardStats::compute($tenantId, $from, $to));
    }

    public function incidents(): void
    {
        $this->guard();
        $tenantId = $this->tenantId();
        $filters = array_filter([
            'status'   => $_GET['status']   ?? null,
            'severity' => $_GET['severity'] ?? null,
        ]);
        $this->render('client-portal/incidents', [
            'incidents' => Incident::listForTenant($tenantId, $filters),
            'filters'   => $filters,
            'title'     => 'Incidents · Client Portal',
        ]);
    }

    public function workOrders(): void
    {
        $this->guard();
        $tenantId = $this->tenantId();
        $filters = array_filter([
            'status'   => $_GET['status']   ?? null,
            'priority' => $_GET['priority'] ?? null,
        ]);
        $this->render('client-portal/work-orders', [
            'orders'  => WorkOrder::listForTenant($tenantId, $filters),
            'filters' => $filters,
            'title'   => 'Work Orders · Client Portal',
        ]);
    }
}
