<?php
declare(strict_types=1);

namespace App\Modules\Disciplines\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Disciplines\Models\SportDiscipline;

class DisciplineController extends Controller
{
    /**
     * List all disciplines with category filter tabs and search.
     */
    public function index(Request $request): Response
    {
        $filters = [
            'q'        => trim((string) $request->get('q', '')),
            'category' => trim((string) $request->get('category', '')),
        ];

        $page = max(1, (int) $request->get('page', 1));
        $result = SportDiscipline::search($filters, 25, $page);

        return $this->view('Disciplines.Views.index', [
            'disciplines' => $result['data'],
            'pagination'  => $result['pagination'],
            'filters'     => $filters,
            'categories'  => SportDiscipline::getCategories(),
        ]);
    }

    /**
     * Show the create discipline form.
     */
    public function create(Request $request): Response
    {
        return $this->view('Disciplines.Views.create', [
            'categories' => SportDiscipline::getCategories(),
        ]);
    }

    /**
     * Validate and store a new discipline.
     */
    public function store(Request $request): Response
    {
        $nameAr = trim((string) $request->post('name_ar', ''));
        $nameEn = trim((string) $request->post('name_en', ''));
        $code = trim((string) $request->post('code', ''));
        $category = trim((string) $request->post('category', ''));
        $icon = trim((string) $request->post('icon', 'activity'));
        $descriptionAr = trim((string) $request->post('description_ar', ''));
        $sortOrder = (int) $request->post('sort_order', 0);

        // Auto-generate code if empty
        if ($code === '') {
            $base = $nameEn ?: $nameAr;
            $code = strtoupper(preg_replace('/[^A-Z0-9]/i', '_', $base));
            $code = substr($code, 0, 25) . '_' . time() % 10000;
        }
        $code = strtoupper($code);

        // Validation
        $errors = [];
        if ($nameAr === '' || mb_strlen($nameAr) < 2) {
            $errors[] = 'الاسم بالعربي مطلوب (حرفان على الأقل)';
        }
        if (!array_key_exists($category, SportDiscipline::getCategories())) {
            $errors[] = 'فئة النشاط غير صالحة';
        }

        // Ensure unique code
        $existing = SportDiscipline::query()
            ->where('code', '=', $code)
            ->first();
        if ($existing) {
            $code = $code . '_' . bin2hex(random_bytes(2));
        }

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

        // Build config_json
        $config = $this->buildConfigFromRequest($request);

        $discipline = SportDiscipline::create([
            'code'           => $code,
            'name_ar'        => $nameAr,
            'name_en'        => $nameEn ?: null,
            'category'       => $category,
            'icon'           => $icon,
            'description_ar' => $descriptionAr ?: null,
            'config_json'    => json_encode($config, JSON_UNESCAPED_UNICODE),
            'sort_order'     => $sortOrder,
            'is_active'      => 1,
        ]);

        return $this->redirect('/disciplines/' . $discipline->id)->withSuccess('تم إضافة النشاط الرياضي بنجاح');
    }

    /**
     * Show discipline detail page.
     */
    public function show(Request $request, string $id): Response
    {
        $discipline = SportDiscipline::find((int) $id);
        if (!$discipline) {
            return $this->redirect('/disciplines')->withError('النشاط الرياضي غير موجود');
        }

        return $this->view('Disciplines.Views.show', [
            'discipline' => $discipline,
            'config'     => $discipline->getConfig(),
            'categories' => SportDiscipline::getCategories(),
        ]);
    }

    /**
     * Show edit form for a discipline.
     */
    public function edit(Request $request, string $id): Response
    {
        $discipline = SportDiscipline::find((int) $id);
        if (!$discipline) {
            return $this->redirect('/disciplines')->withError('النشاط الرياضي غير موجود');
        }

        return $this->view('Disciplines.Views.edit', [
            'discipline' => $discipline,
            'config'     => $discipline->getConfig(),
            'categories' => SportDiscipline::getCategories(),
        ]);
    }

    /**
     * Validate and update an existing discipline.
     */
    public function update(Request $request, string $id): Response
    {
        $discipline = SportDiscipline::find((int) $id);
        if (!$discipline) {
            return $this->redirect('/disciplines')->withError('النشاط الرياضي غير موجود');
        }

        $nameAr = trim((string) $request->post('name_ar', ''));
        $nameEn = trim((string) $request->post('name_en', ''));
        $code = trim((string) $request->post('code', ''));
        $category = trim((string) $request->post('category', ''));
        $icon = trim((string) $request->post('icon', 'activity'));
        $descriptionAr = trim((string) $request->post('description_ar', ''));
        $sortOrder = (int) $request->post('sort_order', 0);

        // Auto-generate code if empty
        if ($code === '') {
            $base = $nameEn ?: $nameAr;
            $code = strtoupper(preg_replace('/[^A-Z0-9]/i', '_', $base));
            $code = substr($code, 0, 25) . '_' . time() % 10000;
        }
        $code = strtoupper($code);

        // Validation
        $errors = [];
        if ($nameAr === '' || mb_strlen($nameAr) < 2) {
            $errors[] = 'الاسم بالعربي مطلوب (حرفان على الأقل)';
        }
        if (!array_key_exists($category, SportDiscipline::getCategories())) {
            $errors[] = 'فئة النشاط غير صالحة';
        }

        // Check unique code (exclude current)
        if ($code !== '') {
            $existing = SportDiscipline::query()
                ->where('code', '=', $code)
                ->whereRaw('`id` != ?', [(int) $id])
                ->first();
            if ($existing) {
                $errors[] = 'كود النشاط مستخدم بالفعل — جرب كود مختلف';
            }
        }

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

        // Build config_json
        $config = $this->buildConfigFromRequest($request);

        $discipline->update([
            'code'           => $code,
            'name_ar'        => $nameAr,
            'name_en'        => $nameEn ?: null,
            'category'       => $category,
            'icon'           => $icon,
            'description_ar' => $descriptionAr ?: null,
            'config_json'    => json_encode($config, JSON_UNESCAPED_UNICODE),
            'sort_order'     => $sortOrder,
        ]);

        return $this->redirect('/disciplines/' . $id)->withSuccess('تم تحديث النشاط الرياضي بنجاح');
    }

    /**
     * Toggle the is_active status of a discipline.
     */
    public function toggle(Request $request, string $id): Response
    {
        $discipline = SportDiscipline::find((int) $id);
        if (!$discipline) {
            return $this->redirect('/disciplines')->withError('النشاط الرياضي غير موجود');
        }

        $newStatus = $discipline->is_active ? 0 : 1;
        $discipline->update(['is_active' => $newStatus]);

        $message = $newStatus ? 'تم تفعيل النشاط الرياضي' : 'تم إيقاف النشاط الرياضي';
        return $this->redirect('/disciplines/' . $id)->withSuccess($message);
    }

    /**
     * Build the config array from the request.
     */
    private function buildConfigFromRequest(Request $request): array
    {
        $config = [];

        $requiresMedicalCert = $request->post('requires_medical_cert');
        if ($requiresMedicalCert) {
            $config['requires_medical_cert'] = true;
        }

        $guardianConsentAge = $request->post('requires_guardian_consent_under');
        if ($guardianConsentAge !== null && $guardianConsentAge !== '') {
            $config['requires_guardian_consent_under'] = (int) $guardianConsentAge;
        }

        $maxPlayers = $request->post('max_players_per_session');
        if ($maxPlayers !== null && $maxPlayers !== '') {
            $config['max_players_per_session'] = (int) $maxPlayers;
        }

        return $config;
    }
}
