<?php

namespace App\Http\Controllers\Api\Classes;

use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Classes\ClassSectionIndexRequest;
use App\Http\Requests\Classes\ClassSectionStoreRequest;
use App\Http\Requests\Classes\ClassSectionUpdateRequest;
use App\Http\Resources\Classes\ClassAttendanceResource;
use App\Http\Resources\Classes\ClassSectionCollection;
use App\Http\Resources\Classes\ClassSectionResource;
use App\Models\ClassSection;
use App\Services\ClassSections\ClassAttendanceService;
use App\Services\ClassSections\ClassSectionCommandService;
use App\Services\ClassSections\ClassSectionQueryService;
use App\Services\ClassSections\ClassSectionSeedService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

class ClassController extends BaseApiController
{
    public function __construct(
        private ClassSectionQueryService $queryService,
        private ClassSectionCommandService $commandService,
        private ClassAttendanceService $attendanceService,
        private ClassSectionSeedService $seedService
    ) {
        parent::__construct();
    }

    public function index(ClassSectionIndexRequest $request): JsonResponse
    {
        $this->authorize('viewAny', ClassSection::class);

        $filters = $request->validated();
        $page = (int) ($filters['page'] ?? 1);
        $perPage = (int) ($filters['per_page'] ?? 20);

        $sections = $this->queryService->list($filters, $page, $perPage);
        $collection = new ClassSectionCollection($sections);

        return $this->success([
            'sections' => $collection->toArray($request),
            'meta' => $collection->with($request)['meta'],
        ]);
    }

    public function show(ClassSection $classSection): JsonResponse
    {
        $this->authorize('view', $classSection);

        $section = $this->queryService->find((int) $classSection->id);

        if (!$section) {
            return $this->error('Class section not found.', Response::HTTP_NOT_FOUND);
        }

        return $this->success([
            'section' => new ClassSectionResource($section),
        ]);
    }

    public function store(ClassSectionStoreRequest $request): JsonResponse
    {
        $this->authorize('create', ClassSection::class);

        $section = $this->commandService->create($request->validated());

        return $this->success([
            'section' => new ClassSectionResource($section),
        ], 'Class section created.', Response::HTTP_CREATED);
    }

    public function update(ClassSectionUpdateRequest $request, ClassSection $classSection): JsonResponse
    {
        $this->authorize('update', $classSection);

        $section = $this->commandService->update($classSection, $request->validated());

        return $this->success([
            'section' => new ClassSectionResource($section),
        ], 'Class section updated.');
    }

    public function destroy(ClassSection $classSection): JsonResponse
    {
        $this->authorize('delete', $classSection);

        if (!$this->commandService->delete($classSection)) {
            return $this->error('Class section not found.', Response::HTTP_NOT_FOUND);
        }

        return $this->success(null, 'Class section deleted.');
    }

    public function attendance(Request $request, int $classSectionId): JsonResponse
    {
        $teacherId = (int) ($request->user()?->id ?? 0);
        if ($teacherId <= 0) {
            return $this->error('Missing teacher authentication.', Response::HTTP_UNAUTHORIZED);
        }

        $payload = $this->attendanceService->getAttendancePayload(
            $classSectionId,
            $teacherId,
            $request->query('school_year'),
            $request->query('semester')
        );

        if (empty($payload['students'])) {
            return $this->error('No data found for this class.', Response::HTTP_NOT_FOUND);
        }

        return $this->success([
            'attendance' => new ClassAttendanceResource($payload),
        ]);
    }

    public function seedDefaults(): JsonResponse
    {
        $this->authorize('seedDefaults', ClassSection::class);

        try {
            $created = $this->seedService->seedDefaults();
        } catch (\Throwable $e) {
            Log::error('Seeding default classes failed: ' . $e->getMessage());
            return $this->error('Unable to seed default classes.', Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        return $this->success([
            'created' => $created,
        ], 'Default classes seeded.');
    }
}
