<?php

namespace App\Controllers\View;

use App\Controllers\BaseController;
use App\Models\ClassModel;
use App\Models\SubjectCurriculumModel;
use CodeIgniter\Exceptions\PageNotFoundException;

class SubjectCurriculumController extends BaseController
{
    private const SUBJECT_OPTIONS = [
        'islamic' => 'Islamic Studies',
        'quran' => 'Quran/Arabic',
    ];

    protected SubjectCurriculumModel $curriculumModel;
    protected ClassModel $classModel;

    public function __construct()
    {
        helper(['form']);
        $this->curriculumModel = new SubjectCurriculumModel();
        $this->classModel = new ClassModel();
    }

    public function index()
    {
        $data = $this->buildViewData();
        $data['editEntry'] = null;
        return view('administrator/subject_curriculum', $data);
    }

    public function store()
    {
        if (! $this->validate($this->getValidationRules())) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $data = $this->buildEntryDataFromInput();
        $insertedId = $this->curriculumModel->insert($data);
        if ($insertedId === false) {
            return redirect()->back()->withInput()->with('error', 'Unable to save the curriculum entry. Please try again.');
        }

        return redirect()->to('administrator/subject-curriculum')->with('success', 'Curriculum entry added.');
    }

    public function edit(int $id)
    {
        $entry = $this->curriculumModel->find($id);
        if (! $entry) {
            throw new PageNotFoundException('Curriculum entry not found.');
        }

        $data = $this->buildViewData();
        $data['editEntry'] = $entry;
        return view('administrator/subject_curriculum', $data);
    }

    public function update(int $id)
    {
        $entry = $this->curriculumModel->find($id);
        if (! $entry) {
            throw new PageNotFoundException('Curriculum entry not found.');
        }

        $redirectBack = redirect()->to('administrator/subject-curriculum/edit/' . $id)->withInput();
        if (! $this->validate($this->getValidationRules())) {
            return $redirectBack->with('errors', $this->validator->getErrors());
        }

        $data = $this->buildEntryDataFromInput();
        if ($this->curriculumModel->update($id, $data) === false) {
            return $redirectBack->with('error', 'Unable to update the curriculum entry.');
        }

        return redirect()->to('administrator/subject-curriculum')->with('success', 'Curriculum entry updated.');
    }

    public function delete(int $id)
    {
        $entry = $this->curriculumModel->find($id);
        if (! $entry) {
            throw new PageNotFoundException('Curriculum entry not found.');
        }

        $this->curriculumModel->delete($id);
        return redirect()->to('administrator/subject-curriculum')->with('success', 'Curriculum entry deleted.');
    }

    private function buildViewData(): array
    {
        $classes = $this->classModel->orderBy('class_name', 'ASC')->findAll();
        $entries = $this->curriculumModel
            ->builder()
            ->select('subject_curriculum_items.*, classes.class_name')
            ->join('classes', 'classes.id = subject_curriculum_items.class_id', 'left')
            ->orderBy('classes.class_name', 'ASC')
            ->orderBy('subject', 'ASC')
            ->orderBy('unit_number', 'ASC')
            ->orderBy('chapter_name', 'ASC')
            ->get()
            ->getResultArray();

        return [
            'classes' => $classes,
            'entries' => $entries,
            'subjectLabels' => self::SUBJECT_OPTIONS,
        ];
    }

    private function buildEntryDataFromInput(): array
    {
        $unitNumber = $this->request->getPost('unit_number');
        $unitNumber = is_numeric($unitNumber) ? (int) $unitNumber : null;
        if ($unitNumber === 0) {
            $unitNumber = null;
        }

        $unitTitle = trim((string) $this->request->getPost('unit_title'));
        $chapterName = trim((string) $this->request->getPost('chapter_name'));

        return [
            'class_id' => (int) $this->request->getPost('class_id'),
            'subject' => (string) $this->request->getPost('subject'),
            'unit_number' => $unitNumber,
            'unit_title' => $unitTitle !== '' ? $unitTitle : null,
            'chapter_name' => $chapterName,
        ];
    }

    private function getValidationRules(): array
    {
        return [
            'class_id' => 'required|is_natural_no_zero',
            'subject' => 'required|in_list[islamic,quran]',
            'chapter_name' => 'required|string|max_length[255]',
            'unit_number' => 'permit_empty|integer',
            'unit_title' => 'permit_empty|string|max_length[255]',
        ];
    }
}
