<?php

namespace App\Services\ClassPreparation;

use App\Models\ClassSection;
use Illuminate\Support\Facades\Log;

class ClassPreparationPrintService
{
    public function __construct(
        private ClassPreparationContextService $context,
        private ClassPreparationRosterService $roster,
        private ClassPreparationCalculatorService $calculator,
        private ClassPreparationAdjustmentService $adjustments,
        private ClassPreparationLogService $logs
    ) {
    }

    public function printPrep(string $classSectionId, string $schoolYear, ?string $semester = null): array
    {
        $semester = $semester ?: $this->context->getSemester();
        $limitToSemester = $this->context->hasRosterForSemester($schoolYear, $semester);

        $studentCount = $this->roster->getStudentCountForSection($schoolYear, $semester, $limitToSemester, $classSectionId);
        $classLevel = $this->calculator->getClassLevelBySection($classSectionId);
        $className = ClassSection::getClassSectionNameBySectionId($classSectionId) ?? $classSectionId;

        $items = $this->calculator->calculatePrepItems($studentCount, $classLevel, $classSectionId);
        [$items, $adjMap] = $this->adjustments->applyAdjustments($items, $classSectionId, $schoolYear);

        $printedAt = $this->utcNow();
        $ok = $this->logs->createLog($classSectionId, $className, $schoolYear, $items, $printedAt);

        if (!$ok) {
            Log::warning('Failed to store class preparation log.', [
                'class_section_id' => $classSectionId,
                'school_year' => $schoolYear,
            ]);
        }

        return [
            'ok' => $ok,
            'class_section_id' => $classSectionId,
            'class_section' => $className,
            'school_year' => $schoolYear,
            'semester' => $semester,
            'prep_items' => $items,
            'adjustments' => $adjMap,
            'printed_at' => $ok ? $printedAt : null,
        ];
    }

    private function utcNow(): string
    {
        if (function_exists('utc_now')) {
            return (string) utc_now();
        }
        return now('UTC')->toDateTimeString();
    }
}
