<?php

namespace App\Http\Controllers\Api\Notifications;

use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Notifications\NotificationActiveRequest;
use App\Http\Requests\Notifications\NotificationDeletedRequest;
use App\Http\Requests\Notifications\NotificationIndexRequest;
use App\Http\Requests\Notifications\NotificationSendRequest;
use App\Http\Requests\Notifications\NotificationUpdateRequest;
use App\Http\Resources\Notifications\NotificationResource;
use App\Http\Resources\Notifications\UserNotificationResource;
use App\Services\Notifications\NotificationActiveService;
use App\Services\Notifications\NotificationDeletedService;
use App\Services\Notifications\NotificationManagementService;
use App\Services\Notifications\NotificationReadService;
use App\Services\Notifications\NotificationSendService;
use App\Services\Notifications\NotificationShowService;
use App\Services\Notifications\NotificationUserListService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;

class NotificationController extends BaseApiController
{
    public function __construct(
        private NotificationUserListService $listService,
        private NotificationSendService $sendService,
        private NotificationReadService $readService,
        private NotificationActiveService $activeService,
        private NotificationDeletedService $deletedService,
        private NotificationManagementService $managementService,
        private NotificationShowService $showService
    ) {
        parent::__construct();
    }

    public function index(NotificationIndexRequest $request): JsonResponse
    {
        $userId = (int) (auth()->id() ?? 0);
        if ($userId <= 0) {
            return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
        }

        $payload = $request->validated();
        $result = $this->listService->listForUser($userId, $payload);

        return response()->json([
            'ok' => true,
            'notifications' => UserNotificationResource::collection($result['notifications']),
            'pagination' => $result['pagination'],
        ]);
    }

    public function show(int $notificationId): JsonResponse
    {
        $userId = (int) (auth()->id() ?? 0);
        if ($userId <= 0) {
            return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
        }

        $row = $this->showService->getForUser($userId, $notificationId);
        if (!$row) {
            return response()->json(['ok' => false, 'message' => 'Notification not found.'], 404);
        }

        return response()->json([
            'ok' => true,
            'notification' => new UserNotificationResource($row),
        ]);
    }

    public function store(NotificationSendRequest $request): JsonResponse
    {
        $payload = $request->validated();
        $actorId = (int) (auth()->id() ?? 0);

        try {
            $result = $this->sendService->send($payload, $actorId);
        } catch (\Throwable $e) {
            Log::error('Notification send failed.', ['error' => $e->getMessage()]);
            return response()->json(['ok' => false, 'message' => 'Failed to send notification.'], 500);
        }

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

        return response()->json([
            'ok' => true,
            'notification' => new NotificationResource($result['notification']),
            'recipient_count' => $result['recipient_count'] ?? 0,
        ], 201);
    }

    public function update(NotificationUpdateRequest $request, int $notificationId): JsonResponse
    {
        $payload = $request->validated();
        $result = $this->managementService->update($notificationId, $payload);

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

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

    public function destroy(int $notificationId): JsonResponse
    {
        $deleted = $this->managementService->delete($notificationId);
        if (!$deleted) {
            return response()->json(['ok' => false, 'message' => 'Notification not found.'], 404);
        }

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

    public function restore(int $notificationId): JsonResponse
    {
        $restored = $this->managementService->restore($notificationId);
        if (!$restored) {
            return response()->json(['ok' => false, 'message' => 'Notification not found.'], 404);
        }

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

    public function markRead(int $notificationId): JsonResponse
    {
        $userId = (int) (auth()->id() ?? 0);
        if ($userId <= 0) {
            return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
        }

        $ok = $this->readService->markRead($userId, $notificationId);
        if (!$ok) {
            return response()->json(['ok' => false, 'message' => 'Notification not found.'], 404);
        }

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

    public function active(NotificationActiveRequest $request): JsonResponse
    {
        $payload = $request->validated();
        $data = $this->activeService->list($payload['target_group'] ?? null);

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

    public function deleted(NotificationDeletedRequest $request): JsonResponse
    {
        $data = $this->deletedService->list();

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