<?php
declare(strict_types=1);

namespace App\Controllers\Web;

use App\Middleware\AuthSession;
use App\Middleware\TenantScope;
use App\Models\Asset;
use App\Models\AssetType;
use App\Models\PmTemplate;
use App\Models\Role;
use App\Models\User;
use Core\Controller;
use Core\Session;
use Core\Tool;

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

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

    private function guardAdmin(): void
    {
        $role = Session::user()['role_code'] ?? '';
        if (!in_array($role, [Role::ADMIN, Role::EXECUTIVE, Role::PROJECT_MANAGER], true)) {
            Session::flash('pm_msg', 'You do not have permission to manage PM templates.');
            redirect('/Home');
        }
    }

    public function index(): void
    {
        $this->guardAdmin();
        $this->render('pm-templates/index', [
            'templates' => PmTemplate::listForTenant($this->tenantId()),
            'flash'     => Session::flash('pm_msg'),
        ]);
    }

    public function create(): void
    {
        $this->guardAdmin();
        $this->render('pm-templates/form', [
            'template'   => null,
            'assetTypes' => AssetType::optionsForTenant($this->tenantId()),
            'csrf'       => Tool::generateCsrf(),
        ]);
    }

    public function edit(int $id): void
    {
        $this->guardAdmin();
        $tpl = PmTemplate::findInTenant($this->tenantId(), $id);
        if (!$tpl) { Session::flash('pm_msg', 'Template not found.'); redirect('/PmTemplates'); }
        $this->render('pm-templates/form', [
            'template'   => $tpl,
            'assetTypes' => AssetType::optionsForTenant($this->tenantId()),
            'csrf'       => Tool::generateCsrf(),
        ]);
    }

    public function save(): void
    {
        $this->guardAdmin();
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') redirect('/PmTemplates');
        if (!Tool::checkCsrf($_POST['_csrf'] ?? null)) { Session::flash('pm_msg', 'Session expired.'); redirect('/PmTemplates'); }
        $tenantId = $this->tenantId();
        $id       = (int) ($_POST['template_id'] ?? 0);
        if (trim((string) ($_POST['name'] ?? '')) === '') {
            Session::flash('pm_msg', 'Name is required.');
            redirect($id > 0 ? "/PmTemplates/edit/{$id}" : '/PmTemplates/create');
        }
        if ($id > 0) {
            PmTemplate::update($tenantId, $id, $_POST);
            Session::flash('pm_msg', 'Template updated.');
        } else {
            $id = PmTemplate::create($tenantId, $_POST);
            Session::flash('pm_msg', 'Template created.');
        }
        redirect("/PmTemplates/show/{$id}");
    }

    public function show(int $id): void
    {
        $this->guardAdmin();
        $tenantId = $this->tenantId();
        $tpl = PmTemplate::findInTenant($tenantId, $id);
        if (!$tpl) { Session::flash('pm_msg', 'Template not found.'); redirect('/PmTemplates'); }
        $this->render('pm-templates/show', [
            'template'  => $tpl,
            'tasks'     => PmTemplate::tasksFor($id),
            'schedules' => PmTemplate::schedulesForTemplate($tenantId, $id),
            'assets'    => Asset::optionsForTenant($tenantId),
            'users'     => User::listForTenant($tenantId),
            'flash'     => Session::flash('pm_msg'),
            'csrf'      => Tool::generateCsrf(),
        ]);
    }

    public function delete(int $id): void
    {
        $this->guardAdmin();
        if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' && !Tool::checkCsrf($_POST['_csrf'] ?? null)) {
            redirect("/PmTemplates/edit/{$id}");
        }
        PmTemplate::softDelete($this->tenantId(), $id);
        Session::flash('pm_msg', 'Template deleted.');
        redirect('/PmTemplates');
    }

    public function addTask(int $templateId): void
    {
        $this->guardAdmin();
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') redirect("/PmTemplates/show/{$templateId}");
        if (!Tool::checkCsrf($_POST['_csrf'] ?? null)) redirect("/PmTemplates/show/{$templateId}");
        if (!PmTemplate::findInTenant($this->tenantId(), $templateId)) redirect('/PmTemplates');
        if (trim((string) ($_POST['title'] ?? '')) !== '') {
            PmTemplate::addTask($templateId, $_POST);
            Session::flash('pm_msg', 'Task added.');
        }
        redirect("/PmTemplates/show/{$templateId}");
    }

    public function editTask(int $templateTaskId): void
    {
        $this->guardAdmin();
        $task = PmTemplate::taskInTenant($this->tenantId(), $templateTaskId);
        if (!$task) { Session::flash('pm_msg', 'Task not found.'); redirect('/PmTemplates'); }
        $tpl = PmTemplate::findInTenant($this->tenantId(), (int) $task['template_id']);
        $this->render('pm-templates/edit-task', [
            'template' => $tpl,
            'task'     => $task,
            'csrf'     => Tool::generateCsrf(),
        ]);
    }

    public function updateTask(int $templateTaskId): void
    {
        $this->guardAdmin();
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') redirect('/PmTemplates');
        if (!Tool::checkCsrf($_POST['_csrf'] ?? null)) redirect('/PmTemplates');
        $task = PmTemplate::taskInTenant($this->tenantId(), $templateTaskId);
        if (!$task) redirect('/PmTemplates');
        if (trim((string) ($_POST['title'] ?? '')) === '') {
            Session::flash('pm_msg', 'Title is required.');
            redirect("/PmTemplates/editTask/{$templateTaskId}");
        }
        PmTemplate::updateTask($templateTaskId, $_POST);
        Session::flash('pm_msg', 'Task updated.');
        redirect('/PmTemplates/show/' . (int) $task['template_id']);
    }

    public function moveTask(int $templateTaskId, string $direction = 'up'): void
    {
        $this->guardAdmin();
        $task = PmTemplate::taskInTenant($this->tenantId(), $templateTaskId);
        if (!$task) redirect('/PmTemplates');
        PmTemplate::moveTask($templateTaskId, $direction);
        redirect('/PmTemplates/show/' . (int) $task['template_id']);
    }

    public function deleteTask(int $templateTaskId): void
    {
        $this->guardAdmin();
        $task = PmTemplate::taskInTenant($this->tenantId(), $templateTaskId);
        if (!$task) redirect('/PmTemplates');
        // Accept POST-with-CSRF (from jquery-confirm forms) or a legacy GET link.
        if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' && !Tool::checkCsrf($_POST['_csrf'] ?? null)) {
            redirect('/PmTemplates/show/' . (int) $task['template_id']);
        }
        PmTemplate::deleteTask($templateTaskId);
        Session::flash('pm_msg', 'Task removed.');
        redirect('/PmTemplates/show/' . (int) $task['template_id']);
    }

    public function addSchedule(int $templateId): void
    {
        $this->guardAdmin();
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') redirect("/PmTemplates/show/{$templateId}");
        if (!Tool::checkCsrf($_POST['_csrf'] ?? null)) redirect("/PmTemplates/show/{$templateId}");
        $tenantId = $this->tenantId();
        if (!PmTemplate::findInTenant($tenantId, $templateId)) redirect('/PmTemplates');
        if (empty($_POST['asset_id'])) {
            Session::flash('pm_msg', 'Pick an asset.');
            redirect("/PmTemplates/show/{$templateId}");
        }
        PmTemplate::addSchedule($tenantId, $templateId, $_POST);
        Session::flash('pm_msg', 'Schedule added.');
        redirect("/PmTemplates/show/{$templateId}");
    }

    public function deleteSchedule(int $scheduleId): void
    {
        $this->guardAdmin();
        $tenantId = $this->tenantId();
        // Look up template so we can redirect back cleanly.
        $sched = \Core\DB::one(
            'SELECT template_id FROM pm_schedules WHERE tenant_id = :t AND schedule_id = :id',
            ['t' => $tenantId, 'id' => $scheduleId]
        );
        if (!$sched) redirect('/PmTemplates');
        if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' && !Tool::checkCsrf($_POST['_csrf'] ?? null)) {
            redirect('/PmTemplates/show/' . (int) $sched['template_id']);
        }
        PmTemplate::deleteSchedule($tenantId, $scheduleId);
        Session::flash('pm_msg', 'Schedule removed.');
        redirect('/PmTemplates/show/' . (int) $sched['template_id']);
    }
}
