<?php
declare(strict_types=1);

namespace App\Modules\SportsActivity\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Core\Pagination;
use App\Modules\SportsActivity\Models\Locker;

class LockerController extends Controller
{
    public function index(Request $request): Response
    {
        $this->authorize('sa.locker.view');

        $db = App::getInstance()->db();

        $search = trim((string) $request->get('q', ''));
        $facilityId = (int) $request->get('facility_id', 0);
        $disciplineId = (int) $request->get('discipline_id', 0);
        $lockerType = trim((string) $request->get('locker_type', ''));
        $page = max(1, (int) $request->get('page', 1));
        $perPage = 25;

        $where = ['l.is_archived = 0'];
        $params = [];

        if ($search !== '') {
            $where[] = '(l.code LIKE ? OR l.name_ar LIKE ? OR l.name_en LIKE ?)';
            $params[] = "%{$search}%";
            $params[] = "%{$search}%";
            $params[] = "%{$search}%";
        }
        if ($facilityId > 0) {
            $where[] = 'l.facility_id = ?';
            $params[] = $facilityId;
        }
        if ($disciplineId > 0) {
            $where[] = 'l.discipline_id = ?';
            $params[] = $disciplineId;
        }
        if ($lockerType !== '') {
            $where[] = 'l.locker_type = ?';
            $params[] = $lockerType;
        }

        $whereSql = implode(' AND ', $where);

        $total = (int) $db->selectOne(
            "SELECT COUNT(*) as cnt FROM sa_lockers l WHERE {$whereSql}",
            $params
        )['cnt'];

        $pagination = Pagination::paginate($total, $perPage, $page);
        $offset = ($page - 1) * $perPage;

        $lockers = $db->select(
            "SELECT l.*, f.name_ar as facility_name, d.name_ar as discipline_name
             FROM sa_lockers l
             LEFT JOIN sa_facilities f ON f.id = l.facility_id
             LEFT JOIN sa_disciplines d ON d.id = l.discipline_id
             WHERE {$whereSql}
             ORDER BY l.created_at DESC
             LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

        // Check occupation status for each locker
        foreach ($lockers as &$locker) {
            $rental = $db->selectOne(
                "SELECT id FROM sa_locker_rentals WHERE locker_id = ? AND status IN ('active','grace_period','pending_eviction') AND is_archived = 0 LIMIT 1",
                [(int) $locker['id']]
            );
            $locker['is_occupied'] = $rental !== null;
        }
        unset($locker);

        $facilities = $db->select("SELECT id, name_ar FROM sa_facilities WHERE is_archived = 0 ORDER BY name_ar");
        $disciplines = $db->select("SELECT id, name_ar FROM sa_disciplines WHERE is_archived = 0 ORDER BY name_ar");

        return $this->view('SportsActivity.Views.lockers.index', [
            'lockers'      => $lockers,
            'pagination'   => $pagination,
            'search'       => $search,
            'facilityId'   => $facilityId,
            'disciplineId' => $disciplineId,
            'lockerType'   => $lockerType,
            'facilities'   => $facilities,
            'disciplines'  => $disciplines,
            'typeOptions'  => Locker::getTypeOptions(),
        ]);
    }

    public function create(Request $request): Response
    {
        $this->authorize('sa.locker.manage');

        $db = App::getInstance()->db();
        $facilities = $db->select("SELECT id, name_ar FROM sa_facilities WHERE is_archived = 0 ORDER BY name_ar");
        $disciplines = $db->select("SELECT id, name_ar FROM sa_disciplines WHERE is_archived = 0 ORDER BY name_ar");

        return $this->view('SportsActivity.Views.lockers.create', [
            'facilities'  => $facilities,
            'disciplines' => $disciplines,
            'typeOptions' => Locker::getTypeOptions(),
        ]);
    }

    public function store(Request $request): Response
    {
        $this->authorize('sa.locker.manage');

        $db = App::getInstance()->db();

        $code = trim((string) $request->post('code', ''));
        $nameAr = trim((string) $request->post('name_ar', ''));
        $nameEn = trim((string) $request->post('name_en', ''));
        $facilityId = (int) $request->post('facility_id', 0);
        $disciplineId = (int) $request->post('discipline_id', 0);
        $lockerType = trim((string) $request->post('locker_type', ''));
        $locationNote = trim((string) $request->post('location_note', ''));

        // Validation
        $errors = [];
        if ($code === '') {
            $errors[] = 'كود اللوكر مطلوب';
        } elseif (mb_strlen($code) > 30) {
            $errors[] = 'كود اللوكر يجب ألا يتجاوز 30 حرف';
        }
        if ($nameAr === '') {
            $errors[] = 'اسم اللوكر بالعربي مطلوب';
        } elseif (mb_strlen($nameAr) > 200) {
            $errors[] = 'اسم اللوكر يجب ألا يتجاوز 200 حرف';
        }
        if ($lockerType === '' || !array_key_exists($lockerType, Locker::getTypeOptions())) {
            $errors[] = 'نوع اللوكر مطلوب';
        }
        if ($code !== '' && Locker::findByCode($code) !== null) {
            $errors[] = 'كود اللوكر مستخدم بالفعل';
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $alerts = array_map(fn($msg) => ['type' => 'error', 'message' => $msg], $errors);
            $session->flash('_alerts', $alerts);
            $session->flash('_old_input', $request->all());
            return $this->redirect('/sa/lockers/create');
        }

        Locker::create([
            'code'          => $code,
            'name_ar'       => $nameAr,
            'name_en'       => $nameEn ?: null,
            'facility_id'   => $facilityId > 0 ? $facilityId : null,
            'discipline_id' => $disciplineId > 0 ? $disciplineId : null,
            'locker_type'   => $lockerType,
            'location_note' => $locationNote ?: null,
            'is_active'     => 1,
        ]);

        return $this->redirect('/sa/lockers')->withSuccess('تم إضافة اللوكر بنجاح');
    }

    public function show(Request $request, string $id): Response
    {
        $this->authorize('sa.locker.view');

        $db = App::getInstance()->db();

        $locker = $db->selectOne(
            "SELECT l.*, f.name_ar as facility_name, d.name_ar as discipline_name
             FROM sa_lockers l
             LEFT JOIN sa_facilities f ON f.id = l.facility_id
             LEFT JOIN sa_disciplines d ON d.id = l.discipline_id
             WHERE l.id = ? AND l.is_archived = 0",
            [(int) $id]
        );

        if (!$locker) {
            return $this->redirect('/sa/lockers')->withError('اللوكر غير موجود');
        }

        // Current rental
        $currentRental = $db->selectOne(
            "SELECT lr.*, p.full_name_ar as player_name
             FROM sa_locker_rentals lr
             LEFT JOIN sa_players p ON p.id = lr.player_id
             WHERE lr.locker_id = ? AND lr.status IN ('active','grace_period','pending_eviction') AND lr.is_archived = 0
             ORDER BY lr.start_date DESC LIMIT 1",
            [(int) $id]
        );

        // Rental history
        $rentalHistory = $db->select(
            "SELECT lr.*, p.full_name_ar as player_name
             FROM sa_locker_rentals lr
             LEFT JOIN sa_players p ON p.id = lr.player_id
             WHERE lr.locker_id = ? AND lr.is_archived = 0
             ORDER BY lr.start_date DESC
             LIMIT 20",
            [(int) $id]
        );

        return $this->view('SportsActivity.Views.lockers.show', [
            'locker'        => $locker,
            'currentRental' => $currentRental,
            'rentalHistory' => $rentalHistory,
            'typeOptions'   => Locker::getTypeOptions(),
            'statusOptions' => \App\Modules\SportsActivity\Models\LockerRental::getStatusOptions(),
            'rentalTypeOptions' => \App\Modules\SportsActivity\Models\LockerRental::getRentalTypeOptions(),
        ]);
    }

    public function edit(Request $request, string $id): Response
    {
        $this->authorize('sa.locker.manage');

        $db = App::getInstance()->db();

        $locker = $db->selectOne(
            "SELECT * FROM sa_lockers WHERE id = ? AND is_archived = 0",
            [(int) $id]
        );

        if (!$locker) {
            return $this->redirect('/sa/lockers')->withError('اللوكر غير موجود');
        }

        $facilities = $db->select("SELECT id, name_ar FROM sa_facilities WHERE is_archived = 0 ORDER BY name_ar");
        $disciplines = $db->select("SELECT id, name_ar FROM sa_disciplines WHERE is_archived = 0 ORDER BY name_ar");

        return $this->view('SportsActivity.Views.lockers.edit', [
            'locker'      => $locker,
            'facilities'  => $facilities,
            'disciplines' => $disciplines,
            'typeOptions' => Locker::getTypeOptions(),
        ]);
    }

    public function update(Request $request, string $id): Response
    {
        $this->authorize('sa.locker.manage');

        $db = App::getInstance()->db();

        $locker = $db->selectOne(
            "SELECT * FROM sa_lockers WHERE id = ? AND is_archived = 0",
            [(int) $id]
        );

        if (!$locker) {
            return $this->redirect('/sa/lockers')->withError('اللوكر غير موجود');
        }

        $code = trim((string) $request->post('code', ''));
        $nameAr = trim((string) $request->post('name_ar', ''));
        $nameEn = trim((string) $request->post('name_en', ''));
        $facilityId = (int) $request->post('facility_id', 0);
        $disciplineId = (int) $request->post('discipline_id', 0);
        $lockerType = trim((string) $request->post('locker_type', ''));
        $locationNote = trim((string) $request->post('location_note', ''));

        // Validation
        $errors = [];
        if ($code === '') {
            $errors[] = 'كود اللوكر مطلوب';
        } elseif (mb_strlen($code) > 30) {
            $errors[] = 'كود اللوكر يجب ألا يتجاوز 30 حرف';
        }
        if ($nameAr === '') {
            $errors[] = 'اسم اللوكر بالعربي مطلوب';
        } elseif (mb_strlen($nameAr) > 200) {
            $errors[] = 'اسم اللوكر يجب ألا يتجاوز 200 حرف';
        }
        if ($lockerType === '' || !array_key_exists($lockerType, Locker::getTypeOptions())) {
            $errors[] = 'نوع اللوكر مطلوب';
        }
        if ($code !== '' && $code !== $locker['code']) {
            $existing = Locker::findByCode($code);
            if ($existing !== null && (int) $existing->id !== (int) $id) {
                $errors[] = 'كود اللوكر مستخدم بالفعل';
            }
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $alerts = array_map(fn($msg) => ['type' => 'error', 'message' => $msg], $errors);
            $session->flash('_alerts', $alerts);
            $session->flash('_old_input', $request->all());
            return $this->redirect("/sa/lockers/{$id}/edit");
        }

        $db->update('sa_lockers', [
            'code'          => $code,
            'name_ar'       => $nameAr,
            'name_en'       => $nameEn ?: null,
            'facility_id'   => $facilityId > 0 ? $facilityId : null,
            'discipline_id' => $disciplineId > 0 ? $disciplineId : null,
            'locker_type'   => $lockerType,
            'location_note' => $locationNote ?: null,
            'updated_at'    => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        return $this->redirect('/sa/lockers')->withSuccess('تم تحديث بيانات اللوكر بنجاح');
    }

    public function toggle(Request $request, string $id): Response
    {
        $this->authorize('sa.locker.manage');

        $db = App::getInstance()->db();

        $locker = $db->selectOne(
            "SELECT * FROM sa_lockers WHERE id = ? AND is_archived = 0",
            [(int) $id]
        );

        if (!$locker) {
            return $this->redirect('/sa/lockers')->withError('اللوكر غير موجود');
        }

        $newStatus = (int) $locker['is_active'] === 1 ? 0 : 1;

        $db->update('sa_lockers', [
            'is_active'  => $newStatus,
            'updated_at' => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        $msg = $newStatus === 1 ? 'تم تفعيل اللوكر' : 'تم تعطيل اللوكر';
        return $this->redirect('/sa/lockers')->withSuccess($msg);
    }
}
