<?php

namespace App\Services\ClassPreparation;

use App\Models\ClassSection;
use App\Models\Configuration;
use Illuminate\Support\Facades\DB;

class ClassPreparationCalculatorService
{
    private array $allowedPrepCategories = [
        'Grade Box',
        'Large Table',
        'Regular Chair',
        'Small Chair',
        'Small Table',
        'Teacher Chair',
        'Trash Bin',
        'White Board',
    ];

    public function getAllowedCategories(): array
    {
        return $this->allowedPrepCategories;
    }

    public function getClassLevelBySection(string $classSectionId): int
    {
        $sectionName = ClassSection::getClassSectionNameBySectionId($classSectionId);
        $label = $sectionName !== null && $sectionName !== '' ? (string) $sectionName : $classSectionId;

        if (preg_match('/^(kg|k)(\\b|[^a-z0-9])/i', $label)) {
            return 1;
        }

        $numValue = (int) preg_replace('/\\D/', '', $label);

        if ($numValue > 0 && $numValue < 30) {
            $firstDigit = (int) substr((string) $numValue, 0, 1);
            return $firstDigit === 1 ? 1 : ($firstDigit === 2 ? 2 : 3);
        }

        return 3;
    }

    public function calculatePrepItems(int $students, int $classLevel, string $classSectionId): array
    {
        $allowed = $this->allowedPrepCategories;
        $items = array_fill_keys($allowed, 0);

        $categories = DB::table('inventory_categories')
            ->select('name', 'grade_min', 'grade_max')
            ->where('type', 'classroom')
            ->whereIn('name', $allowed)
            ->orderBy('name')
            ->get()
            ->toArray();

        $isLowerGrades = in_array($classLevel, [1, 2], true);
        $teacherCount = $this->getTeacherCountForSection(
            $classSectionId,
            (string) Configuration::getConfig('school_year')
        );

        foreach ($categories as $cat) {
            $name = (string) $cat->name;
            $gradeMin = $cat->grade_min ?? null;
            $gradeMax = $cat->grade_max ?? null;

            if ($gradeMin !== null && $classLevel < (int) $gradeMin) {
                $items[$name] = 0;
                continue;
            }
            if ($gradeMax !== null && $classLevel > (int) $gradeMax) {
                $items[$name] = 0;
                continue;
            }

            $qty = 0;
            switch (strtolower($name)) {
                case 'small table':
                    $qty = $isLowerGrades ? (int) ceil($students / 3) : 0;
                    break;
                case 'large table':
                    $qty = $isLowerGrades ? 0 : (int) ceil($students / 4);
                    break;
                case 'small chair':
                    $qty = $isLowerGrades ? $students : 0;
                    break;
                case 'regular chair':
                    $qty = $isLowerGrades ? 0 : $students;
                    break;
                case 'teacher chair':
                    $qty = $teacherCount > 0 ? (int) $teacherCount : 1;
                    break;
                case 'trash bin':
                case 'white board':
                case 'grade box':
                    $qty = 1;
                    break;
                default:
                    $qty = 0;
            }

            if (array_key_exists($name, $items)) {
                $items[$name] = $qty;
            }
        }

        return $items;
    }

    private function getTeacherCountForSection(string $classSectionId, ?string $schoolYear = null): int
    {
        $schoolYear = $schoolYear ?: (string) Configuration::getConfig('school_year');

        $baseQuery = DB::table('teacher_class')
            ->select('COUNT(*) AS cnt')
            ->where('class_section_id', $classSectionId)
            ->whereIn('position', ['main', 'ta']);

        $row = $schoolYear !== null && $schoolYear !== ''
            ? (clone $baseQuery)->where('school_year', $schoolYear)->first()
            : $baseQuery->first();

        $count = (int) ($row->cnt ?? 0);

        if ($count === 0 && $schoolYear !== null && $schoolYear !== '') {
            $row = $baseQuery->first();
            $count = (int) ($row->cnt ?? 0);
        }

        return $count;
    }
}
