<?php

namespace App\Http\Controllers\Api\Staff;

use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Staff\StaffIndexRequest;
use App\Http\Requests\Staff\StaffStoreRequest;
use App\Http\Requests\Staff\StaffUpdateRequest;
use App\Http\Resources\Staff\StaffCollection;
use App\Http\Resources\Staff\StaffResource;
use App\Models\Staff;
use App\Services\Staff\StaffCommandService;
use App\Services\Staff\StaffQueryService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

class StaffController extends BaseApiController
{
    public function __construct(
        private StaffQueryService $queryService,
        private StaffCommandService $commandService
    ) {
        parent::__construct();
    }

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

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

        $result = $this->queryService->paginate($filters, $page, $perPage);
        $collection = new StaffCollection($result['paginator']);

        return $this->success([
            'staff' => $collection->toArray($request),
            'meta' => $collection->with($request)['meta'] ?? null,
            'issues_count' => $result['issues_count'],
            'semester' => $result['semester'],
            'school_year' => $result['school_year'],
        ]);
    }

    public function show(int $id): JsonResponse
    {
        $staff = $this->queryService->find($id);
        if (!$staff) {
            return $this->error('Staff member not found.', Response::HTTP_NOT_FOUND);
        }

        $this->authorize('view', $staff);
        $staff->school_id = \App\Models\User::getSchoolIdByUserId((int) ($staff->user_id ?? 0));

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

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

        try {
            $staff = $this->commandService->create($request->validated());
        } catch (\Throwable $e) {
            Log::error('Staff create failed: ' . $e->getMessage());
            return $this->error($e->getMessage(), Response::HTTP_BAD_REQUEST);
        }

        return $this->success([
            'staff' => new StaffResource($staff),
        ], 'Staff member added.', Response::HTTP_CREATED);
    }

    public function update(StaffUpdateRequest $request, int $id): JsonResponse
    {
        $staff = $this->queryService->find($id);
        if (!$staff) {
            return $this->error('Staff member not found.', Response::HTTP_NOT_FOUND);
        }

        $this->authorize('update', $staff);

        try {
            $updated = $this->commandService->update($staff, $request->validated());
        } catch (\Throwable $e) {
            Log::error('Staff update failed: ' . $e->getMessage());
            return $this->error('Unable to update staff.', Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        return $this->success([
            'staff' => new StaffResource($updated),
        ], 'Staff member updated.');
    }

    public function destroy(int $id): JsonResponse
    {
        $staff = $this->queryService->find($id);
        if (!$staff) {
            return $this->error('Staff member not found.', Response::HTTP_NOT_FOUND);
        }

        $this->authorize('delete', $staff);

        try {
            $deleted = $this->commandService->delete($staff);
        } catch (\Throwable $e) {
            Log::error('Staff delete failed: ' . $e->getMessage());
            return $this->error('Unable to delete staff.', Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        if (!$deleted) {
            return $this->error('Unable to delete staff.', Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        return $this->success(null, 'Staff member deleted.');
    }
}
