<?php

namespace App\Controllers;

use App\Models\RoomModel;
use App\Models\RoomTypeModel;

/**
 * Redesigned to match a user-supplied "Room Types" mockup: stat cards,
 * photo thumbnails, a short code badge, curated-amenity icons, and
 * Active/Inactive status. The mockup's counts (12 room types, 48 rooms)
 * are just its sample data — the stat cards below are computed for real
 * from whatever room types/rooms actually exist for this tenant, not
 * hardcoded to match the mockup's numbers.
 */
class RoomTypeController extends BaseController
{
    public function index()
    {
        $model = new RoomTypeModel();

        $perPage = (int) ($this->request->getGet('perPage') ?: 10);
        $perPage = in_array($perPage, [10, 25, 50], true) ? $perPage : 10;

        $roomTypes = $model->orderBy('name')->paginate($perPage);
        $pager     = $model->pager;

        foreach ($roomTypes as $roomType) {
            $roomType->room_count      = $model->roomCount($roomType->id);
            $roomType->available_count = $model->availableCount($roomType->id);
            $roomType->display_code    = $model->displayCode($roomType);
        }

        $allTypes  = (new RoomTypeModel())->findAll();
        $totalRooms = (new RoomModel())->countAllResults();
        $avgRate   = count($allTypes) > 0
            ? array_sum(array_map(static fn ($t) => (float) $t->base_rate, $allTypes)) / count($allTypes)
            : 0;

        return view('room_types/index', [
            'pageTitle'  => 'Room Types',
            'pageIcon'   => 'bi-door-closed',
            'breadcrumb' => ['Rooms' => site_url('rooms/board'), 'Room Types' => null],
            'roomTypes'  => $roomTypes,
            'pager'      => $pager,
            'perPage'    => $perPage,
            'stats'      => [
                'totalTypes'   => count($allTypes),
                'totalRooms'   => $totalRooms,
                'availableNow' => (new RoomModel())->where('status', 'clean')->countAllResults(),
                'avgRate'      => number_format($avgRate, 0),
            ],
        ]);
    }

    public function new()
    {
        return view('room_types/form', [
            'pageTitle' => 'New Room Type',
            'roomType'  => null,
        ]);
    }

    public function create()
    {
        $model = new RoomTypeModel();

        $data = $this->collectInput();

        $upload = handle_image_upload($this->request->getFile('photo'), 'room-types');

        if ($upload['error'] !== null) {
            return redirect()->back()->withInput()->with('error', $upload['error']);
        }

        if ($upload['path'] !== null) {
            $data['photo_path'] = $upload['path'];
        }

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

        $this->logActivity('room_types', 'Created room type "' . $data['name'] . '".');

        return redirect()->to('room-types')->with('success', 'Room type created.');
    }

    public function edit(int $id)
    {
        $model    = new RoomTypeModel();
        $roomType = $model->find($id);

        if ($roomType === null) {
            return redirect()->to('room-types')->with('error', 'Room type not found.');
        }

        return view('room_types/form', [
            'pageTitle' => 'Edit Room Type',
            'roomType'  => $roomType,
        ]);
    }

    public function update(int $id)
    {
        $model = new RoomTypeModel();

        if ($model->find($id) === null) {
            return redirect()->to('room-types')->with('error', 'Room type not found.');
        }

        $data = $this->collectInput();

        $upload = handle_image_upload($this->request->getFile('photo'), 'room-types');

        if ($upload['error'] !== null) {
            return redirect()->back()->withInput()->with('error', $upload['error']);
        }

        if ($upload['path'] !== null) {
            $data['photo_path'] = $upload['path'];
        }

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

        $this->logActivity('room_types', 'Updated room type "' . $data['name'] . '".');

        return redirect()->to('room-types')->with('success', 'Room type updated.');
    }

    public function toggleActive(int $id)
    {
        $model    = new RoomTypeModel();
        $roomType = $model->find($id);

        if ($roomType === null) {
            return redirect()->to('room-types')->with('error', 'Room type not found.');
        }

        $model->update($id, ['is_active' => $roomType->is_active ? 0 : 1]);
        $this->logActivity('room_types', ($roomType->is_active ? 'Deactivated' : 'Activated') . ' room type "' . $roomType->name . '".');

        return redirect()->to('room-types')->with('success', 'Room type ' . ($roomType->is_active ? 'deactivated' : 'activated') . '.');
    }

    public function delete(int $id)
    {
        $model    = new RoomTypeModel();
        $roomType = $model->find($id);

        if ($roomType === null) {
            return redirect()->to('room-types')->with('error', 'Room type not found.');
        }

        if ($model->roomCount($id) > 0) {
            return redirect()->to('room-types')->with('error', 'Cannot delete a room type that still has rooms assigned to it.');
        }

        $model->delete($id);
        $this->logActivity('room_types', 'Deleted room type "' . $roomType->name . '".');

        return redirect()->to('room-types')->with('success', 'Room type deleted.');
    }

    private function collectInput(): array
    {
        // Curated checkboxes (exact labels from RoomTypeModel::CURATED_AMENITIES)
        // plus a free-text "other" field for anything not on that list —
        // keeps the icon-list mockup look without forcing amenities into
        // a closed enum (see the model's doc comment).
        $checked = $this->request->getPost('amenities') ?? [];
        $checked = is_array($checked) ? array_intersect($checked, array_keys(RoomTypeModel::CURATED_AMENITIES)) : [];

        $otherRaw = (string) ($this->request->getPost('amenities_other') ?? '');
        $other    = array_values(array_filter(array_map('trim', explode(',', $otherRaw))));

        $amenities = array_values(array_unique(array_merge($checked, $other)));

        return [
            'name'        => $this->request->getPost('name'),
            'code'        => strtoupper(trim((string) $this->request->getPost('code'))) ?: null,
            'description' => $this->request->getPost('description'),
            'base_rate'   => parse_money($this->request->getPost('base_rate')),
            'capacity'    => (int) $this->request->getPost('capacity'),
            'amenities'   => json_encode($amenities),
            'is_active'   => $this->request->getPost('is_active') ? 1 : 0,
        ];
    }
}
