<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\Member;
use App\Models\Coach;
use App\Services\NotificationService;
use App\Traits\ApiResponseTrait;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Enums\NotificationTypeEnum;

class NotificationController extends Controller
{
    use ApiResponseTrait;

    public function __construct(
        protected NotificationService $notificationService
    ) {}

    public function index(Request $request): JsonResponse
    {
        $user = $request->user();

        if (! ($user instanceof Member) && ! ($user instanceof Coach)) {
            return $this->errorResponse(__('Invalid member.'), 403);
        }

        $notifications = $user->notifications()
            ->orderByDesc('created_at')
            ->paginate(20);

        $data = $notifications->map(fn ($n) => [
            'id'         => $n->id,
            'type'       => NotificationTypeEnum::label($n->type),
            'booking_id' => $n->data['booking_id'] ?? null,
            'title'      => $n->data['title'] ?? __('Notification'),
            'message'    => $n->data['message'] ?? '',
            'read_at'    => $n->read_at ? $n->read_at : '-',
            'created_at' => $n->created_at,
        ]);

        return $this->ApiResponse([
            'notifications' => $data,
            'meta' => [
                'current_page' => $notifications->currentPage(),
                'last_page'    => $notifications->lastPage(),
                'per_page'     => $notifications->perPage(),
                'total'        => $notifications->total(),
            ],
        ], __('Success'), 200);
    }

    public function markAllRead(Request $request): JsonResponse
    {
        $user = $request->user();

        if (! ($user instanceof Member) && ! ($user instanceof Coach)) {
            return $this->errorResponse(__('Invalid member.'), 403);
        }

        $user->unreadNotifications->markAsRead();

        return $this->ApiResponse([], __('All notifications marked as read.'), 200);
    }

    /**
     * POST /api/v1/notifications/general
     * Send a general notification to all active members.
     */
    public function sendGeneral(Request $request): JsonResponse
    {
        $request->validate([
            'title'   => ['required', 'string', 'max:255'],
            'message' => ['required', 'string', 'max:1000'],
        ]);

        $count = $this->notificationService->sendGeneralNotification(
            $request->title,
            $request->message
        );

        return $this->ApiResponse(
            ['recipients_count' => $count],
            __('General notification sent to :count members.', ['count' => $count]),
            200
        );
    }

    /**
     * POST /api/v1/notifications/specific
     * Send a notification to a specific member.
     */
    public function sendSpecific(Request $request): JsonResponse
    {
        $request->validate([
            'member_id' => ['required', 'integer', 'exists:members,id'],
            'title'     => ['required', 'string', 'max:255'],
            'message'   => ['required', 'string', 'max:1000'],
        ]);

        $this->notificationService->sendSpecificCustomerNotification(
            $request->member_id,
            $request->title,
            $request->message
        );

        return $this->ApiResponse([], __('Notification sent successfully.'), 200);
    }

    public function sendBooking(Request $request): JsonResponse
    {
        $request->validate([
            'member_id'  => ['required', 'integer', 'exists:members,id'],
            'booking_id' => ['required', 'integer', 'exists:bookings,id'],
            'title'      => ['required', 'string', 'max:255'],
            'message'    => ['required', 'string', 'max:1000'],
            'type'       => ['nullable', 'integer', 'in:1,2,3,4,5,6'],
        ]);

        $this->notificationService->sendBookingNotification(
            $request->member_id,
            $request->title,
            $request->message,
            $request->booking_id,
            $request->input('type')
        );

        return $this->ApiResponse([], __('Booking notification sent successfully.'), 200);
    }

    public function sendBookingReminder(Request $request): JsonResponse
    {
        $request->validate([
            'member_id'  => ['required', 'integer', 'exists:members,id'],
            'booking_id' => ['required', 'integer', 'exists:bookings,id'],
            'title'      => ['required', 'string', 'max:255'],
            'message'    => ['required', 'string', 'max:1000'],
        ]);

        $this->notificationService->sendBookingReminder(
            $request->member_id,
            $request->title,
            $request->message,
            $request->booking_id
        );

        return $this->ApiResponse([], __('Booking reminder sent successfully.'), 200);
    }

    public function sendSessionReminder(Request $request): JsonResponse
    {
        $request->validate([
            'member_id'  => ['required', 'integer', 'exists:members,id'],
            'session_id' => ['required', 'integer', 'exists:coach_sessions,id'],
            'title'      => ['required', 'string', 'max:255'],
            'message'    => ['required', 'string', 'max:1000'],
        ]);

        $this->notificationService->sendSessionReminder(
            $request->member_id,
            $request->title,
            $request->message,
            $request->session_id
        );

        return $this->ApiResponse([], __('Session reminder sent successfully.'), 200);
    }

    public function sendInvitation(Request $request): JsonResponse
    {
        $request->validate([
            'member_id'  => ['required', 'integer', 'exists:members,id'],
            'title'      => ['required', 'string', 'max:255'],
            'message'    => ['required', 'string', 'max:1000'],
            'booking_id' => ['nullable', 'integer', 'exists:bookings,id'],
        ]);

        $this->notificationService->sendInvitation(
            $request->member_id,
            $request->title,
            $request->message,
            $request->input('booking_id')
        );

        return $this->ApiResponse([], __('Invitation notification sent successfully.'), 200);
    }
}
