<?php

namespace App\Http\Controllers\Api\AttendanceManagement;

use App\Http\Controllers\Api\Core\BaseApiController;
use App\Services\AttendanceManagement\AttendanceManagementService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpFoundation\Response;

class AttendanceManagementController extends BaseApiController
{
    public function __construct(private AttendanceManagementService $service)
    {
        parent::__construct();
    }

    public function dashboard(Request $request): JsonResponse
    {
        try {
            return $this->success($this->service->dashboard($request->query()));
        } catch (\Throwable $e) {
            return $this->error($e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    public function manualEntry(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'person_type' => ['nullable', 'string', 'max:32'],
            'person_id' => ['nullable', 'integer'],
            'person_name' => ['nullable', 'string', 'max:255'],
            'role_grade' => ['nullable', 'string', 'max:128'],
            'badge_id' => ['nullable', 'string', 'max:128'],
            'entry_time' => ['nullable', 'date'],
            'manual_entry_time' => ['nullable', 'date'],
            'manual_reason' => ['nullable', 'string', 'max:255'],
            'reason_for_manual_entry' => ['nullable', 'string', 'max:255'],
            'report_status' => ['nullable', 'string', 'max:48'],
            'reason' => ['nullable', 'string', 'max:255'],
            'notes' => ['nullable', 'string'],
        ]);
        if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
        try {
            return $this->success(['event' => $this->service->manualEntry($validator->validated(), $request->user())], 'Manual attendance entry recorded.', Response::HTTP_CREATED);
        } catch (\InvalidArgumentException $e) {
            return $this->error($e->getMessage(), Response::HTTP_UNPROCESSABLE_ENTITY);
        } catch (\Throwable $e) {
            return $this->error($e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    public function scan(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'badge_scan' => ['nullable', 'string', 'max:255'],
            'badge_id' => ['nullable', 'string', 'max:255'],
            'scan_time' => ['nullable', 'date'],
            'scan_type' => ['nullable', 'string', 'max:32'],
            'location' => ['nullable', 'string', 'max:255'],
            'report_status' => ['nullable', 'string', 'max:48'],
            'authorized' => ['nullable'],
            'reason' => ['nullable', 'string', 'max:255'],
        ]);
        if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
        try {
            return $this->success(['event' => $this->service->badgeScan($validator->validated(), $request->user())], 'Badge scan classified.');
        } catch (\InvalidArgumentException $e) {
            return $this->error($e->getMessage(), Response::HTTP_UNPROCESSABLE_ENTITY);
        } catch (\Throwable $e) {
            return $this->error($e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    public function exitEntry(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'person_type' => ['nullable', 'string', 'max:32'],
            'person_id' => ['nullable', 'integer'],
            'person_name' => ['nullable', 'string', 'max:255'],
            'role_grade' => ['nullable', 'string', 'max:128'],
            'badge_id' => ['nullable', 'string', 'max:128'],
            'exit_time' => ['nullable', 'date'],
            'manual_exit_time' => ['nullable', 'date'],
            'exit_method' => ['nullable', 'string', 'max:64'],
            'exit_location' => ['nullable', 'string', 'max:255'],
            'authorized' => ['nullable'],
            'authorized_by' => ['nullable', 'string', 'max:255'],
            'report_status' => ['nullable', 'string', 'max:48'],
            'reason' => ['nullable', 'string', 'max:255'],
            'notes' => ['nullable', 'string'],
        ]);
        if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
        try {
            return $this->success(['event' => $this->service->exitEntry($validator->validated(), $request->user())], 'Exit attendance entry recorded.', Response::HTTP_CREATED);
        } catch (\InvalidArgumentException $e) {
            return $this->error($e->getMessage(), Response::HTTP_UNPROCESSABLE_ENTITY);
        } catch (\Throwable $e) {
            return $this->error($e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    public function absent(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'person_type' => ['nullable', 'string', 'max:32'],
            'person_id' => ['nullable', 'integer'],
            'person_name' => ['nullable', 'string', 'max:255'],
            'role_grade' => ['nullable', 'string', 'max:128'],
            'badge_id' => ['nullable', 'string', 'max:128'],
            'date' => ['nullable', 'date'],
            'report_status' => ['nullable', 'string', 'max:48'],
            'reason' => ['nullable', 'string', 'max:255'],
        ]);
        if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
        try {
            return $this->success(['event' => $this->service->markAbsent($validator->validated(), $request->user())], 'Absence recorded.', Response::HTTP_CREATED);
        } catch (\InvalidArgumentException $e) {
            return $this->error($e->getMessage(), Response::HTTP_UNPROCESSABLE_ENTITY);
        } catch (\Throwable $e) {
            return $this->error($e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    public function completeFollowUp(int $id, Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'report_status' => ['nullable', 'string', 'max:48'],
            'final_decision' => ['nullable', 'string', 'max:255'],
            'notes' => ['nullable', 'string'],
        ]);
        if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
        try {
            return $this->success(['event' => $this->service->completeFollowUp($id, $validator->validated(), $request->user())], 'Follow-up completed.');
        } catch (\RuntimeException $e) {
            return $this->error($e->getMessage(), Response::HTTP_NOT_FOUND);
        } catch (\Throwable $e) {
            return $this->error($e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    public function reprintLateSlip(int $id, Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'reason' => ['nullable', 'string', 'max:255'],
            'slip_number' => ['nullable', 'string', 'max:64'],
            'late_slip_log_id' => ['nullable', 'integer'],
        ]);
        if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
        try {
            return $this->success(['reprint' => $this->service->reprintLateSlip($id, $validator->validated(), $request->user())], 'Late slip reprint logged.', Response::HTTP_CREATED);
        } catch (\RuntimeException $e) {
            return $this->error($e->getMessage(), Response::HTTP_NOT_FOUND);
        } catch (\Throwable $e) {
            return $this->error($e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }
}
