<?php

namespace App\Services\Subjects;

use App\Models\SchoolClass;
use App\Models\SubjectCurriculum;
use App\Services\SchoolYears\SchoolYearContextService;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class SubjectCurriculumService
{
    private SchoolYearContextService $schoolYears;

    public const SUBJECT_OPTIONS = [
        'islamic' => 'Islamic Studies',
        'quran' => 'Quran/Arabic',
    ];

    public function __construct(?SchoolYearContextService $schoolYears = null)
    {
        $this->schoolYears = $schoolYears ?: app(SchoolYearContextService::class);
    }

    public function list(?string $schoolYear = null): array
    {
        $classes = SchoolClass::query()
            ->orderBy('class_name')
            ->get()
            ->toArray();

        $resolvedSchoolYear = $this->schoolYears->currentSchoolYear($schoolYear);

        $entriesQuery = DB::table('subject_curriculum_items as sci')
            ->leftJoin('classes', 'classes.id', '=', 'sci.class_id')
            ->select('sci.*', 'classes.class_name');

        if ($resolvedSchoolYear !== '' && Schema::hasColumn('subject_curriculum_items', 'school_year')) {
            $entriesQuery->where(function ($query) use ($resolvedSchoolYear) {
                $query->where('sci.school_year', $resolvedSchoolYear)
                    ->orWhereNull('sci.school_year')
                    ->orWhere('sci.school_year', '');
            });
        }

        $entries = $entriesQuery
            ->orderBy('classes.class_name')
            ->orderBy('sci.subject')
            ->orderBy('sci.unit_number')
            ->orderBy('sci.chapter_name')
            ->get()
            ->map(fn ($r) => (array) $r)
            ->all();

        return [
            'classes' => $classes,
            'entries' => $entries,
            'subject_labels' => self::SUBJECT_OPTIONS,
            'meta' => $this->schoolYears->options($resolvedSchoolYear),
        ];
    }

    public function store(array $payload): SubjectCurriculum
    {
        $data = [
            'class_id' => (int) $payload['class_id'],
            'subject' => (string) $payload['subject'],
            'unit_number' => $payload['unit_number'] !== null ? (int) $payload['unit_number'] : null,
            'unit_title' => $payload['unit_title'] !== '' ? $payload['unit_title'] : null,
            'chapter_name' => (string) $payload['chapter_name'],
        ];

        if (Schema::hasColumn('subject_curriculum_items', 'school_year')) {
            $data['school_year'] = $this->schoolYears->currentSchoolYear($payload['school_year'] ?? null) ?: null;
        }

        return SubjectCurriculum::query()->create($data);
    }

    public function update(int $id, array $payload): ?SubjectCurriculum
    {
        $entry = SubjectCurriculum::query()->find($id);
        if (!$entry) {
            return null;
        }

        $data = [
            'class_id' => (int) $payload['class_id'],
            'subject' => (string) $payload['subject'],
            'unit_number' => $payload['unit_number'] !== null ? (int) $payload['unit_number'] : null,
            'unit_title' => $payload['unit_title'] !== '' ? $payload['unit_title'] : null,
            'chapter_name' => (string) $payload['chapter_name'],
        ];

        if (Schema::hasColumn('subject_curriculum_items', 'school_year')) {
            $data['school_year'] = $this->schoolYears->currentSchoolYear($payload['school_year'] ?? null) ?: null;
        }

        $entry->update($data);

        return $entry;
    }

    public function delete(int $id): bool
    {
        $entry = SubjectCurriculum::query()->find($id);
        if (!$entry) {
            return false;
        }

        return (bool) $entry->delete();
    }
}
