<?php

namespace App\Controllers;

use App\Models\HousekeepingTaskModel;
use App\Models\RoomModel;
use App\Models\UserModel;
use Config\Lookups;

/**
 * Housekeeping module — built for real from a user-supplied mockup
 * (previously a disabled "Soon" nav item). Every stat/chart here is
 * computed from real tasks/rooms, nothing fabricated: "Rooms to Clean"
 * is the live count of rooms with status=dirty (RoomModel), "Cleaned
 * Today"/"In Progress"/"Inspected" come straight from this module's own
 * tasks. The mockup's "82% of target" under Cleaned Today implied a
 * staffing/target metric this app has no concept of — omitted rather
 * than invented.
 */
class HousekeepingController extends BaseController
{
    public function index()
    {
        $tasks = new HousekeepingTaskModel();
        $rooms = new RoomModel();

        // Plain ORDER BY priority would sort alphabetically (high, low,
        // medium) — FIELD() spells out the real urgency order instead.
        $liveTasks = $tasks->withDetails()
            ->whereIn('housekeeping_tasks.status', ['not_started', 'in_progress'])
            ->orderBy("FIELD(housekeeping_tasks.priority, 'high', 'medium', 'low')", '', false)
            ->orderBy('housekeeping_tasks.created_at', 'asc')
            ->findAll();

        $roomStatusCounts = [];
        foreach (array_keys((new Lookups())->roomStatuses) as $key) {
            $roomStatusCounts[$key] = (new RoomModel())->where('status', $key)->countAllResults();
        }

        return view('housekeeping/index', [
            'pageTitle'    => 'Housekeeping',
            'pageSubtitle' => 'Manage room cleaning and housekeeping tasks.',
            'liveTasks'    => $liveTasks,
            'roomsToClean' => $roomStatusCounts['dirty'] ?? 0,
            'cleanedToday' => (new HousekeepingTaskModel())->countCompletedOn(date('Y-m-d')),
            'inProgress'   => (new HousekeepingTaskModel())->countByStatus('in_progress'),
            'inspected'    => (new HousekeepingTaskModel())->countInspected(),
            'outOfService' => $roomStatusCounts['out_of_service'] ?? 0,
            'totalRooms'   => $rooms->countAllResults(),
            'roomStatusCounts' => $roomStatusCounts,
            'completedTrend'   => (new HousekeepingTaskModel())->completedTrend(7),
            'lookups'      => new Lookups(),
        ]);
    }

    public function new()
    {
        return view('housekeeping/form', [
            'pageTitle' => 'New Housekeeping Task',
            'rooms'     => (new RoomModel())->withType()->orderBy('rooms.room_number')->findAll(),
            'staff'     => (new UserModel())->where('is_active', 1)->orderBy('full_name')->findAll(),
            'lookups'   => new Lookups(),
        ]);
    }

    public function create()
    {
        $tasks = new HousekeepingTaskModel();

        $data = [
            'room_id'     => (int) $this->request->getPost('room_id'),
            'task_type'   => $this->request->getPost('task_type'),
            'priority'    => $this->request->getPost('priority') ?: 'medium',
            'assigned_to' => $this->request->getPost('assigned_to') ?: null,
            'notes'       => $this->request->getPost('notes') ?: null,
            'status'      => 'not_started',
        ];

        if (! $tasks->insert($data)) {
            return $this->redirectWithModelErrors($tasks);
        }

        $room = (new RoomModel())->find($data['room_id']);
        $this->logActivity('housekeeping', "Created {$data['task_type']} task for room {$room->room_number}.");

        return redirect()->to('housekeeping')->with('success', 'Task created.');
    }

    public function start(int $id)
    {
        $tasks = new HousekeepingTaskModel();
        $task  = $tasks->find($id);

        if ($task === null) {
            return redirect()->to('housekeeping')->with('error', 'Task not found.');
        }

        $tasks->update($id, ['status' => 'in_progress', 'start_time' => date('Y-m-d H:i:s')]);
        $this->logActivity('housekeeping', "Started task #{$id}.");

        return redirect()->to('housekeeping')->with('success', 'Task started.');
    }

    /**
     * Completing a task also marks the room clean — this module and the
     * Room Management board must never disagree about a room's status.
     */
    public function complete(int $id)
    {
        $tasks = new HousekeepingTaskModel();
        $task  = $tasks->find($id);

        if ($task === null) {
            return redirect()->to('housekeeping')->with('error', 'Task not found.');
        }

        $tasks->update($id, ['status' => 'completed', 'completed_at' => date('Y-m-d H:i:s')]);

        $room = (new RoomModel())->find($task->room_id);

        if ($room !== null && $room->status === 'dirty') {
            (new RoomModel())->setStatus($room->id, 'clean');
        }

        $this->logActivity('housekeeping', "Completed task #{$id}" . ($room ? " for room {$room->room_number}" : '') . '.');

        return redirect()->to('housekeeping')->with('success', 'Task completed — room marked clean.');
    }

    public function inspect(int $id)
    {
        $tasks = new HousekeepingTaskModel();
        $task  = $tasks->find($id);

        if ($task === null || $task->status !== 'completed') {
            return redirect()->to('housekeeping')->with('error', 'Only a completed task can be inspected.');
        }

        $tasks->update($id, ['inspected_at' => date('Y-m-d H:i:s'), 'inspected_by' => $this->currentUserId()]);
        $this->logActivity('housekeeping', "Inspected task #{$id}.");

        return redirect()->to('housekeeping')->with('success', 'Task marked inspected.');
    }

    public function show(int $id)
    {
        $task = (new HousekeepingTaskModel())->withDetails()->where('housekeeping_tasks.id', $id)->first();

        if ($task === null) {
            return redirect()->to('housekeeping')->with('error', 'Task not found.');
        }

        $inspector = $task->inspected_by ? (new UserModel())->find($task->inspected_by) : null;

        return view('housekeeping/show', [
            'pageTitle'    => 'Housekeeping Task #' . $id,
            'task'         => $task,
            'inspectorName' => $inspector->full_name ?? null,
            'lookups'      => new Lookups(),
        ]);
    }

    /**
     * Edits the task's assignment details only (room/type/priority/
     * assignee/notes) — reuses housekeeping/form.php in edit mode. The
     * workflow status itself is never hand-edited here; it only moves
     * forward through start()/complete()/inspect() so it can't drift out
     * of sync with timestamps or the linked room's status.
     */
    public function edit(int $id)
    {
        $tasks = new HousekeepingTaskModel();
        $task  = $tasks->withDetails()->where('housekeeping_tasks.id', $id)->first();

        if ($task === null) {
            return redirect()->to('housekeeping')->with('error', 'Task not found.');
        }

        return view('housekeeping/form', [
            'pageTitle' => 'Edit Housekeeping Task',
            'task'      => $task,
            'rooms'     => (new RoomModel())->withType()->orderBy('rooms.room_number')->findAll(),
            'staff'     => (new UserModel())->where('is_active', 1)->orderBy('full_name')->findAll(),
            'lookups'   => new Lookups(),
        ]);
    }

    public function update(int $id)
    {
        $tasks = new HousekeepingTaskModel();

        if ($tasks->find($id) === null) {
            return redirect()->to('housekeeping')->with('error', 'Task not found.');
        }

        $data = [
            'room_id'     => (int) $this->request->getPost('room_id'),
            'task_type'   => $this->request->getPost('task_type'),
            'priority'    => $this->request->getPost('priority') ?: 'medium',
            'assigned_to' => $this->request->getPost('assigned_to') ?: null,
            'notes'       => $this->request->getPost('notes') ?: null,
        ];

        if (! $tasks->update($id, $data)) {
            return $this->redirectWithModelErrors($tasks);
        }

        $this->logActivity('housekeeping', "Updated task #{$id}.");

        return redirect()->to('housekeeping/' . $id)->with('success', 'Task updated.');
    }
}
