<?php

namespace App\Http\Controllers\Api\ClassPreparation;

use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\ClassPreparation\ClassPreparationAdjustmentRequest;
use App\Http\Requests\ClassPreparation\ClassPreparationIndexRequest;
use App\Http\Requests\ClassPreparation\ClassPreparationMarkPrintedRequest;
use App\Http\Requests\ClassPreparation\ClassPreparationPrintRequest;
use App\Http\Resources\ClassPreparation\ClassPreparationPrintResource;
use App\Http\Resources\ClassPreparation\ClassPreparationResultResource;
use App\Services\ClassPrep\ClassRosterService;
use App\Services\ClassPrep\StickerCountService;
use App\Services\ClassPreparation\ClassPreparationService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

class ClassPreparationController extends BaseApiController
{
    private ClassPreparationService $service;
    private StickerCountService $stickerCounts;
    private ClassRosterService $roster;

    public function __construct(
        ClassPreparationService $service,
        StickerCountService $stickerCounts,
        ClassRosterService $roster
    )
    {
        parent::__construct();
        $this->service = $service;
        $this->stickerCounts = $stickerCounts;
        $this->roster = $roster;
    }

    public function index(ClassPreparationIndexRequest $request): JsonResponse
    {
        $schoolYear = (string) ($request->query('school_year') ?? '');
        $semester = (string) ($request->query('semester') ?? '');

        $payload = $this->service->listPrep(
            $schoolYear !== '' ? $schoolYear : null,
            $semester !== '' ? $semester : null
        );

        return $this->success([
            'schoolYear' => $payload['schoolYear'],
            'semester' => $payload['semester'],
            'results' => ClassPreparationResultResource::collection($payload['results']),
            'totals' => $payload['totals'],
            'shortages' => $payload['shortages'],
        ]);
    }

    public function markPrinted(ClassPreparationMarkPrintedRequest $request): JsonResponse
    {
        $validated = $request->validated();
        $schoolYear = (string) ($validated['school_year'] ?? '');
        $semester = (string) ($validated['semester'] ?? '');
        $ids = $validated['class_section_ids'] ?? [];

        $count = $this->service->markPrinted($schoolYear, $semester, $ids);

        return $this->success([
            'updated' => $count,
        ], 'Class preparation logs updated.');
    }

    public function saveAdjustments(ClassPreparationAdjustmentRequest $request): JsonResponse
    {
        $validated = $request->validated();
        $classSectionId = (string) $validated['class_section_id'];
        $schoolYear = (string) ($validated['school_year'] ?? '');

        try {
            $count = $this->service->saveAdjustments($classSectionId, $schoolYear, $validated['adjustments']);
        } catch (\Throwable $e) {
            Log::error('Class prep adjustment save failed: ' . $e->getMessage());
            return $this->error('Unable to save adjustments.', Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        return $this->success([
            'updated' => $count,
        ], 'Adjustments saved.');
    }

    public function print(ClassPreparationPrintRequest $request): JsonResponse
    {
        $validated = $request->validated();

        $payload = $this->service->printPrep(
            (string) $validated['class_section_id'],
            (string) $validated['school_year'],
            (string) ($validated['semester'] ?? '')
        );

        if (empty($payload['ok'])) {
            return $this->error('Unable to log class preparation print.', Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        return $this->success([
            'print' => new ClassPreparationPrintResource($payload),
        ], 'Class preparation logged.');
    }

    public function stickerCounts(Request $request): JsonResponse
    {
        $schoolYear = (string) ($request->query('school_year') ?? '');
        $semester = (string) ($request->query('semester') ?? '');
        $classSectionId = $request->query('class_section_id') ?? $request->query('class_id');
        $classSectionId = is_numeric($classSectionId) ? (int) $classSectionId : null;

        if ($classSectionId !== null && $classSectionId > 0) {
            $payload = $this->stickerCounts->listForClass($schoolYear, $semester, $classSectionId);
        } else {
            $payload = $this->stickerCounts->listAll($schoolYear, $semester);
        }

        return response()->json([
            'ok' => true,
            'data' => $payload,
        ]);
    }

    public function studentsByClass(Request $request, int $classSectionId): JsonResponse
    {
        $schoolYear = (string) ($request->query('school_year') ?? '');

        $students = $this->roster->listStudentsByClass($classSectionId, $schoolYear !== '' ? $schoolYear : null);

        return response()->json([
            'ok' => true,
            'students' => $students,
        ]);
    }
}
