<?php

namespace App\Http\Controllers\Api\Incidents;

use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Incidents\IncidentCancelRequest;
use App\Http\Requests\Incidents\IncidentCloseRequest;
use App\Http\Requests\Incidents\IncidentListRequest;
use App\Http\Requests\Incidents\IncidentStateRequest;
use App\Http\Resources\Incidents\IncidentAnalysisStudentResource;
use App\Http\Resources\Incidents\IncidentGradeResource;
use App\Http\Resources\Incidents\IncidentResource;
use App\Http\Resources\Incidents\IncidentStudentOptionResource;
use App\Services\Incidents\CurrentIncidentService;
use App\Services\Incidents\IncidentAnalysisService;
use App\Services\Incidents\IncidentHistoryService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class IncidentController extends BaseApiController
{
    public function __construct(
        private CurrentIncidentService $currentService,
        private IncidentHistoryService $historyService,
        private IncidentAnalysisService $analysisService
    ) {
        parent::__construct();
    }

    public function current(): JsonResponse
    {
        $data = $this->currentService->listCurrent();

        return response()->json([
            'ok' => true,
            'incidents' => IncidentResource::collection($data['incidents']),
            'grades' => IncidentGradeResource::collection($data['grades']),
        ]);
    }

    public function history(IncidentListRequest $request): JsonResponse
    {
        $payload = $request->validated();
        $incidents = $this->historyService->history($payload['school_year'] ?? null, $payload['semester'] ?? null);

        return response()->json([
            'ok' => true,
            'incidents' => IncidentResource::collection($incidents),
        ]);
    }

    public function processed(IncidentListRequest $request): JsonResponse
    {
        $payload = $request->validated();
        $incidents = $this->historyService->processed($payload['school_year'] ?? null, $payload['semester'] ?? null);

        return response()->json([
            'ok' => true,
            'incidents' => IncidentResource::collection($incidents),
        ]);
    }

    public function analysis(IncidentListRequest $request): JsonResponse
    {
        $payload = $request->validated();
        $students = $this->analysisService->analyze($payload['school_year'] ?? null, $payload['semester'] ?? null);

        return response()->json([
            'ok' => true,
            'students' => IncidentAnalysisStudentResource::collection($students),
            'school_year' => $payload['school_year'] ?? null,
            'semester' => $payload['semester'] ?? null,
        ]);
    }

    public function studentsByGrade(int $gradeId): JsonResponse
    {
        $students = $this->currentService->studentsByGrade($gradeId);

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

    public function store(Request $request): JsonResponse
    {
        $data = array_merge($request->query->all(), $request->all(), $request->json()->all());
        $validator = Validator::make($data, [
            'student_id' => ['required', 'integer', 'min:1'],
            'grade' => ['required', 'integer', 'min:1'],
            'incident' => ['required', 'string', 'max:255'],
            'description' => ['required', 'string', 'max:2000'],
            'school_year' => ['nullable', 'string', 'max:20'],
            'semester' => ['nullable', 'string', 'max:20'],
        ]);

        if ($validator->fails()) {
            return response()->json([
                'message' => 'Validation failed.',
                'errors' => $validator->errors(),
            ], 422);
        }

        $payload = $validator->validated();
        $result = $this->currentService->addIncident($payload, (int) (auth()->id() ?? 0));

        if (empty($result['ok'])) {
            return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Failed to add incident.'], 422);
        }

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

    public function updateState(IncidentStateRequest $request, int $incidentId): JsonResponse
    {
        $payload = $request->validated();
        $updated = $this->currentService->updateState($incidentId, (string) $payload['incident_state']);

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

    public function close(Request $request, int $incidentId): JsonResponse
    {
        $data = array_merge($request->query->all(), $request->all(), $request->json()->all());
        $validator = Validator::make($data, [
            'state_description' => ['required', 'string', 'max:2000'],
            'action_taken' => ['nullable', 'string', 'max:2000'],
        ]);

        if ($validator->fails()) {
            return response()->json([
                'message' => 'Validation failed.',
                'errors' => $validator->errors(),
            ], 422);
        }

        $payload = $validator->validated();
        $result = $this->currentService->closeIncident(
            $incidentId,
            (string) $payload['state_description'],
            $payload['action_taken'] ?? null,
            (int) (auth()->id() ?? 0)
        );

        if (empty($result['ok'])) {
            return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Failed to close incident.'], 422);
        }

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

    public function cancel(IncidentCancelRequest $request, int $incidentId): JsonResponse
    {
        $payload = $request->validated();
        $result = $this->currentService->cancelIncident(
            $incidentId,
            $payload['state_description'] ?? null,
            $payload['action_taken'] ?? null,
            (int) (auth()->id() ?? 0)
        );

        if (empty($result['ok'])) {
            return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Failed to cancel incident.'], 422);
        }

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