<?php

namespace App\Http\Controllers\Api\Parents;

use App\Http\Controllers\Api\Core\BaseApiController;
use App\Http\Requests\Parents\ParentAttendanceRequest;
use App\Http\Requests\Parents\ParentEnrollmentActionRequest;
use App\Http\Requests\Parents\ParentEnrollmentRequest;
use App\Http\Requests\Parents\ParentEmergencyContactRequest;
use App\Http\Requests\Parents\ParentEventParticipationRequest;
use App\Http\Requests\Parents\ParentInvoiceRequest;
use App\Http\Requests\Parents\ParentProfileUpdateRequest;
use App\Http\Requests\Parents\ParentRegistrationRequest;
use App\Http\Requests\Parents\ParentStudentUpdateRequest;
use App\Http\Resources\Parents\ParentAttendanceResource;
use App\Http\Resources\Parents\ParentEmergencyContactResource;
use App\Http\Resources\Parents\ParentStudentResource;
use App\Http\Resources\Invoices\InvoiceResource;
use App\Services\Parents\ParentAttendanceService;
use App\Services\Parents\ParentEmergencyContactService;
use App\Services\Parents\ParentEnrollmentService;
use App\Services\Parents\ParentEventParticipationService;
use App\Services\Parents\ParentInvoiceService;
use App\Services\Parents\ParentProfileService;
use App\Services\Parents\ParentRegistrationService;
use Illuminate\Http\JsonResponse;

class ParentController extends BaseApiController
{
    public function __construct(
        private ParentAttendanceService $attendanceService,
        private ParentInvoiceService $invoiceService,
        private ParentEnrollmentService $enrollmentService,
        private ParentRegistrationService $registrationService,
        private ParentEmergencyContactService $emergencyContactService,
        private ParentProfileService $profileService,
        private ParentEventParticipationService $eventService
    ) {
        parent::__construct();
    }

    public function attendance(ParentAttendanceRequest $request): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $data = $this->attendanceService->listAttendance($guard, $request->validated()['school_year'] ?? null);

        return response()->json([
            'ok' => true,
            'attendance' => ParentAttendanceResource::collection($data['attendance']),
            'schoolYears' => $data['schoolYears'],
            'selectedYear' => $data['selectedYear'],
        ]);
    }

    public function invoices(ParentInvoiceRequest $request): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $schoolYear = $request->validated()['school_year'] ?? null;
        $rows = $this->invoiceService->listInvoices($guard, $schoolYear);

        return response()->json([
            'ok' => true,
            'invoices' => InvoiceResource::collection($rows),
        ]);
    }

    public function enrollments(ParentEnrollmentRequest $request): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $data = $this->enrollmentService->overview($guard, $request->validated()['school_year'] ?? null);

        return response()->json([
            'ok' => true,
            'students' => ParentStudentResource::collection($data['students']),
            'schoolYears' => $data['schoolYears'],
            'selectedYear' => $data['selectedYear'],
            'withdrawalDeadline' => $data['withdrawalDeadline'],
            'lastDayOfRegistration' => $data['lastDayOfRegistration'],
            'schoolStartDate' => $data['schoolStartDate'],
        ]);
    }

    public function updateEnrollments(ParentEnrollmentActionRequest $request): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $payload = $request->validated();
        $result = $this->enrollmentService->updateEnrollment(
            $guard,
            $payload['enroll'] ?? [],
            $payload['withdraw'] ?? []
        );

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

    public function registration(): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $data = $this->registrationService->overview($guard);

        return response()->json([
            'ok' => true,
            'parent' => $data['parent'],
            'existingKids' => ParentStudentResource::collection($data['existingKids']),
            'emergencies' => ParentEmergencyContactResource::collection($data['emergencies']),
            'maxChilds' => $data['maxChilds'],
            'maxEmergency' => $data['maxEmergency'],
            'lastDayOfRegistration' => $data['lastDayOfRegistration'],
            'registrationAgeDeadline' => $data['registrationAgeDeadline'],
        ]);
    }

    public function storeRegistration(ParentRegistrationRequest $request): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $payload = $request->validated();
        $result = $this->registrationService->register(
            $guard,
            $payload['students'] ?? [],
            $payload['emergency_contacts'] ?? []
        );

        $createdCount = count($result['created_student_ids']);
        $skipped = $result['skipped'] ?? [];

        return response()->json([
            'ok' => true,
            'created_student_ids' => $result['created_student_ids'],
            'skipped' => $skipped,
        ], $createdCount > 0 ? 201 : 200);
    }

    public function updateStudent(ParentStudentUpdateRequest $request, int $studentId): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $this->registrationService->updateStudent($guard, $studentId, $request->validated());

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

    public function deleteStudent(int $studentId): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $this->registrationService->deleteStudent($guard, $studentId);

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

    public function emergencyContacts(): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $rows = $this->emergencyContactService->list($guard);

        return response()->json([
            'ok' => true,
            'contacts' => ParentEmergencyContactResource::collection($rows),
        ]);
    }

    public function storeEmergencyContact(ParentEmergencyContactRequest $request): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $contact = $this->emergencyContactService->store($guard, $request->validated());

        return response()->json([
            'ok' => true,
            'contact' => new ParentEmergencyContactResource($contact),
        ], 201);
    }

    public function updateEmergencyContact(ParentEmergencyContactRequest $request, int $contactId): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $contact = $this->emergencyContactService->update($guard, $contactId, $request->validated());

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

    public function profile(): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $profile = $this->profileService->getProfile($guard);

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

    public function updateProfile(ParentProfileUpdateRequest $request): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $profile = $this->profileService->updateProfile($guard, $request->validated());

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

    public function events(): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $data = $this->eventService->overview($guard);

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

    public function updateParticipation(ParentEventParticipationRequest $request): JsonResponse
    {
        $guard = $this->parentIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $this->eventService->updateParticipation($guard, $request->validated()['participation'] ?? []);

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

    /**
     * @return int|JsonResponse Effective primary-parent user id, or 401 JSON for this controller's legacy `{ ok }` shape.
     *
     * `parent.access` middleware resolves second parents (user_type=secondary)
     * and authorized users (user_type=tertiary) to their primary parent and
     * stashes the result as `primary_parent_id` on the request. If we are
     * called outside that middleware we fall back to the authenticated id.
     */
    private function parentIdOrUnauthorized(): int|JsonResponse
    {
        $request = request();
        $primary = (int) ($request?->attributes?->get('primary_parent_id') ?? 0);
        if ($primary > 0) {
            return $primary;
        }

        $parentId = (int) (auth()->id() ?? 0);
        if ($parentId <= 0) {
            return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
        }

        return $parentId;
    }
}
